eslint-config-setup 0.5.1 → 0.5.2

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -1 +1 @@
1
- {"version":3,"sources":["../src/configs/ai.ts","../src/configs/base.ts","../src/build/config-builder.ts","../src/configs/compat.ts","../src/configs/cspell.ts","../src/configs/de-morgan.ts","../src/configs/imports.ts","../src/configs/jsdoc.ts","../src/configs/json.ts","../src/configs/markdown.ts","../src/configs/node.ts","../src/configs/package-json.ts","../src/configs/perfectionist.ts","../src/configs/prettier.ts","../src/configs/react.ts","../src/file-patterns.ts","../src/plugins/react-compat.ts","../src/configs/react-effect.ts","../src/configs/regexp.ts","../src/configs/security.ts","../src/configs/sonarjs.ts","../src/configs/typescript.ts","../src/configs/unicorn.ts","../src/overrides/config-files.ts","../src/overrides/declarations.ts","../src/overrides/e2e.ts","../src/overrides/scripts.ts","../src/overrides/stories.ts","../src/overrides/tests.ts","../src/oxlint/integration.ts","../src/presets/standard.ts","../src/build/compose.ts"],"sourcesContent":["import type { FlatConfigArray } from \"../types\"\n\n/**\n * AI mode — cross-cutting concerns that span multiple domains.\n *\n * Domain-specific AI rules live in their respective configs (base.ts,\n * typescript.ts, react.ts, unicorn.ts, sonarjs.ts, regexp.ts, jsdoc.ts,\n * node.ts) behind an `ai` flag. This file only contains:\n *\n * 1. Test framework rules (vitest) — no dedicated domain config\n * 2. File-scoped relaxations — cross-domain, must come last to override\n *\n * @see ADR-0006: docs/adr/0006-ai-mode-as-dedicated-flag.md\n */\nconst TEST_FILES = [\"**/*.test.{ts,tsx}\", \"**/__tests__/**/*.{ts,tsx}\"]\nconst E2E_FILES = [\"**/*.spec.ts\"]\nconst CONFIG_FILES = [\n \"**/*.config.{ts,mts,cts,js,mjs,cjs}\",\n \"**/vite.config.*\",\n \"**/vitest.config.*\",\n \"**/next.config.*\",\n]\n\nconst AI_TESTS_STRICT_CONFIG: FlatConfigArray[number] = {\n name: \"eslint-config-setup/ai-tests-strict\",\n files: TEST_FILES,\n rules: {\n // Every test must be inside a describe block — organized test suites\n \"vitest/require-top-level-describe\": \"error\",\n\n // Hooks (beforeEach, afterEach) must be at the top of describe — predictable setup\n \"vitest/prefer-hooks-on-top\": \"error\",\n },\n}\n\nconst AI_TESTS_RELAXED_CONFIG: FlatConfigArray[number] = {\n name: \"eslint-config-setup/ai-tests-relaxed\",\n files: TEST_FILES,\n rules: {\n \"max-lines\": \"off\",\n \"max-lines-per-function\": \"off\",\n \"max-statements\": \"off\",\n \"max-nested-callbacks\": \"off\",\n \"@typescript-eslint/no-magic-numbers\": \"off\",\n \"sonarjs/no-duplicate-string\": \"off\",\n \"@typescript-eslint/explicit-function-return-type\": \"off\",\n \"@typescript-eslint/naming-convention\": \"off\",\n \"unicorn/prevent-abbreviations\": \"off\",\n },\n}\n\nconst AI_E2E_RELAXED_CONFIG: FlatConfigArray[number] = {\n name: \"eslint-config-setup/ai-e2e-relaxed\",\n files: E2E_FILES,\n rules: {\n \"max-lines\": \"off\",\n \"max-lines-per-function\": \"off\",\n \"max-statements\": \"off\",\n \"@typescript-eslint/no-magic-numbers\": \"off\",\n \"@typescript-eslint/explicit-function-return-type\": \"off\",\n },\n}\n\nconst AI_CONFIG_RELAXED_CONFIG: FlatConfigArray[number] = {\n name: \"eslint-config-setup/ai-config-relaxed\",\n files: CONFIG_FILES,\n rules: {\n complexity: \"off\",\n \"max-lines\": \"off\",\n \"max-lines-per-function\": \"off\",\n \"max-statements\": \"off\",\n \"@typescript-eslint/no-magic-numbers\": \"off\",\n \"@typescript-eslint/explicit-function-return-type\": \"off\",\n \"@typescript-eslint/naming-convention\": \"off\",\n },\n}\n\nconst AI_DECLARATIONS_RELAXED_CONFIG: FlatConfigArray[number] = {\n name: \"eslint-config-setup/ai-declarations-relaxed\",\n files: [\"**/*.d.ts\"],\n rules: {\n \"@typescript-eslint/explicit-function-return-type\": \"off\",\n \"@typescript-eslint/naming-convention\": \"off\",\n \"@typescript-eslint/no-explicit-any\": \"off\",\n \"@typescript-eslint/no-magic-numbers\": \"off\",\n \"unicorn/prevent-abbreviations\": \"off\",\n \"unicorn/filename-case\": \"off\",\n },\n}\n\nexport function aiConfig(): FlatConfigArray {\n return [\n AI_TESTS_STRICT_CONFIG,\n AI_TESTS_RELAXED_CONFIG,\n AI_E2E_RELAXED_CONFIG,\n AI_CONFIG_RELAXED_CONFIG,\n AI_DECLARATIONS_RELAXED_CONFIG,\n ]\n}\n","import type { Linter } from \"eslint\"\n\nimport eslint from \"@eslint/js\"\n\nimport type { FlatConfigArray } from \"../types\"\n\nimport { createConfig } from \"../build/config-builder\"\n\ntype Builder = ReturnType<typeof createConfig>\n\nconst ERROR_PREVENTION_RULES = {\n \"accessor-pairs\": [\"error\", { enforceForClassMembers: true }],\n \"array-callback-return\": [\"error\", { allowImplicit: true }],\n \"no-constructor-return\": \"error\",\n \"no-promise-executor-return\": \"error\",\n \"no-self-compare\": \"error\",\n \"no-template-curly-in-string\": \"error\",\n \"no-unreachable-loop\": \"error\",\n \"require-atomic-updates\": \"error\",\n \"no-unmodified-loop-condition\": \"error\",\n \"grouped-accessor-pairs\": [\"error\", \"getBeforeSet\"],\n \"no-useless-rename\": \"error\",\n \"no-useless-computed-key\": [\"error\", { enforceForClassMembers: true }],\n} satisfies Linter.RulesRecord\n\nconst DANGEROUS_PATTERN_RULES = {\n \"no-eval\": \"error\",\n \"no-alert\": \"error\",\n \"no-caller\": \"error\",\n \"no-extend-native\": \"error\",\n \"no-new-func\": \"error\",\n \"no-new-wrappers\": \"error\",\n \"no-object-constructor\": \"error\",\n \"no-proto\": \"error\",\n \"no-iterator\": \"error\",\n \"no-script-url\": \"error\",\n \"no-octal-escape\": \"error\",\n \"no-implicit-globals\": \"error\",\n} satisfies Linter.RulesRecord\n\nconst CODE_QUALITY_RULES = {\n eqeqeq: [\"error\", \"smart\"],\n \"guard-for-in\": \"error\",\n \"default-case-last\": \"error\",\n radix: \"error\",\n yoda: \"error\",\n \"no-sequences\": [\"error\", { allowInParentheses: false }],\n \"no-new\": \"error\",\n \"no-labels\": \"error\",\n \"no-extra-bind\": \"error\",\n \"no-lone-blocks\": \"error\",\n \"no-useless-call\": \"error\",\n \"no-useless-concat\": \"error\",\n \"no-useless-return\": \"error\",\n \"no-return-assign\": [\"error\", \"always\"],\n \"no-multi-str\": \"error\",\n \"prefer-regex-literals\": [\"error\", { disallowRedundantWrapping: true }],\n} satisfies Linter.RulesRecord\n\nconst MODERN_STYLE_RULES = {\n \"no-var\": \"error\",\n \"prefer-const\": [\"error\", { destructuring: \"all\" }],\n \"prefer-object-has-own\": \"error\",\n \"prefer-object-spread\": \"error\",\n \"prefer-rest-params\": \"error\",\n \"prefer-spread\": \"error\",\n \"symbol-description\": \"error\",\n \"prefer-numeric-literals\": \"error\",\n \"object-shorthand\": [\"error\", \"always\", { avoidExplicitReturnArrows: true, avoidQuotes: true }],\n} satisfies Linter.RulesRecord\n\nconst AI_STRUCTURAL_RULES = {\n curly: [\"error\", \"all\"],\n \"no-else-return\": [\"error\", { allowElseIf: false }],\n \"no-nested-ternary\": \"error\",\n \"no-unneeded-ternary\": \"error\",\n \"no-negated-condition\": \"error\",\n \"no-lonely-if\": \"error\",\n \"no-param-reassign\": [\"error\", { props: true }],\n \"no-multi-assign\": \"error\",\n \"one-var\": [\"error\", \"never\"],\n \"no-implicit-coercion\": \"error\",\n \"arrow-body-style\": \"error\",\n \"prefer-arrow-callback\": [\"error\", { allowNamedFunctions: true }],\n \"logical-assignment-operators\": [\"error\", \"always\", { enforceForIfStatements: true }],\n \"max-statements-per-line\": [\"error\", { max: 1 }],\n \"prefer-exponentiation-operator\": \"error\",\n \"prefer-named-capture-group\": \"error\",\n \"require-unicode-regexp\": \"error\",\n \"no-warning-comments\": \"warn\",\n \"no-await-in-loop\": \"error\",\n} satisfies Linter.RulesRecord\n\nfunction addRules(builder: Builder, rules: Linter.RulesRecord): void {\n for (const [ruleName, value] of Object.entries(rules)) {\n builder.addRule(ruleName, value)\n }\n}\n\nfunction addBaseOverrides(builder: Builder): void {\n builder.overrideRule(\"use-isnan\", [\"error\", { enforceForIndexOf: true, enforceForSwitchCase: true }])\n builder.overrideRule(\"valid-typeof\", [\"error\", { requireStringLiterals: true }])\n}\n\nfunction addComplexityRules(builder: Builder, isAi: boolean): void {\n builder.addRule(\"complexity\", [\"error\", isAi ? 10 : 20])\n builder.addRule(\"max-depth\", [\"error\", isAi ? 3 : 5])\n builder.addRule(\"max-nested-callbacks\", [\"error\", isAi ? 2 : 4])\n builder.addRule(\"max-params\", [\"error\", isAi ? 3 : 5])\n builder.addRule(\"max-statements\", [\"error\", isAi ? 15 : 25])\n builder.addRule(\"max-lines-per-function\", [\n \"error\",\n { max: isAi ? 100 : 200, skipBlankLines: true, skipComments: true },\n ])\n builder.addRule(\"max-lines\", [\n \"error\",\n { max: isAi ? 300 : 500, skipBlankLines: true, skipComments: true },\n ])\n builder.addRule(\"sonarjs/cognitive-complexity\", [\"error\", isAi ? 10 : 20])\n}\n\nfunction addModernStyleRules(builder: Builder, isAi: boolean): void {\n addRules(builder, MODERN_STYLE_RULES)\n builder.addRule(\"prefer-template\", isAi ? \"error\" : \"warn\")\n}\n\n/**\n * Base ESLint config — extends `eslint.configs.recommended` with additional\n * best-practice rules for error prevention and modern JS style.\n *\n * Rules with TypeScript equivalents (no-implied-eval, dot-notation, etc.)\n * are NOT included here — they are handled by the typescript-eslint presets.\n *\n * Preset: `@eslint/js` recommended\n * @see https://eslint.org/docs/latest/rules/\n */\nexport function baseConfig(opts?: { ai?: boolean }): FlatConfigArray {\n const isAi = opts?.ai ?? false\n\n const builder = createConfig({\n name: \"eslint-config-setup/base\",\n presets: [eslint.configs.recommended],\n })\n\n addRules(builder, ERROR_PREVENTION_RULES)\n addBaseOverrides(builder)\n addRules(builder, DANGEROUS_PATTERN_RULES)\n addRules(builder, CODE_QUALITY_RULES)\n addComplexityRules(builder, isAi)\n addModernStyleRules(builder, isAi)\n\n if (isAi) {\n addRules(builder, AI_STRUCTURAL_RULES)\n }\n\n return builder.build()\n}\n","/* eslint-disable max-lines-per-function, max-statements, max-depth, complexity, sonarjs/cognitive-complexity -- Config builder: merges presets, rules, and overrides in a single pass. Inherent complexity from ESLint's config format. */\nimport type { Linter } from \"eslint\"\n\nimport type { FlatConfig, FlatConfigArray } from \"../types\"\n\ntype RuleValue = Linter.RuleEntry\n\ntype ConfigBuilderOptions = {\n name: string\n presets?: FlatConfig[]\n passthrough?: FlatConfigArray\n plugins?: NonNullable<FlatConfig[\"plugins\"]>\n languageOptions?: NonNullable<FlatConfig[\"languageOptions\"]>\n settings?: NonNullable<FlatConfig[\"settings\"]>\n files?: NonNullable<FlatConfig[\"files\"]>\n ignores?: NonNullable<FlatConfig[\"ignores\"]>\n}\n\ntype Severity = \"error\" | \"off\" | \"warn\"\n\ntype ConfigBuilder = {\n /** Override an existing preset rule. THROWS if rule not in preset. */\n overrideRule: (name: string, value: RuleValue) => ConfigBuilder\n /** Change only the severity of an existing preset rule, keeping its options. THROWS if not in preset. */\n overrideSeverity: (name: string, severity: Severity) => ConfigBuilder\n /** Change only the options of an existing preset rule, keeping its severity. THROWS if not in preset. */\n overrideOptions: (name: string, ...options: unknown[]) => ConfigBuilder\n /** Add a new rule. THROWS if rule already exists in preset or was already added. */\n addRule: (name: string, value: RuleValue) => ConfigBuilder\n /** Disable an existing preset rule (set to \"off\"). THROWS if not found. */\n disableRule: (name: string) => ConfigBuilder\n /** Remove a rule entirely from output. THROWS if not found. */\n removeRule: (name: string) => ConfigBuilder\n /** Add an extra output block with specific files and rules (not validated against preset). */\n addFileOverride: (\n name: string,\n files: string[],\n rules: Partial<Linter.RulesRecord>,\n ) => ConfigBuilder\n /** Materialize into FlatConfigArray. */\n build: () => FlatConfigArray\n}\n\nexport function createConfig(options: ConfigBuilderOptions): ConfigBuilder {\n // Expand presets: merge all rules from preset objects into one map\n const presetRules = new Map<string, RuleValue>()\n const presetPlugins: NonNullable<FlatConfig[\"plugins\"]> = {}\n\n if (options.presets) {\n for (const preset of options.presets) {\n if (preset.plugins) {\n Object.assign(presetPlugins, preset.plugins)\n }\n if (preset.rules) {\n for (const [name, value] of Object.entries(preset.rules)) {\n if (value !== undefined) {\n presetRules.set(name, value)\n }\n }\n }\n }\n }\n\n // Mutable builder state\n const overrides = new Map<string, RuleValue>()\n const additions = new Map<string, RuleValue>()\n const disabled = new Set<string>()\n const removed = new Set<string>()\n const fileOverrides: Array<{\n name: string\n files: string[]\n rules: Partial<Linter.RulesRecord>\n }> = []\n\n const builder: ConfigBuilder = {\n overrideRule(name: string, value: RuleValue): ConfigBuilder {\n if (!presetRules.has(name)) {\n throw new Error(\n `overrideRule(\"${name}\"): rule not found in preset. ` +\n `Cannot override a rule that doesn't exist in the preset.`,\n )\n }\n overrides.set(name, value)\n return builder\n },\n\n overrideSeverity(name: string, severity: Severity): ConfigBuilder {\n if (!presetRules.has(name)) {\n throw new Error(\n `overrideSeverity(\"${name}\"): rule not found in preset. ` +\n `Cannot override severity of a rule that doesn't exist in the preset.`,\n )\n }\n const existing = presetRules.get(name)\n if (Array.isArray(existing)) {\n const [, ...restOptions] = existing\n // eslint-disable-next-line @typescript-eslint/no-unsafe-assignment -- Spreading rule options from preset\n overrides.set(name, [severity, ...restOptions])\n } else {\n overrides.set(name, severity)\n }\n return builder\n },\n\n overrideOptions(name: string, ...ruleOptions: unknown[]): ConfigBuilder {\n if (!presetRules.has(name)) {\n throw new Error(\n `overrideOptions(\"${name}\"): rule not found in preset. ` +\n `Cannot override options of a rule that doesn't exist in the preset.`,\n )\n }\n const existing = presetRules.get(name)\n const severity = Array.isArray(existing) ? existing[0] : existing\n // eslint-disable-next-line @typescript-eslint/no-unsafe-type-assertion -- Severity extracted from preset rule entry\n overrides.set(name, [severity as Severity, ...ruleOptions])\n return builder\n },\n\n addRule(name: string, value: RuleValue): ConfigBuilder {\n if (presetRules.has(name)) {\n throw new Error(\n `addRule(\"${name}\"): rule already exists in preset. ` +\n `Use overrideRule() to change its value, or removeRule() to drop it.`,\n )\n }\n if (additions.has(name)) {\n throw new Error(\n `addRule(\"${name}\"): rule was already added. ` +\n `Each rule can only be added once.`,\n )\n }\n additions.set(name, value)\n return builder\n },\n\n disableRule(name: string): ConfigBuilder {\n if (!presetRules.has(name) && !additions.has(name)) {\n throw new Error(\n `disableRule(\"${name}\"): rule not found in preset or additions. ` +\n `Cannot disable a rule that doesn't exist.`,\n )\n }\n disabled.add(name)\n return builder\n },\n\n removeRule(name: string): ConfigBuilder {\n if (!presetRules.has(name) && !additions.has(name)) {\n throw new Error(\n `removeRule(\"${name}\"): rule not found in preset or additions. ` +\n `Cannot remove a rule that doesn't exist.`,\n )\n }\n removed.add(name)\n return builder\n },\n\n addFileOverride(\n name: string,\n files: string[],\n rules: Partial<Linter.RulesRecord>,\n ): ConfigBuilder {\n fileOverrides.push({ name, files, rules })\n return builder\n },\n\n build(): FlatConfigArray {\n // Start with all preset rules\n const rules: Linter.RulesRecord = {}\n for (const [name, value] of presetRules) {\n if (!removed.has(name)) {\n rules[name] = value\n }\n }\n\n // Apply overrides\n for (const [name, value] of overrides) {\n if (!removed.has(name)) {\n rules[name] = value\n }\n }\n\n // Apply additions\n for (const [name, value] of additions) {\n if (!removed.has(name)) {\n rules[name] = value\n }\n }\n\n // Apply disabled\n for (const name of disabled) {\n if (!removed.has(name)) {\n rules[name] = \"off\"\n }\n }\n\n // Build the main config block\n const mainBlock: FlatConfig = {\n name: options.name,\n rules,\n }\n\n // Merge plugins from preset + user\n const mergedPlugins = { ...presetPlugins, ...options.plugins }\n if (Object.keys(mergedPlugins).length > 0) {\n mainBlock.plugins = mergedPlugins\n }\n\n if (options.languageOptions) {\n mainBlock.languageOptions = options.languageOptions\n }\n if (options.settings) {\n mainBlock.settings = options.settings\n }\n if (options.files) {\n mainBlock.files = options.files\n }\n if (options.ignores) {\n mainBlock.ignores = options.ignores\n }\n\n const result: FlatConfigArray = []\n\n // Passthrough blocks first\n if (options.passthrough) {\n result.push(...options.passthrough)\n }\n\n // Main validated block\n result.push(mainBlock)\n\n // File override blocks\n for (const fo of fileOverrides) {\n result.push({\n name: fo.name,\n files: fo.files,\n rules: fo.rules,\n })\n }\n\n return result\n },\n }\n\n return builder\n}\n","import compatPlugin from \"eslint-plugin-compat\"\n\nimport type { FlatConfigArray } from \"../types\"\n\n/**\n * Browser compatibility config — checks that browser APIs are available\n * in the project's browserslist targets. Uses MDN compatibility data.\n *\n * Activated automatically for non-Node projects (when `node: false`).\n * If no browserslist config exists, the default applies:\n * `> 0.5%, last 2 versions, Firefox ESR, not dead`\n *\n * @see https://github.com/amilajack/eslint-plugin-compat\n * @see https://browsersl.ist/\n */\nexport function compatConfig(): FlatConfigArray {\n return [\n {\n name: \"eslint-config-setup/compat\",\n plugins: {\n compat: compatPlugin,\n },\n rules: {\n // Warn when using browser APIs not supported in browserslist targets\n // https://github.com/amilajack/eslint-plugin-compat#usage\n \"compat/compat\": \"warn\",\n },\n },\n ]\n}\n","import cspellPlugin from \"@cspell/eslint-plugin\"\n\nimport type { FlatConfigArray } from \"../types\"\n\n/**\n * CSpell config — spell checking for identifiers and comments.\n * Catches typos in variable names, function names, and documentation.\n * Severity is \"warn\" because dictionary misses are common for domain terms.\n *\n * @see https://github.com/streetsidesoftware/cspell/tree/main/packages/cspell-eslint-plugin#readme\n */\nexport function cspellConfig(): FlatConfigArray {\n return [\n {\n name: \"eslint-config-setup/cspell\",\n plugins: {\n \"@cspell\": cspellPlugin,\n },\n rules: {\n // Check spelling in identifiers and comments — catches typos in API names\n // Strings are excluded (may contain user-facing text, URLs, etc.)\n // Auto-fix disabled — spelling corrections need human review\n // https://github.com/streetsidesoftware/cspell/tree/main/packages/cspell-eslint-plugin#rules\n \"@cspell/spellchecker\": [\n \"warn\",\n {\n checkComments: true,\n checkIdentifiers: true,\n checkStrings: false,\n autoFix: false,\n },\n ],\n },\n },\n ]\n}\n","import deMorganPlugin from \"eslint-plugin-de-morgan\"\n\nimport type { FlatConfigArray } from \"../types\"\n\n/**\n * De Morgan config — enforces De Morgan's laws on negated boolean expressions.\n * Both rules are auto-fixable: !(A && B) → !A || !B and !(A || B) → !A && !B.\n *\n * Complements sonarjs/no-inverted-boolean-check (which handles simple !(a === b) → a !== b)\n * by targeting compound expressions with && and ||.\n *\n * @see https://github.com/azat-io/eslint-plugin-de-morgan\n */\nexport function deMorganConfig(): FlatConfigArray {\n return [\n {\n name: \"eslint-config-setup/de-morgan\",\n plugins: {\n \"de-morgan\": deMorganPlugin,\n },\n rules: {\n // Transform !(A && B) → !A || !B — more readable negated conjunction\n // https://github.com/azat-io/eslint-plugin-de-morgan/blob/main/docs/no-negated-conjunction.md\n \"de-morgan/no-negated-conjunction\": \"error\",\n\n // Transform !(A || B) → !A && !B — more readable negated disjunction\n // https://github.com/azat-io/eslint-plugin-de-morgan/blob/main/docs/no-negated-disjunction.md\n \"de-morgan/no-negated-disjunction\": \"error\",\n },\n },\n ]\n}\n","import importXPlugin from \"eslint-plugin-import-x\"\nimport unusedImportsPlugin from \"eslint-plugin-unused-imports\"\n\nimport type { FlatConfigArray } from \"../types\"\n\n/**\n * Import/export config — two plugins with clear separation of concerns:\n * - `import-x` handles import **validation** (cycles, duplicates, etc.)\n * - `unused-imports` handles **removal** of unused imports (auto-fixable)\n *\n * Import/export **ordering** is handled by perfectionist (see perfectionist.ts).\n *\n * @see https://github.com/un-ts/eslint-plugin-import-x\n * @see https://github.com/sweepline/eslint-plugin-unused-imports\n */\nexport function importsConfig(): FlatConfigArray {\n return [\n {\n name: \"eslint-config-setup/imports\",\n plugins: {\n // eslint-disable-next-line @typescript-eslint/no-unsafe-type-assertion -- Plugin type is compatible\n \"import\": importXPlugin as unknown as Record<string, unknown>,\n \"unused-imports\": unusedImportsPlugin,\n },\n rules: {\n // ── Validation (import-x) ────────────────────────────────────\n\n // Merge duplicate import paths into one statement — reduces noise\n // https://github.com/un-ts/eslint-plugin-import/blob/master/docs/rules/no-duplicates.md\n \"import/no-duplicates\": \"error\",\n\n // Forbid a module from importing itself — always a bug\n // https://github.com/un-ts/eslint-plugin-import/blob/master/docs/rules/no-self-import.md\n \"import/no-self-import\": \"error\",\n\n // Detect circular dependencies — limited to depth 3 for performance\n // https://github.com/un-ts/eslint-plugin-import/blob/master/docs/rules/no-cycle.md\n \"import/no-cycle\": [\"error\", { maxDepth: 3 }],\n\n // Remove unnecessary path segments (e.g., ./foo/../foo → ./foo)\n // https://github.com/un-ts/eslint-plugin-import/blob/master/docs/rules/no-useless-path-segments.md\n \"import/no-useless-path-segments\": \"error\",\n\n // Forbid mutable export bindings — prevents shared mutable state\n // https://github.com/un-ts/eslint-plugin-import/blob/master/docs/rules/no-mutable-exports.md\n \"import/no-mutable-exports\": \"error\",\n\n // Imports must come before other statements — consistent module structure\n // https://github.com/un-ts/eslint-plugin-import/blob/master/docs/rules/first.md\n \"import/first\": \"error\",\n\n // Require blank line after import block — visual separation\n // https://github.com/un-ts/eslint-plugin-import/blob/master/docs/rules/newline-after-import.md\n \"import/newline-after-import\": \"error\",\n\n // Detect `import Foo from './Foo'` when Foo is also a named export — likely wrong\n // https://github.com/un-ts/eslint-plugin-import-x/blob/master/docs/rules/no-named-as-default.md\n \"import/no-named-as-default\": \"error\",\n\n // Detect `Foo.bar` when `bar` is a named export — use `import { bar }` instead\n // https://github.com/un-ts/eslint-plugin-import-x/blob/master/docs/rules/no-named-as-default-member.md\n \"import/no-named-as-default-member\": \"error\",\n\n // Detect empty `import {} from 'foo'` — leftover after refactoring\n // https://github.com/un-ts/eslint-plugin-import-x/blob/master/docs/rules/no-empty-named-blocks.md\n \"import/no-empty-named-blocks\": \"error\",\n\n // Forbid absolute file paths in imports — not portable across machines\n // https://github.com/un-ts/eslint-plugin-import-x/blob/master/docs/rules/no-absolute-path.md\n \"import/no-absolute-path\": \"error\",\n\n // Forbid imports of packages not listed in package.json — catches phantom deps\n // https://github.com/un-ts/eslint-plugin-import-x/blob/master/docs/rules/no-extraneous-dependencies.md\n \"import/no-extraneous-dependencies\": [\"error\", { includeTypes: true }],\n\n // Forbid side-effect-only imports — make dependencies explicit\n // https://github.com/un-ts/eslint-plugin-import-x/blob/master/docs/rules/no-unassigned-import.md\n \"import/no-unassigned-import\": [\n \"error\",\n {\n allow: [\n \"@babel/polyfill\",\n \"**/register\",\n \"**/register.*\",\n \"**/register/**\",\n \"**/register/**.*\",\n \"**/*.css\",\n \"**/*.scss\",\n \"**/*.sass\",\n \"**/*.less\",\n ],\n },\n ],\n\n // Forbid `import { default as Foo }` — use `import Foo` instead\n // https://github.com/un-ts/eslint-plugin-import-x/blob/master/docs/rules/no-named-default.md\n \"import/no-named-default\": \"error\",\n\n // ── Disabled: ordering handled by perfectionist ────────────────\n\n // https://github.com/un-ts/eslint-plugin-import/blob/master/docs/rules/order.md\n \"import/order\": \"off\",\n // https://github.com/un-ts/eslint-plugin-import/blob/master/docs/rules/sort-imports.md\n \"import/sort-imports\": \"off\",\n\n // ── Unused import removal ─────────────────────────────────────\n\n // Auto-remove unused imports — keeps imports clean (auto-fixable)\n // https://github.com/sweepline/eslint-plugin-unused-imports#usage\n \"unused-imports/no-unused-imports\": \"error\",\n },\n },\n ]\n}\n","import jsdocPlugin from \"eslint-plugin-jsdoc\"\n\nimport type { FlatConfigArray } from \"../types\"\n\nimport { createConfig } from \"../build/config-builder\"\n\n/**\n * JSDoc config — validates existing JSDoc annotations without requiring them.\n *\n * Preset: `flat/recommended-typescript-error` — all recommended JSDoc rules\n * adapted for TypeScript (types are in TS, not JSDoc).\n *\n * Overrides:\n * - `require-jsdoc` OFF — we validate existing JSDoc, we don't mandate it\n * - param/return descriptions downgraded to warn — helpful but not blocking\n * @see https://github.com/gajus/eslint-plugin-jsdoc#rules\n */\nexport function jsdocConfig(opts?: { ai?: boolean }): FlatConfigArray {\n const isAi = opts?.ai ?? false\n\n const builder = createConfig({\n name: \"eslint-config-setup/jsdoc\",\n presets: [jsdocPlugin.configs[\"flat/recommended-typescript-error\"]],\n })\n // OFF: Don't require JSDoc on everything — only validate what exists\n // https://github.com/gajus/eslint-plugin-jsdoc/blob/main/docs/rules/require-jsdoc.md\n .overrideRule(\"jsdoc/require-jsdoc\", \"off\")\n\n // OFF: Too strict for normal usage — requiring @param/@returns on every\n // documented function adds noise. Enabled in AI mode where completeness matters.\n .overrideRule(\"jsdoc/require-param\", \"off\")\n .overrideRule(\"jsdoc/require-returns\", \"off\")\n .overrideRule(\"jsdoc/require-yields\", \"off\")\n\n // Warn if @param descriptions are missing — helpful but not blocking\n // https://github.com/gajus/eslint-plugin-jsdoc/blob/main/docs/rules/require-param-description.md\n .overrideRule(\"jsdoc/require-param-description\", \"warn\")\n\n // Warn if @returns description is missing — helpful but not blocking\n // https://github.com/gajus/eslint-plugin-jsdoc/blob/main/docs/rules/require-returns-description.md\n .overrideRule(\"jsdoc/require-returns-description\", \"warn\")\n\n // Override preset's typed option — use plain error without options\n // https://github.com/gajus/eslint-plugin-jsdoc/blob/main/docs/rules/check-tag-names.md\n .overrideRule(\"jsdoc/check-tag-names\", \"error\")\n\n // Enable detection of references to undefined types in JSDoc (off in preset)\n // https://github.com/gajus/eslint-plugin-jsdoc/blob/main/docs/rules/no-undefined-types.md\n .overrideRule(\"jsdoc/no-undefined-types\", \"error\")\n\n // OFF: Allow blank lines between description and tags — keeps JSDoc readable\n // The preset enforces no blank lines before tags, but visual separation helps.\n .overrideRule(\"jsdoc/tag-lines\", \"off\")\n\n if (isAi) {\n builder.overrideRule(\"jsdoc/require-param\", \"error\")\n builder.overrideRule(\"jsdoc/require-returns\", \"error\")\n builder.overrideRule(\"jsdoc/informative-docs\", \"error\")\n }\n\n return builder.build()\n}\n","import type { ESLint } from \"eslint\"\n\nimport jsonPlugin from \"@eslint/json\"\n\nimport type { FlatConfigArray } from \"../types\"\n\n// eslint-disable-next-line @typescript-eslint/no-unsafe-type-assertion -- Typing the JSON plugin\nconst plugin = jsonPlugin as unknown as ESLint.Plugin\n\n/**\n * JSON/JSONC config — native JSON linting using the official `@eslint/json` plugin.\n * Two blocks: strict JSON for most files, JSONC (with comments) for tsconfig etc.\n *\n * @see https://github.com/eslint/json#rules\n */\nexport function jsonConfig(): FlatConfigArray {\n return [\n {\n name: \"eslint-config-setup/json\",\n files: [\"**/*.json\"],\n ignores: [\"**/package-lock.json\"],\n language: \"json/json\",\n plugins: {\n json: plugin,\n },\n rules: {\n // Detect duplicate keys in JSON — last-write-wins is confusing\n // https://github.com/eslint/json#rules\n \"json/no-duplicate-keys\": \"error\",\n\n // Detect empty string keys — likely a mistake\n // https://github.com/eslint/json#rules\n \"json/no-empty-keys\": \"error\",\n\n // Detect unsafe values (NaN, Infinity, lone surrogates) — invalid JSON\n // https://github.com/eslint/json#rules\n \"json/no-unsafe-values\": \"error\",\n\n // Detect unnormalized Unicode keys — prevents invisible key mismatches\n // https://github.com/eslint/json#rules\n \"json/no-unnormalized-keys\": \"error\",\n },\n },\n {\n name: \"eslint-config-setup/jsonc\",\n files: [\n \"**/tsconfig.json\",\n \"**/tsconfig.*.json\",\n \"**/.vscode/*.json\",\n \"**/turbo.json\",\n ],\n language: \"json/jsonc\",\n plugins: {\n json: plugin,\n },\n rules: {\n // Detect duplicate keys in JSONC — same rationale as JSON\n // https://github.com/eslint/json#rules\n \"json/no-duplicate-keys\": \"error\",\n\n // Detect empty string keys — likely a mistake\n // https://github.com/eslint/json#rules\n \"json/no-empty-keys\": \"error\",\n\n // Detect unsafe values (NaN, Infinity, lone surrogates) — invalid JSON\n // https://github.com/eslint/json#rules\n \"json/no-unsafe-values\": \"error\",\n\n // Detect unnormalized Unicode keys — prevents invisible key mismatches\n // https://github.com/eslint/json#rules\n \"json/no-unnormalized-keys\": \"error\",\n },\n },\n ]\n}\n","import * as mdxPlugin from \"eslint-plugin-mdx\"\n\nimport type { FlatConfigArray } from \"../types\"\n\n/**\n * Markdown & MDX config — lints code blocks inside Markdown and MDX files\n * using eslint-plugin-mdx. Code examples in docs get the same ESLint rules\n * as your source code. Covers both `.md` and `.mdx` files.\n *\n * Markdown structure linting (headings, links, etc.) is intentionally left\n * to dedicated tools like markdownlint.\n *\n * @see https://github.com/mdx-js/eslint-mdx\n * @see https://github.com/DavidAnson/markdownlint-cli2 (recommended for Markdown structure linting)\n */\nexport function markdownConfig(): FlatConfigArray {\n const codeBlockLanguageOptions =\n mdxPlugin.flatCodeBlocks.languageOptions ?? {}\n const codeBlockParserOptions =\n codeBlockLanguageOptions.parserOptions ?? {}\n\n return [\n // ── MDX / Markdown parsing ─────────────────────────────────────\n {\n ...mdxPlugin.flat,\n processor: mdxPlugin.createRemarkProcessor({\n lintCodeBlocks: true,\n languageMapper: {},\n }),\n },\n\n // ── Code block linting ─────────────────────────────────────────\n // Applies ESLint rules to fenced code blocks extracted from .md/.mdx.\n // Relaxes rules that don't apply to incomplete code snippets.\n {\n ...mdxPlugin.flatCodeBlocks,\n languageOptions: {\n ...codeBlockLanguageOptions,\n parserOptions: {\n ...codeBlockParserOptions,\n projectService: false,\n },\n },\n rules: {\n ...mdxPlugin.flatCodeBlocks.rules,\n // Snippets don't need trailing newlines\n \"eol-last\": \"off\",\n // Variables may be defined elsewhere\n \"no-undef\": \"off\",\n // Snippets often show standalone expressions\n \"no-unused-expressions\": \"off\",\n // Variables are often declared for demonstration\n \"no-unused-vars\": \"off\",\n // Padding is irrelevant in snippets\n \"padded-blocks\": \"off\",\n // Strict mode is irrelevant in snippets\n strict: \"off\",\n // BOM is irrelevant in snippets\n \"unicode-bom\": \"off\",\n },\n },\n ]\n}\n","import nodePlugin from \"eslint-plugin-n\"\nimport globals from \"globals\"\n\nimport type { FlatConfigArray } from \"../types\"\n\nimport { createConfig } from \"../build/config-builder\"\n\n/**\n * Node.js config — rules for server-side JavaScript/TypeScript.\n * Hand-picked subset of eslint-plugin-n. We don't use the full preset because\n * module resolution rules (`no-missing-import`, `no-unpublished-import`) are\n * handled better by TypeScript.\n *\n * @see https://github.com/eslint-community/eslint-plugin-n#-rules\n */\nexport function nodeConfig(opts?: { ai?: boolean }): FlatConfigArray {\n const isAi = opts?.ai ?? false\n\n const builder = createConfig({\n name: \"eslint-config-setup/node\",\n presets: [\n {\n rules: {\n // Detect usage of deprecated Node.js APIs (fs.exists, url.parse, etc.)\n // https://github.com/eslint-community/eslint-plugin-n/blob/master/docs/rules/no-deprecated-api.md\n \"node/no-deprecated-api\": \"error\",\n\n // Prevent `module.exports = ...` assignment in ES modules\n // https://github.com/eslint-community/eslint-plugin-n/blob/master/docs/rules/no-exports-assign.md\n \"node/no-exports-assign\": \"error\",\n\n // OFF: TypeScript resolves imports — this rule has false positives\n // https://github.com/eslint-community/eslint-plugin-n/blob/master/docs/rules/no-missing-import.md\n \"node/no-missing-import\": \"off\",\n\n // OFF: TypeScript resolves requires — this rule has false positives\n // https://github.com/eslint-community/eslint-plugin-n/blob/master/docs/rules/no-missing-require.md\n \"node/no-missing-require\": \"off\",\n\n // Warn on process.exit() — prefer throwing errors for clean shutdown\n // https://github.com/eslint-community/eslint-plugin-n/blob/master/docs/rules/no-process-exit.md\n \"node/no-process-exit\": \"warn\",\n\n // OFF: Too many false positives with monorepos and devDependencies\n // https://github.com/eslint-community/eslint-plugin-n/blob/master/docs/rules/no-unpublished-import.md\n \"node/no-unpublished-import\": \"off\",\n\n // Validate hashbang lines — correct syntax, Unix linebreaks, only in entry files\n // https://github.com/eslint-community/eslint-plugin-n/blob/master/docs/rules/hashbang.md\n \"node/hashbang\": \"error\",\n\n // Detect `__dirname + '/foo'` — use path.join() instead (breaks on Windows)\n // https://github.com/eslint-community/eslint-plugin-n/blob/master/docs/rules/no-path-concat.md\n \"node/no-path-concat\": \"error\",\n\n // Treat process.exit() as throw — prevents false positives in unreachable code analysis\n // https://github.com/eslint-community/eslint-plugin-n/blob/master/docs/rules/process-exit-as-throw.md\n \"node/process-exit-as-throw\": \"error\",\n\n // Ensure error parameters in callbacks are handled — don't silently swallow errors\n // https://github.com/eslint-community/eslint-plugin-n/blob/master/docs/rules/handle-callback-err.md\n \"node/handle-callback-err\": \"error\",\n\n // ── Prefer global builtins ────────────────────────────────────\n\n // Use global Buffer instead of require('buffer').Buffer\n // https://github.com/eslint-community/eslint-plugin-n/blob/master/docs/rules/prefer-global/buffer.md\n \"node/prefer-global/buffer\": [\"error\", \"always\"],\n\n // Use global console — always available in Node.js\n // https://github.com/eslint-community/eslint-plugin-n/blob/master/docs/rules/prefer-global/console.md\n \"node/prefer-global/console\": [\"error\", \"always\"],\n\n // Use global process — always available in Node.js\n // https://github.com/eslint-community/eslint-plugin-n/blob/master/docs/rules/prefer-global/process.md\n \"node/prefer-global/process\": [\"error\", \"always\"],\n\n // Use global URL — available since Node.js 10\n // https://github.com/eslint-community/eslint-plugin-n/blob/master/docs/rules/prefer-global/url.md\n \"node/prefer-global/url\": [\"error\", \"always\"],\n\n // Use global URLSearchParams — available since Node.js 10\n // https://github.com/eslint-community/eslint-plugin-n/blob/master/docs/rules/prefer-global/url-search-params.md\n \"node/prefer-global/url-search-params\": [\"error\", \"always\"],\n\n // ── Prefer promise-based APIs ─────────────────────────────────\n\n // Use dns.promises instead of callback-based dns — modern async\n // https://github.com/eslint-community/eslint-plugin-n/blob/master/docs/rules/prefer-promises/dns.md\n \"node/prefer-promises/dns\": \"error\",\n\n // Use fs.promises instead of callback-based fs — modern async\n // https://github.com/eslint-community/eslint-plugin-n/blob/master/docs/rules/prefer-promises/fs.md\n \"node/prefer-promises/fs\": \"error\",\n },\n },\n ],\n plugins: { node: nodePlugin },\n languageOptions: { globals: { ...globals.node } },\n })\n\n if (isAi) {\n builder.addRule(\"node/no-unsupported-features/node-builtins\", \"error\")\n }\n\n return builder.build()\n}\n","import { configs as packageJsonConfigs } from \"eslint-plugin-package-json\"\n\nimport type { FlatConfigArray } from \"../types\"\n\n/**\n * Package.json config — semantic validation of package.json files.\n *\n * Uses the recommended preset from eslint-plugin-package-json which includes:\n * - All valid-* rules (only fire on malformed existing fields, never on missing)\n * - Conservative require-* rules with ignorePrivate: true by default\n * - Quality rules (no-empty-fields, unique-dependencies, etc.)\n *\n * Sorting/ordering rules are off by default — enabled only in AI mode.\n *\n * @see https://github.com/JoshuaKGoldberg/eslint-plugin-package-json\n */\nexport function packageJsonConfig(): FlatConfigArray {\n const recommended = packageJsonConfigs.recommended\n\n return [\n {\n ...recommended,\n name: \"eslint-config-setup/package-json\",\n },\n ]\n}\n\n/**\n * Package.json AI config — enables ordering and sorting rules.\n * Only active in AI mode where deterministic structure is enforced.\n */\nexport function packageJsonAiConfig(): FlatConfigArray {\n return [\n {\n name: \"eslint-config-setup/package-json-ai\",\n files: [\"**/package.json\"],\n rules: {\n // Enforce consistent property ordering in package.json\n // https://github.com/JoshuaKGoldberg/eslint-plugin-package-json\n \"package-json/order-properties\": \"error\",\n\n // Sort dependencies, scripts, exports, etc. alphabetically\n // https://github.com/JoshuaKGoldberg/eslint-plugin-package-json\n \"package-json/sort-collections\": \"error\",\n },\n },\n ]\n}\n","import perfectionistPlugin from \"eslint-plugin-perfectionist\"\n\nimport type { FlatConfigArray } from \"../types\"\n\n/**\n * Perfectionist config — deterministic sorting of code elements.\n *\n * Sorts everything Prettier doesn't: imports, exports, union types,\n * object keys, interface members, etc. Especially valuable for\n * AI-generated code where ordering is arbitrary.\n *\n * Replaces `simple-import-sort` — perfectionist handles everything\n * simple-import-sort does, plus TypeScript path alias recognition\n * and named import sorting.\n *\n * Core philosophy: `partitionByNewLine: true` globally — semantic\n * grouping via blank lines is preserved, within groups natural sort.\n *\n * @see https://perfectionist.dev\n */\n\n/**\n * Mechanical sorting rules — always active.\n * These have no semantic dimension: the order of imports, named exports,\n * or union type members carries no meaning.\n */\nexport function perfectionistConfig(): FlatConfigArray {\n return [\n {\n name: \"eslint-config-setup/perfectionist\",\n plugins: {\n perfectionist: perfectionistPlugin,\n },\n settings: {\n perfectionist: {\n type: \"natural\",\n order: \"asc\",\n partitionByNewLine: true,\n },\n },\n rules: {\n // Auto-sort import statements — deterministic ordering regardless of input\n // Replaces simple-import-sort/imports\n // https://perfectionist.dev/rules/sort-imports\n \"perfectionist/sort-imports\": [\n \"error\",\n {\n partitionByNewLine: false,\n },\n ],\n\n // Sort specifiers inside `import { a, b, c }` — deterministic\n // https://perfectionist.dev/rules/sort-named-imports\n \"perfectionist/sort-named-imports\": \"error\",\n\n // Sort specifiers inside `export { a, b, c }` — deterministic\n // https://perfectionist.dev/rules/sort-named-exports\n \"perfectionist/sort-named-exports\": \"error\",\n\n // Auto-sort export statements — deterministic ordering\n // Replaces simple-import-sort/exports\n // https://perfectionist.dev/rules/sort-exports\n \"perfectionist/sort-exports\": \"error\",\n\n // Sort union type members — `number | string` has no semantic order\n // https://perfectionist.dev/rules/sort-union-types\n \"perfectionist/sort-union-types\": \"error\",\n\n // Sort intersection type members — `A & B` has no semantic order\n // https://perfectionist.dev/rules/sort-intersection-types\n \"perfectionist/sort-intersection-types\": \"error\",\n },\n },\n ]\n}\n\n/**\n * Structural sorting rules — AI mode only.\n * These sort code elements that *could* have semantic ordering\n * (e.g., object keys grouped by concern). Enforcing alphabetical\n * order here is a trade-off: consistency over intent. Worth it\n * for AI-generated code where \"intent\" is often random.\n */\nexport function perfectionistAiConfig(): FlatConfigArray {\n return [\n {\n name: \"eslint-config-setup/perfectionist-ai\",\n rules: {\n // Sort interface members — consistent shape definitions\n // https://perfectionist.dev/rules/sort-interfaces\n \"perfectionist/sort-interfaces\": \"error\",\n\n // Sort object type members — consistent type definitions\n // https://perfectionist.dev/rules/sort-object-types\n \"perfectionist/sort-object-types\": \"error\",\n\n // Sort enum members — consistent enum definitions\n // https://perfectionist.dev/rules/sort-enums\n \"perfectionist/sort-enums\": \"error\",\n\n // Sort JSX props — consistent component usage\n // https://perfectionist.dev/rules/sort-jsx-props\n \"perfectionist/sort-jsx-props\": \"error\",\n\n // Sort object keys — consistent object literals\n // https://perfectionist.dev/rules/sort-objects\n \"perfectionist/sort-objects\": \"error\",\n\n // Sort class members — consistent class structure\n // https://perfectionist.dev/rules/sort-classes\n \"perfectionist/sort-classes\": \"error\",\n\n // Sort switch cases — consistent case ordering\n // https://perfectionist.dev/rules/sort-switch-case\n \"perfectionist/sort-switch-case\": \"error\",\n\n // Sort Map entries — consistent Map initialization\n // https://perfectionist.dev/rules/sort-maps\n \"perfectionist/sort-maps\": \"error\",\n\n // Sort Set entries — consistent Set initialization\n // https://perfectionist.dev/rules/sort-sets\n \"perfectionist/sort-sets\": \"error\",\n\n // Sort array.includes() members — consistent membership checks\n // https://perfectionist.dev/rules/sort-array-includes\n \"perfectionist/sort-array-includes\": \"error\",\n },\n },\n ]\n}\n","import prettierConfig from \"eslint-config-prettier\"\n\nimport type { FlatConfigArray } from \"../types\"\n\nimport { createConfig } from \"../build/config-builder\"\n\n/**\n * Prettier compat config — disables all ESLint rules that conflict with Prettier.\n * Must be the last config block (before OxLint if enabled).\n *\n * Preset: eslint-config-prettier (turns off ~30 formatting rules)\n * @see https://github.com/prettier/eslint-config-prettier#readme\n */\nexport function prettierCompatConfig(): FlatConfigArray {\n return createConfig({\n name: \"eslint-config-setup/prettier\",\n presets: [prettierConfig],\n }).build()\n}\n","import type { Linter } from \"eslint\"\n\nimport eslintReactPlugin from \"@eslint-react/eslint-plugin\"\nimport stylisticPlugin from \"@stylistic/eslint-plugin\"\n// @ts-expect-error -- no type declarations available\nimport jsxA11yPlugin from \"eslint-plugin-jsx-a11y\"\nimport reactHooksPlugin from \"eslint-plugin-react-hooks\"\n// @ts-expect-error -- no type declarations available\nimport reactPerfPlugin from \"eslint-plugin-react-perf\"\nimport reactRefreshPlugin from \"eslint-plugin-react-refresh\"\nimport globals from \"globals\"\n\nimport type { FlatConfigArray } from \"../types\"\n\nimport { createConfig } from \"../build/config-builder\"\nimport {\n TYPESCRIPT_SOURCE_FILES,\n} from \"../file-patterns\"\nimport {\n reactCompatPlugin,\n translatePresetRules,\n} from \"../plugins/react-compat\"\n\ntype Builder = ReturnType<typeof createConfig>\n\n// ── Derive react/ rules from @eslint-react presets ──────────────────────────\n// strict-type-checked is translated to react/ compat names. Hook/compiler rules\n// are intentionally supplied by eslint-plugin-react-hooks under react-hooks/*.\n// eslint-disable-next-line @typescript-eslint/no-unsafe-type-assertion -- Typing the eslint-react configs shape\nconst typedConfigs = eslintReactPlugin.configs as unknown as Record<\n string,\n { rules: Linter.RulesRecord }\n>\nconst strictTypeCheckedRules = typedConfigs[\"strict-type-checked\"].rules\n\nexport const REACT_HOOKS_REPLACED_ESLINT_REACT_RULES = [\n \"error-boundaries\",\n \"exhaustive-deps\",\n \"purity\",\n \"rules-of-hooks\",\n \"set-state-in-effect\",\n \"set-state-in-render\",\n \"static-components\",\n \"unsupported-syntax\",\n \"use-memo\",\n] as const\n\nconst reactHooksReplacedRules = new Set<string>(\n REACT_HOOKS_REPLACED_ESLINT_REACT_RULES,\n)\n\nfunction filterReactHooksRules(rules: Linter.RulesRecord): Linter.RulesRecord {\n const filtered: Linter.RulesRecord = {}\n\n for (const [ruleName, value] of Object.entries(rules)) {\n const shortName = ruleName.replace(/^@eslint-react\\//, \"\")\n if (!reactHooksReplacedRules.has(shortName)) {\n filtered[ruleName] = value\n }\n }\n\n return filtered\n}\n\nconst presetRules = translatePresetRules(filterReactHooksRules(strictTypeCheckedRules))\n\nconst reactHooksRecommendedLatest = reactHooksPlugin.configs.flat[\n \"recommended-latest\"\n] as Linter.Config\n// eslint-disable-next-line @typescript-eslint/no-unsafe-type-assertion -- The plugin ships flat config metadata outside ESLint's Plugin type.\nconst reactHooksPluginForEslint = reactHooksPlugin as unknown as Record<string, unknown>\n\nconst EXTRA_REACT_RULES = {\n \"react/no-duplicate-key\": \"error\",\n \"react/no-implicit-key\": \"error\",\n \"react/no-unknown-property\": \"error\",\n \"react/style-prop-object\": \"error\",\n} satisfies Linter.RulesRecord\n\nexport const AI_ADDED_REACT_RULES = {\n \"react/no-unused-state\": \"error\",\n} satisfies Linter.RulesRecord\n\nexport const AI_REACT_PERF_RULES = {\n \"react-perf/jsx-no-jsx-as-prop\": \"error\",\n \"react-perf/jsx-no-new-array-as-prop\": \"error\",\n \"react-perf/jsx-no-new-function-as-prop\": \"error\",\n \"react-perf/jsx-no-new-object-as-prop\": \"error\",\n} satisfies Linter.RulesRecord\n\nconst JSX_A11Y_ERROR_RULES = {\n \"jsx-a11y/alt-text\": \"error\",\n \"jsx-a11y/anchor-has-content\": \"error\",\n \"jsx-a11y/anchor-is-valid\": \"error\",\n \"jsx-a11y/aria-activedescendant-has-tabindex\": \"error\",\n \"jsx-a11y/aria-props\": \"error\",\n \"jsx-a11y/aria-proptypes\": \"error\",\n \"jsx-a11y/aria-role\": \"error\",\n \"jsx-a11y/aria-unsupported-elements\": \"error\",\n \"jsx-a11y/click-events-have-key-events\": \"error\",\n \"jsx-a11y/heading-has-content\": \"error\",\n \"jsx-a11y/html-has-lang\": \"error\",\n \"jsx-a11y/img-redundant-alt\": \"error\",\n \"jsx-a11y/label-has-associated-control\": \"error\",\n \"jsx-a11y/mouse-events-have-key-events\": \"error\",\n \"jsx-a11y/no-access-key\": \"error\",\n \"jsx-a11y/no-distracting-elements\": \"error\",\n \"jsx-a11y/no-redundant-roles\": \"error\",\n \"jsx-a11y/role-has-required-aria-props\": \"error\",\n \"jsx-a11y/role-supports-aria-props\": \"error\",\n \"jsx-a11y/scope\": \"error\",\n \"jsx-a11y/tabindex-no-positive\": \"error\",\n \"jsx-a11y/lang\": \"error\",\n \"jsx-a11y/autocomplete-valid\": \"error\",\n} satisfies Linter.RulesRecord\n\nexport const AI_PROMOTED_REACT_RULES = [\n \"react/jsx-no-comment-textnodes\",\n \"react/jsx-no-useless-fragment\",\n \"react/jsx-no-constructed-context-values\",\n \"react/no-array-index-key\",\n \"react/no-object-type-as-default-prop\",\n \"react/jsx-no-target-blank\",\n \"react/button-has-type\",\n \"react/iframe-missing-sandbox\",\n \"react/forward-ref-uses-ref\",\n \"react/no-context-provider\",\n \"react/no-use-context\",\n \"react/no-leaked-event-listener\",\n \"react/no-leaked-interval\",\n \"react/no-leaked-timeout\",\n \"react/no-leaked-resize-observer\",\n] as const\n\nconst AI_A11Y_RULES = [\n \"jsx-a11y/no-static-element-interactions\",\n \"jsx-a11y/no-noninteractive-element-interactions\",\n \"jsx-a11y/interactive-supports-focus\",\n] as const\n\nfunction addRules(builder: Builder, rules: Linter.RulesRecord): void {\n for (const [ruleName, value] of Object.entries(rules)) {\n builder.addRule(ruleName, value)\n }\n}\n\nfunction addExtraReactRules(builder: Builder): void {\n addRules(builder, EXTRA_REACT_RULES)\n}\n\nfunction addStylisticReactRules(builder: Builder): void {\n builder.addRule(\"@stylistic/jsx-self-closing-comp\", \"error\")\n builder.addRule(\"@stylistic/jsx-curly-brace-presence\", [\n \"error\",\n { props: \"never\", children: \"never\" },\n ])\n}\n\nfunction addReactRefreshRules(builder: Builder): void {\n builder.addRule(\"react-refresh/only-export-components\", [\n \"warn\",\n { allowConstantExport: true },\n ])\n}\n\nfunction addAccessibilityRules(builder: Builder): void {\n addRules(builder, JSX_A11Y_ERROR_RULES)\n builder.addRule(\"jsx-a11y/no-autofocus\", [\"error\", { ignoreNonDOM: true }])\n}\n\nfunction applyAiReactRules(builder: Builder): void {\n for (const ruleName of AI_PROMOTED_REACT_RULES) {\n builder.overrideSeverity(ruleName, \"error\")\n }\n\n addRules(builder, AI_ADDED_REACT_RULES)\n addRules(builder, AI_REACT_PERF_RULES)\n\n for (const ruleName of AI_A11Y_RULES) {\n builder.addRule(ruleName, \"error\")\n }\n}\n\nfunction addReactFileOverrides(builder: Builder): void {\n builder.addFileOverride(\n \"eslint-config-setup/react-typescript\",\n [...TYPESCRIPT_SOURCE_FILES],\n {\n // Allow async event handlers — onClick={async () => {...}} is idiomatic React\n \"@typescript-eslint/no-misused-promises\": [\n \"error\",\n { checksVoidReturn: false },\n ],\n },\n )\n}\n\n/**\n * React config — React 19+, Hooks, JSX accessibility, and Web API leak detection.\n *\n * Uses `@eslint-react` (eslint-plugin-react-x) for React, DOM, Web API,\n * naming-convention, and RSC rules under the `react/` compat namespace.\n * Rules of Hooks and React Compiler linting come from Meta's\n * eslint-plugin-react-hooks under the native `react-hooks/` namespace.\n *\n * Base React severities come from the `@eslint-react` `strict-type-checked` preset.\n * When `ai: true`, preset \"warn\" rules that AI should always get right are\n * promoted to \"error\", and React performance rules are enabled as errors.\n *\n * @see https://eslint-react.xyz/docs/rules/overview\n * @see https://www.npmjs.com/package/eslint-plugin-react-hooks\n * @see https://github.com/cvazac/eslint-plugin-react-perf\n * @see https://github.com/ArnaudBarre/eslint-plugin-react-refresh\n * @see https://github.com/jsx-eslint/eslint-plugin-jsx-a11y#supported-rules\n */\nexport function reactConfig(opts?: { ai?: boolean }): FlatConfigArray {\n const isAi = opts?.ai ?? false\n\n const builder = createConfig({\n name: \"eslint-config-setup/react\",\n presets: [{ rules: presetRules }, reactHooksRecommendedLatest],\n plugins: {\n react: reactCompatPlugin,\n \"@stylistic\": stylisticPlugin,\n \"react-hooks\": reactHooksPluginForEslint,\n // eslint-disable-next-line @typescript-eslint/no-unsafe-type-assertion -- Plugin from untyped module\n \"react-perf\": reactPerfPlugin as Record<string, unknown>,\n \"react-refresh\": reactRefreshPlugin,\n // eslint-disable-next-line @typescript-eslint/no-unsafe-type-assertion -- Plugin from untyped module\n \"jsx-a11y\": jsxA11yPlugin as Record<string, unknown>,\n },\n languageOptions: {\n globals: {\n ...globals.browser,\n },\n parserOptions: {\n ecmaFeatures: {\n jsx: true,\n },\n },\n },\n })\n\n addExtraReactRules(builder)\n addStylisticReactRules(builder)\n addReactRefreshRules(builder)\n addAccessibilityRules(builder)\n\n // ── AI mode: promote preset \"warn\" rules to \"error\" ───────────────\n // These rules catch real bugs or patterns AI should always avoid.\n // overrideSeverity validates that the rule exists in the preset —\n // if a future @eslint-react version removes one, we get a build error.\n if (isAi) {\n applyAiReactRules(builder)\n }\n\n addReactFileOverrides(builder)\n\n return builder.build()\n}\n","export const TYPESCRIPT_SOURCE_FILES = [\n \"**/*.ts\",\n \"**/*.tsx\",\n \"**/*.mts\",\n \"**/*.cts\",\n] as const\n\nexport const MARKDOWN_DOCUMENT_FILES = [\"**/*.{md,mdx}\"] as const\nexport const MARKDOWN_CODE_BLOCK_FILES = [\"**/*.{md,mdx}/**\"] as const\n","import type { ESLint, Linter, Rule } from \"eslint\"\n\n/**\n * React Compat Plugin — merges all `@eslint-react` sub-plugins into a single\n * `react` namespace and re-exports rules under legacy `eslint-plugin-react`\n * names where a 1:1 equivalent exists.\n *\n * **Why?** OxLint implements many React rules under the classic `react/` prefix\n * with legacy names (e.g. `react/jsx-key`, `react/no-danger`). By registering\n * the modern `@eslint-react` rule implementations under those legacy names, we\n * get automatic OxLint coverage — OxLint runs the fast Rust check and ESLint\n * skips the JS version via `eslint-plugin-oxlint`'s `flat/react` config.\n *\n * Rules without a legacy equivalent keep their `@eslint-react` short name\n * (e.g. `react/no-context-provider`, `react/no-leaked-event-listener`).\n * As OxLint expands React support, more rules will automatically be covered.\n *\n * @see https://eslint-react.xyz/docs/rules/overview - `@eslint-react` rules overview\n * @see https://oxc.rs/docs/guide/usage/linter/rules.html - OxLint rules\n */\nimport eslintReactPlugin from \"@eslint-react/eslint-plugin\"\n\ntype PluginRules = Record<string, Rule.RuleModule>\n\n// eslint-disable-next-line @typescript-eslint/no-unsafe-type-assertion -- Typing the rules export\nconst coreRules = eslintReactPlugin.rules as PluginRules\n\nfunction selectPrefixedRules(prefix: string): PluginRules {\n const result: PluginRules = {}\n\n for (const [name, rule] of Object.entries(coreRules)) {\n if (name.startsWith(prefix)) {\n result[name.slice(prefix.length)] = rule\n }\n }\n\n return result\n}\n\nconst domRules = selectPrefixedRules(\"dom-\")\nconst jsxRules = selectPrefixedRules(\"jsx-\")\nconst namingRules = selectPrefixedRules(\"naming-convention-\")\nconst rscRules = selectPrefixedRules(\"rsc-\")\nconst webApiRules = selectPrefixedRules(\"web-api-\")\n\n// ── Legacy name mapping ─────────────────────────────────────────────────────\n// Maps legacy eslint-plugin-react name → { source rules object, original name }\n// Based on @eslint-react's `disable-conflict-eslint-plugin-react` config.\n// Only 1:1 mappings are included — 1:many (e.g. `no-unsafe` → 3 rules) are skipped.\n\nexport const REACT_COMPAT_LEGACY_ALIAS_NAMES = [\n \"button-has-type\",\n \"display-name\",\n \"forward-ref-uses-ref\",\n \"hook-use-state\",\n \"iframe-missing-sandbox\",\n \"jsx-key\",\n \"jsx-key-before-spread\",\n \"jsx-no-comment-textnodes\",\n \"jsx-no-constructed-context-values\",\n \"jsx-no-leaked-render\",\n \"jsx-no-script-url\",\n \"jsx-no-target-blank\",\n \"jsx-no-useless-fragment\",\n \"no-access-state-in-setstate\",\n \"no-array-index-key\",\n \"no-children-prop\",\n \"no-danger\",\n \"no-danger-with-children\",\n \"no-did-mount-set-state\",\n \"no-did-update-set-state\",\n \"no-direct-mutation-state\",\n \"no-find-dom-node\",\n \"no-namespace\",\n \"no-object-type-as-default-prop\",\n \"no-render-return-value\",\n \"no-unknown-property\",\n \"no-unstable-nested-components\",\n \"no-unused-class-component-members\",\n \"no-unused-state\",\n \"no-will-update-set-state\",\n \"style-prop-object\",\n \"void-dom-elements-no-children\",\n] as const\n\nconst LEGACY_ALIASES =\n {\n // ── Core: identical names ──────────────────────────────────────────\n \"no-access-state-in-setstate\": [coreRules, \"no-access-state-in-setstate\"],\n \"no-array-index-key\": [coreRules, \"no-array-index-key\"],\n \"no-children-prop\": [jsxRules, \"no-children-prop\"],\n \"no-direct-mutation-state\": [coreRules, \"no-direct-mutation-state\"],\n \"no-unused-class-component-members\": [\n coreRules,\n \"no-unused-class-component-members\",\n ],\n \"no-unused-state\": [coreRules, \"no-unused-state\"],\n \"jsx-no-comment-textnodes\": [jsxRules, \"no-comment-textnodes\"],\n\n // ── Core: renamed 1:1 ──────────────────────────────────────────────\n \"jsx-key\": [coreRules, \"no-missing-key\"],\n \"jsx-key-before-spread\": [jsxRules, \"no-key-after-spread\"],\n \"jsx-no-constructed-context-values\": [\n coreRules,\n \"no-unstable-context-value\",\n ],\n \"jsx-no-leaked-render\": [coreRules, \"no-leaked-conditional-rendering\"],\n \"jsx-no-useless-fragment\": [jsxRules, \"no-useless-fragment\"],\n \"no-object-type-as-default-prop\": [coreRules, \"no-unstable-default-props\"],\n \"no-unstable-nested-components\": [\n coreRules,\n \"no-nested-component-definitions\",\n ],\n \"display-name\": [coreRules, \"no-missing-component-display-name\"],\n \"forward-ref-uses-ref\": [coreRules, \"no-forward-ref\"],\n \"no-did-mount-set-state\": [\n coreRules,\n \"no-set-state-in-component-did-mount\",\n ],\n \"no-did-update-set-state\": [\n coreRules,\n \"no-set-state-in-component-did-update\",\n ],\n \"no-will-update-set-state\": [\n coreRules,\n \"no-set-state-in-component-will-update\",\n ],\n\n // ── Naming convention → legacy names ───────────────────────────────\n \"hook-use-state\": [coreRules, \"use-state\"],\n\n // ── DOM → legacy react/ names (not react-dom/) ─────────────────────\n \"no-danger\": [domRules, \"no-dangerously-set-innerhtml\"],\n \"no-danger-with-children\": [\n domRules,\n \"no-dangerously-set-innerhtml-with-children\",\n ],\n \"no-find-dom-node\": [domRules, \"no-find-dom-node\"],\n \"no-namespace\": [jsxRules, \"no-namespace\"],\n \"no-render-return-value\": [domRules, \"no-render-return-value\"],\n \"jsx-no-script-url\": [domRules, \"no-script-url\"],\n \"jsx-no-target-blank\": [domRules, \"no-unsafe-target-blank\"],\n \"no-unknown-property\": [domRules, \"no-unknown-property\"],\n \"void-dom-elements-no-children\": [\n domRules,\n \"no-void-elements-with-children\",\n ],\n \"button-has-type\": [domRules, \"no-missing-button-type\"],\n \"iframe-missing-sandbox\": [domRules, \"no-missing-iframe-sandbox\"],\n \"style-prop-object\": [domRules, \"no-string-style-prop\"],\n } satisfies Record<\n (typeof REACT_COMPAT_LEGACY_ALIAS_NAMES)[number],\n [source: PluginRules, originalName: string]\n >\n\n// Build the set of original rule names that are aliased to a legacy name.\n// These will NOT be included under their original name to avoid duplicates.\nconst aliasedOriginals = new Set<string>()\nfor (const [source, originalName] of Object.values(LEGACY_ALIASES)) {\n if (source === coreRules) {\n aliasedOriginals.add(originalName)\n } else if (source === domRules) {\n aliasedOriginals.add(`dom-${originalName}`)\n } else if (source === jsxRules) {\n aliasedOriginals.add(`jsx-${originalName}`)\n } else if (source === namingRules) {\n aliasedOriginals.add(`naming-convention-${originalName}`)\n } else if (source === rscRules) {\n aliasedOriginals.add(`rsc-${originalName}`)\n } else if (source === webApiRules) {\n aliasedOriginals.add(`web-api-${originalName}`)\n }\n}\n\n// ── Merge all rules ─────────────────────────────────────────────────────────\nconst mergedRules: PluginRules = {}\n\n// 1. Core rules — skip those that have a legacy alias\nfor (const [name, rule] of Object.entries(coreRules)) {\n if (!aliasedOriginals.has(name)) {\n mergedRules[name] = rule\n }\n}\n\n// 2. Sub-plugin rules — use short name (strip sub-plugin prefix).\n// Skip `prefer-namespace-import` from dom (collides with core).\nconst subPlugins: Array<[PluginRules, Set<string>]> = [\n [domRules, new Set([\"prefer-namespace-import\"])],\n [jsxRules, new Set()],\n [webApiRules, new Set()],\n [namingRules, new Set()],\n [rscRules, new Set()],\n]\n\nfor (const [rules, skip] of subPlugins) {\n for (const [name, rule] of Object.entries(rules)) {\n if (skip.has(name)) continue\n // Skip sub-plugin rules that are aliased to a legacy name\n const isAliased = Object.values(LEGACY_ALIASES).some(\n ([source, originalName]) => source === rules && originalName === name,\n )\n if (!isAliased) {\n mergedRules[name] = rule\n }\n }\n}\n\n// 3. Legacy aliases — register under legacy name pointing to the implementation\nfor (const [legacyName, [source, originalName]] of Object.entries(\n LEGACY_ALIASES,\n)) {\n mergedRules[legacyName] = source[originalName]\n}\n\n// ── Reverse map: original name → compat name ────────────────────────────────\n// Used by translatePresetRules to convert @eslint-react preset keys to react/ keys.\nconst originalToCompat = new Map<string, string>()\nfor (const [legacyName, [source, originalName]] of Object.entries(LEGACY_ALIASES)) {\n originalToCompat.set(originalName, legacyName)\n if (source === domRules) {\n originalToCompat.set(`dom-${originalName}`, legacyName)\n } else if (source === jsxRules) {\n originalToCompat.set(`jsx-${originalName}`, legacyName)\n } else if (source === namingRules) {\n originalToCompat.set(`naming-convention-${originalName}`, legacyName)\n } else if (source === rscRules) {\n originalToCompat.set(`rsc-${originalName}`, legacyName)\n } else if (source === webApiRules) {\n originalToCompat.set(`web-api-${originalName}`, legacyName)\n }\n}\n\n/**\n * Translates rules from an `@eslint-react` preset (e.g. `recommended`, `strict`)\n * into `react/` compat names that match our unified plugin namespace.\n *\n * Example: `\"@eslint-react/no-missing-key\": \"error\"` → `\"react/jsx-key\": \"error\"`\n */\nexport function translatePresetRules(\n presetRules: Linter.RulesRecord,\n): Linter.RulesRecord {\n const result: Linter.RulesRecord = {}\n\n for (const [key, value] of Object.entries(presetRules)) {\n // Strip plugin prefix: @eslint-react/dom/X → X, @eslint-react/X → X\n const shortName = key\n .replace(\n /^@eslint-react\\/(?:dom|web-api|naming-convention|rsc)\\//,\n \"\",\n )\n .replace(/^@eslint-react\\//, \"\")\n .replace(/^(?:dom|web-api|naming-convention|rsc)-/, \"\")\n\n const compatName = originalToCompat.get(shortName) ?? shortName\n if (compatName in mergedRules) {\n result[`react/${compatName}`] = value\n }\n }\n\n return result\n}\n\n/**\n * Unified React plugin registered as `react` in ESLint flat config.\n * Contains all `@eslint-react` rule implementations under OxLint-compatible names.\n */\nexport const reactCompatPlugin: ESLint.Plugin = {\n meta: {\n name: \"react-compat\",\n version: \"1.0.0\",\n },\n rules: mergedRules,\n}\n","import reactEffectPlugin from \"eslint-plugin-react-you-might-not-need-an-effect\"\n\nimport type { FlatConfigArray } from \"../types\"\n\n/**\n * React effect config — catches unnecessary useEffect anti-patterns.\n * Codifies the patterns from the React docs article \"You Might Not Need an Effect\".\n *\n * Complements react-hooks (which checks dependency arrays are correct) by\n * detecting when the entire effect is unnecessary — derived state, chained\n * state updates, prop-triggered resets, and more.\n *\n * @see https://react.dev/learn/you-might-not-need-an-effect\n * @see https://github.com/nickjvandyke/eslint-plugin-react-you-might-not-need-an-effect\n */\nexport function reactEffectConfig(): FlatConfigArray {\n return [\n {\n name: \"eslint-config-setup/react-effect\",\n plugins: {\n \"react-you-might-not-need-an-effect\": reactEffectPlugin,\n },\n rules: {\n // Disallow storing derived state in an effect — compute at render time or useMemo\n // https://github.com/nickjvandyke/eslint-plugin-react-you-might-not-need-an-effect\n \"react-you-might-not-need-an-effect/no-derived-state\": \"error\",\n\n // Disallow chaining state updates in an effect — update together instead\n // https://github.com/nickjvandyke/eslint-plugin-react-you-might-not-need-an-effect\n \"react-you-might-not-need-an-effect/no-chain-state-updates\": \"error\",\n\n // Disallow using state + effect as an event handler — call logic directly\n // https://github.com/nickjvandyke/eslint-plugin-react-you-might-not-need-an-effect\n \"react-you-might-not-need-an-effect/no-event-handler\": \"error\",\n\n // Disallow adjusting state when a prop changes — compute inline during render\n // https://github.com/nickjvandyke/eslint-plugin-react-you-might-not-need-an-effect\n \"react-you-might-not-need-an-effect/no-adjust-state-on-prop-change\": \"warn\",\n\n // Disallow resetting all state when a prop changes — use the key prop instead\n // https://github.com/nickjvandyke/eslint-plugin-react-you-might-not-need-an-effect\n \"react-you-might-not-need-an-effect/no-reset-all-state-on-prop-change\": \"error\",\n\n // Disallow passing live state to parent via effect — lift state up instead\n // https://github.com/nickjvandyke/eslint-plugin-react-you-might-not-need-an-effect\n \"react-you-might-not-need-an-effect/no-pass-live-state-to-parent\": \"error\",\n\n // Disallow passing fetched data to parent via effect — fetch in parent instead\n // https://github.com/nickjvandyke/eslint-plugin-react-you-might-not-need-an-effect\n \"react-you-might-not-need-an-effect/no-pass-data-to-parent\": \"error\",\n\n // Disallow external-store subscriptions in an effect — use useSyncExternalStore\n // https://github.com/nickjvandyke/eslint-plugin-react-you-might-not-need-an-effect\n \"react-you-might-not-need-an-effect/no-external-store-subscription\": \"error\",\n\n // Disallow initializing state in an effect — pass initial value to useState\n // https://github.com/nickjvandyke/eslint-plugin-react-you-might-not-need-an-effect\n \"react-you-might-not-need-an-effect/no-initialize-state\": \"error\",\n },\n },\n ]\n}\n","import { configs as regexpConfigs } from \"eslint-plugin-regexp\"\n\nimport type { FlatConfigArray } from \"../types\"\n\nimport { createConfig } from \"../build/config-builder\"\n\n/**\n * RegExp config — uses the full `flat/recommended` preset from eslint-plugin-regexp.\n * Validates regular expression syntax, detects common mistakes, and suggests\n * simpler patterns.\n *\n * Preset: eslint-plugin-regexp flat/recommended (all rules at their default severity)\n * @see https://ota-meshi.github.io/eslint-plugin-regexp/\n * @see https://ota-meshi.github.io/eslint-plugin-regexp/rules/\n */\nexport function regexpConfig(opts?: { ai?: boolean }): FlatConfigArray {\n const isAi = opts?.ai ?? false\n\n const builder = createConfig({\n name: \"eslint-config-setup/regexp\",\n presets: [regexpConfigs[\"flat/recommended\"]],\n })\n\n // ── Beyond recommended ──────────────────────────────────────────\n\n // Disallow invisible control characters in regex — almost always a paste artifact\n // https://ota-meshi.github.io/eslint-plugin-regexp/rules/no-control-character.html\n .addRule(\"regexp/no-control-character\", \"error\")\n\n // Disallow ambiguous octal escapes — use \\x01 or named backreference instead\n // https://ota-meshi.github.io/eslint-plugin-regexp/rules/no-octal.html\n .addRule(\"regexp/no-octal\", \"error\")\n\n // Disallow standalone backslashes — /\\a/ silently ignores the backslash\n // https://ota-meshi.github.io/eslint-plugin-regexp/rules/no-standalone-backslash.html\n .addRule(\"regexp/no-standalone-backslash\", \"error\")\n\n // Detect patterns with quadratic move behavior — subtle ReDoS variant\n // https://ota-meshi.github.io/eslint-plugin-regexp/rules/no-super-linear-move.html\n .addRule(\"regexp/no-super-linear-move\", \"error\")\n\n // Require $$ for literal dollar signs in replacement strings — prevents bugs\n // https://ota-meshi.github.io/eslint-plugin-regexp/rules/prefer-escape-replacement-dollar-char.html\n .addRule(\"regexp/prefer-escape-replacement-dollar-char\", \"error\")\n\n if (isAi) {\n builder.addRule(\"regexp/prefer-lookaround\", \"error\")\n builder.addRule(\"regexp/prefer-named-backreference\", \"error\")\n builder.addRule(\"regexp/prefer-named-replacement\", \"error\")\n builder.addRule(\"regexp/prefer-quantifier\", \"error\")\n builder.addRule(\"regexp/prefer-result-array-groups\", \"error\")\n builder.addRule(\"regexp/require-unicode-sets-regexp\", \"error\")\n }\n\n return builder.build()\n}\n","import type { ESLint } from \"eslint\"\n\n// @ts-expect-error -- no type declarations available\nimport securityPlugin from \"eslint-plugin-security\"\n\nimport type { FlatConfigArray } from \"../types\"\n\n// eslint-disable-next-line @typescript-eslint/no-unsafe-type-assertion -- Typing the security plugin\nconst plugin = securityPlugin as unknown as ESLint.Plugin\n\n/**\n * Security config — Node.js security patterns from eslint-plugin-security.\n * We manually select rules instead of using the preset because the preset\n * enables `detect-object-injection` which produces too many false positives.\n *\n * @see https://github.com/eslint-community/eslint-plugin-security#rules\n */\nexport function securityConfig(): FlatConfigArray {\n return [\n {\n name: \"eslint-config-setup/security\",\n plugins: {\n security: plugin,\n },\n rules: {\n // ── Errors: dangerous patterns that should never appear ────────\n\n // Detect Buffer read/write without noAssert — can read out of bounds\n // https://github.com/eslint-community/eslint-plugin-security/blob/main/docs/rules/detect-buffer-noassert.md\n \"security/detect-buffer-noassert\": \"error\",\n\n // Detect child_process usage — potential command injection vector\n // https://github.com/eslint-community/eslint-plugin-security/blob/main/docs/rules/detect-child-process.md\n \"security/detect-child-process\": \"error\",\n\n // Detect disabled mustache escaping — XSS risk in templates\n // https://github.com/eslint-community/eslint-plugin-security/blob/main/docs/rules/detect-disable-mustache-escape.md\n \"security/detect-disable-mustache-escape\": \"error\",\n\n // Detect eval() with variable arguments — code injection risk\n // https://github.com/eslint-community/eslint-plugin-security/blob/main/docs/rules/detect-eval-with-expression.md\n \"security/detect-eval-with-expression\": \"error\",\n\n // Detect new Buffer(n) — deprecated, use Buffer.alloc() instead\n // https://github.com/eslint-community/eslint-plugin-security/blob/main/docs/rules/detect-new-buffer.md\n \"security/detect-new-buffer\": \"error\",\n\n // Detect CSRF middleware placed after method-override — CSRF bypass\n // https://github.com/eslint-community/eslint-plugin-security/blob/main/docs/rules/detect-no-csrf-before-method-override.md\n \"security/detect-no-csrf-before-method-override\": \"error\",\n\n // Detect Math.random() / pseudoRandomBytes — not cryptographically secure\n // https://github.com/eslint-community/eslint-plugin-security/blob/main/docs/rules/detect-pseudoRandomBytes.md\n \"security/detect-pseudoRandomBytes\": \"error\",\n\n // Detect regexes vulnerable to ReDoS (catastrophic backtracking)\n // https://github.com/eslint-community/eslint-plugin-security/blob/main/docs/rules/detect-unsafe-regex.md\n \"security/detect-unsafe-regex\": \"error\",\n\n // ── Warnings: worth reviewing but may have legitimate uses ─────\n\n // Detect dynamic fs paths — potential path traversal (many false positives)\n // https://github.com/eslint-community/eslint-plugin-security/blob/main/docs/rules/detect-non-literal-fs-filename.md\n \"security/detect-non-literal-fs-filename\": \"warn\",\n\n // Detect dynamic regex construction — potential ReDoS\n // https://github.com/eslint-community/eslint-plugin-security/blob/main/docs/rules/detect-non-literal-regexp.md\n \"security/detect-non-literal-regexp\": \"warn\",\n\n // Detect dynamic require() — potential code injection\n // https://github.com/eslint-community/eslint-plugin-security/blob/main/docs/rules/detect-non-literal-require.md\n \"security/detect-non-literal-require\": \"warn\",\n\n // Detect string comparisons that may leak timing info — side-channel risk\n // https://github.com/eslint-community/eslint-plugin-security/blob/main/docs/rules/detect-possible-timing-attacks.md\n \"security/detect-possible-timing-attacks\": \"warn\",\n\n // Detect Unicode bidirectional control characters — source code trojan attack\n // https://github.com/eslint-community/eslint-plugin-security/blob/main/docs/rules/detect-bidi-characters.md\n \"security/detect-bidi-characters\": \"error\",\n\n // ── Disabled: too many false positives ────────────────────────\n\n // Flags all bracket notation (obj[key]) — nearly every codebase triggers this\n // https://github.com/eslint-community/eslint-plugin-security/blob/main/docs/rules/detect-object-injection.md\n \"security/detect-object-injection\": \"off\",\n },\n },\n ]\n}\n","import sonarjsPlugin from \"eslint-plugin-sonarjs\"\n\nimport type { FlatConfigArray } from \"../types\"\n\nimport { createConfig } from \"../build/config-builder\"\n\n/**\n * SonarJS config — code-quality rules from SonarSource.\n * Hand-picked subset focused on bug detection and code smells.\n * We don't use the full preset because many SonarJS rules overlap with\n * typescript-eslint and unicorn.\n *\n * @see https://github.com/SonarSource/SonarJS/tree/master/packages/jsts/src/rules#readme\n */\nexport function sonarjsConfig(opts?: { ai?: boolean }): FlatConfigArray {\n const isAi = opts?.ai === true\n\n const builder = createConfig({\n name: \"eslint-config-setup/sonarjs\",\n presets: [{\n plugins: { sonarjs: sonarjsPlugin },\n rules: {\n // Detect copy-pasted functions — extract to shared helper instead\n // https://sonarsource.github.io/rspec/#/rspec/S4144/javascript\n \"sonarjs/no-identical-functions\": \"error\",\n\n // Merge nested if-statements that can be combined — reduces nesting\n // https://sonarsource.github.io/rspec/#/rspec/S1066/javascript\n \"sonarjs/no-collapsible-if\": \"error\",\n\n // Simplify `if (x) return true; else return false;` → `return x`\n // https://sonarsource.github.io/rspec/#/rspec/S1125/javascript\n \"sonarjs/no-redundant-boolean\": \"error\",\n\n // Detect collections that are populated but never read — dead code\n // https://sonarsource.github.io/rspec/#/rspec/S4030/javascript\n \"sonarjs/no-unused-collection\": \"error\",\n\n // Return value directly instead of storing in temp variable first\n // https://sonarsource.github.io/rspec/#/rspec/S1488/javascript\n \"sonarjs/prefer-immediate-return\": \"error\",\n\n // Simplify boolean return patterns — `return cond` instead of `if/else`\n // https://sonarsource.github.io/rspec/#/rspec/S1126/javascript\n \"sonarjs/prefer-single-boolean-return\": \"error\",\n\n // Detect identical sub-expressions on both sides of operator (x && x)\n // https://sonarsource.github.io/rspec/#/rspec/S1764/javascript\n \"sonarjs/no-identical-expressions\": \"error\",\n\n // Simplify `!(a === b)` → `a !== b` — more readable\n // https://sonarsource.github.io/rspec/#/rspec/S1940/javascript\n \"sonarjs/no-inverted-boolean-check\": \"error\",\n\n // Detect size/length comparisons that are always true/false\n // https://sonarsource.github.io/rspec/#/rspec/S3981/javascript\n \"sonarjs/no-collection-size-mischeck\": \"error\",\n\n // Detect duplicate conditions in if/else-if chains — copy-paste bug\n // https://sonarsource.github.io/rspec/#/rspec/S1862/javascript\n \"sonarjs/no-identical-conditions\": \"error\",\n\n // Detect identical code in if and else branches — refactoring leftover\n // https://sonarsource.github.io/rspec/#/rspec/S1871/javascript\n \"sonarjs/no-duplicated-branches\": \"error\",\n\n // Detect .filter()/.map()/.slice() called without using the result\n // https://sonarsource.github.io/rspec/#/rspec/S2201/javascript\n \"sonarjs/no-ignored-return\": \"error\",\n\n // Detect redundant return/break/continue at end of block\n // https://sonarsource.github.io/rspec/#/rspec/S3626/javascript\n \"sonarjs/no-redundant-jump\": \"error\",\n\n // Prevent .only() from being committed — blocks CI for others\n // https://sonarsource.github.io/rspec/#/rspec/S6426/javascript\n \"sonarjs/no-exclusive-tests\": \"error\",\n\n // Detect `const sorted = arr.sort()` — .sort() mutates the original\n // https://sonarsource.github.io/rspec/#/rspec/S4043/javascript\n \"sonarjs/no-misleading-array-reverse\": \"error\",\n\n // Require initial value for .reduce() — crashes on empty arrays without it\n // https://sonarsource.github.io/rspec/#/rspec/S6959/javascript\n \"sonarjs/reduce-initial-value\": \"error\",\n\n // Disallow async operations in constructors — use factory methods\n // https://sonarsource.github.io/rspec/#/rspec/S7059/javascript\n \"sonarjs/no-async-constructor\": \"error\",\n\n // Detect `field?: string | undefined` — the `?` already implies undefined\n // https://sonarsource.github.io/rspec/#/rspec/S4782/javascript\n \"sonarjs/no-redundant-optional\": \"error\",\n\n // Detect `string | number | string` — duplicate constituents in unions\n // https://sonarsource.github.io/rspec/#/rspec/S4621/javascript\n \"sonarjs/no-duplicate-in-composite\": \"error\",\n\n // Detect hardcoded secrets (API keys, passwords, tokens) in source code\n // https://sonarsource.github.io/rspec/#/rspec/S6418/javascript\n \"sonarjs/no-hardcoded-secrets\": \"warn\",\n },\n }],\n })\n\n if (isAi) {\n // New AI-only rules (not already in base config)\n builder.addRule(\"sonarjs/no-nested-switch\", \"error\")\n builder.addRule(\"sonarjs/no-nested-template-literals\", \"error\")\n builder.addRule(\"sonarjs/max-union-size\", [\"error\", { threshold: 5 }])\n builder.addRule(\"sonarjs/prefer-type-guard\", \"error\")\n builder.addRule(\"sonarjs/public-static-readonly\", \"error\")\n builder.addRule(\"sonarjs/no-duplicate-string\", [\"error\", { threshold: 3 }])\n }\n\n return builder.build()\n}\n","/* eslint-disable max-lines-per-function, max-statements, complexity -- Rule definition file: sequential builder calls that configure the TypeScript preset. */\nimport tseslint from \"typescript-eslint\"\n\nimport type { FlatConfig, FlatConfigArray } from \"../types\"\n\nimport { createConfig } from \"../build/config-builder\"\nimport { MARKDOWN_CODE_BLOCK_FILES, TYPESCRIPT_SOURCE_FILES } from \"../file-patterns\"\n\n/**\n * TypeScript config — extends typescript-eslint strict presets with project-wide type checking.\n *\n * Presets used:\n * - `tseslint.configs.strictTypeChecked` — all recommended + strict rules with type info\n * - `tseslint.configs.stylisticTypeChecked` — consistent code style with type info\n *\n * The presets already handle many core ESLint rules by disabling them and enabling\n * TS-aware equivalents (no-implied-eval, dot-notation, no-throw-literal, etc.).\n *\n * @see https://typescript-eslint.io/getting-started/\n * @see https://typescript-eslint.io/rules/\n */\nexport function typescriptConfig(opts?: { ai?: boolean; react?: boolean }): FlatConfigArray {\n const isAi = opts?.ai ?? false\n const isReact = opts?.react ?? false\n\n const typeChecked = tseslint.configs.strictTypeChecked\n const stylistic = tseslint.configs.stylisticTypeChecked\n\n // Blocks 0+1: parser setup + ESLint-core replacements (structural, not validated)\n // Block 2 from each: the actual @typescript-eslint/* rules (validated)\n const structuralBlocks = typeChecked.slice(0, 2) as FlatConfigArray\n const ruleBlocks = [typeChecked[2], stylistic[2]] as FlatConfig[]\n\n const builder = createConfig({\n name: \"eslint-config-setup/typescript\",\n passthrough: structuralBlocks,\n presets: ruleBlocks,\n files: [...TYPESCRIPT_SOURCE_FILES],\n ignores: [...MARKDOWN_CODE_BLOCK_FILES],\n languageOptions: {\n parserOptions: {\n // Use project service for automatic tsconfig resolution\n // https://typescript-eslint.io/packages/parser#projectservice\n projectService: true,\n },\n },\n })\n\n // ── Override preset defaults ──────────────────────────────────\n\n // Override bare `error` with underscore-ignore pattern — universal convention\n // Preset sets bare `error` with no options (no ignoreRestSiblings, no _ pattern)\n // https://typescript-eslint.io/rules/no-unused-vars\n builder.overrideRule(\"@typescript-eslint/no-unused-vars\", [\n \"error\",\n {\n args: \"all\",\n argsIgnorePattern: \"^_\",\n caughtErrors: \"all\",\n caughtErrorsIgnorePattern: \"^_\",\n destructuredArrayIgnorePattern: \"^_\",\n varsIgnorePattern: \"^_\",\n ignoreRestSiblings: true,\n },\n ])\n\n // Enforce T[] for simple types, Array<T> for complex — readable array types\n // (in stylisticTypeChecked preset as bare \"error\", we add options)\n // https://typescript-eslint.io/rules/array-type\n builder.overrideRule(\"@typescript-eslint/array-type\", [\n \"error\",\n { default: \"array-simple\" },\n ])\n\n // Override return-await from \"error-handling-correctness-only\" to \"in-try-catch\"\n // https://typescript-eslint.io/rules/return-await\n builder.overrideRule(\"@typescript-eslint/return-await\", [\n \"error\",\n \"in-try-catch\",\n ])\n\n // Downgrade from error to warn — stay current but don't block\n // https://typescript-eslint.io/rules/no-deprecated\n builder.overrideSeverity(\"@typescript-eslint/no-deprecated\", \"warn\")\n\n // Downgrade from error to warn — nudge towards unknown, don't block\n // https://typescript-eslint.io/rules/no-explicit-any\n builder.overrideRule(\"@typescript-eslint/no-explicit-any\", [\n \"warn\",\n { fixToUnknown: true },\n ])\n\n // Enforce `type` over `interface` — consistent, prevents accidental declaration merging\n // https://typescript-eslint.io/rules/consistent-type-definitions\n builder.overrideRule(\"@typescript-eslint/consistent-type-definitions\", [\n \"error\",\n \"type\",\n ])\n\n // Require description for @ts-expect-error — document why you override the compiler\n // https://typescript-eslint.io/rules/ban-ts-comment\n builder.overrideOptions(\"@typescript-eslint/ban-ts-comment\", {\n \"ts-expect-error\": \"allow-with-description\",\n })\n\n // Catch unhandled thenables (not just Promises) and allow async IIFEs\n // https://typescript-eslint.io/rules/no-floating-promises\n builder.overrideOptions(\"@typescript-eslint/no-floating-promises\", {\n checkThenables: true,\n ignoreIIFE: true,\n })\n\n // ── Beyond presets: import/export hygiene ──────────────────\n\n // Enforce `import type { T }` — separate type imports for clarity\n // https://typescript-eslint.io/rules/consistent-type-imports\n builder.addRule(\"@typescript-eslint/consistent-type-imports\", [\n \"error\",\n { fixStyle: isAi ? \"inline-type-imports\" : \"separate-type-imports\" },\n ])\n\n // Enforce `export type { T }` — matches import convention\n // https://typescript-eslint.io/rules/consistent-type-exports\n builder.addRule(\"@typescript-eslint/consistent-type-exports\", [\n \"error\",\n { fixMixedExportsWithInlineTypeSpecifier: true },\n ])\n\n // Prevent type-only imports from triggering side effects\n // https://typescript-eslint.io/rules/no-import-type-side-effects\n builder.addRule(\"@typescript-eslint/no-import-type-side-effects\", \"error\")\n\n // Remove unnecessary namespace qualifiers — cleaner code\n // https://typescript-eslint.io/rules/no-unnecessary-qualifier\n builder.addRule(\"@typescript-eslint/no-unnecessary-qualifier\", \"error\")\n\n // Remove useless `export {}` — keeps module boundaries clean\n // https://typescript-eslint.io/rules/no-useless-empty-export\n builder.addRule(\"@typescript-eslint/no-useless-empty-export\", \"error\")\n\n // Detect redundant `this.x = x` after constructor parameter property\n // https://typescript-eslint.io/rules/no-unnecessary-parameter-property-assignment\n builder.addRule(\n \"@typescript-eslint/no-unnecessary-parameter-property-assignment\",\n \"error\",\n )\n\n // Void-returning callbacks must not accidentally return values\n // Catches: `forEach(x => map.set(x, 1))` — .set() returns the map, but forEach expects void\n // https://typescript-eslint.io/rules/strict-void-return\n builder.addRule(\"@typescript-eslint/strict-void-return\", \"error\")\n\n // Suggest readonly for properties that are never reassigned — clarifies intent\n // https://typescript-eslint.io/rules/prefer-readonly\n builder.addRule(\"@typescript-eslint/prefer-readonly\", isAi ? \"error\" : \"warn\")\n\n // Require comparator for Array.sort() — [10,2,1].sort() → [1,10,2] without one\n // https://typescript-eslint.io/rules/require-array-sort-compare\n builder.addRule(\"@typescript-eslint/require-array-sort-compare\", [\n \"error\",\n { ignoreStringArrays: true },\n ])\n\n // Disallow unsafe type assertions — use type guards instead of `as Type`\n // https://typescript-eslint.io/rules/no-unsafe-type-assertion\n builder.addRule(\"@typescript-eslint/no-unsafe-type-assertion\", \"error\")\n\n // Exhaustive switch — all union/enum values must be handled, no redundant defaults\n // https://typescript-eslint.io/rules/switch-exhaustiveness-check\n builder.addRule(\"@typescript-eslint/switch-exhaustiveness-check\", [\n \"error\",\n {\n allowDefaultCaseForExhaustiveSwitch: false,\n requireDefaultForNonUnion: true,\n },\n ])\n\n // Require async keyword on functions returning Promises — intent is immediately visible\n // https://typescript-eslint.io/rules/promise-function-async\n builder.addRule(\"@typescript-eslint/promise-function-async\", \"error\")\n\n // Enforce property-style signatures — safer due to strict parameter contra-variance\n // https://typescript-eslint.io/rules/method-signature-style\n builder.addRule(\"@typescript-eslint/method-signature-style\", [\n \"error\",\n \"property\",\n ])\n\n // ── Beyond presets: safety & correctness ──────────────────────\n\n // Prevent variable shadowing — catches bugs where inner var hides outer\n // Not in any preset. TS-aware version avoids false positives with type/value merging.\n // https://typescript-eslint.io/rules/no-shadow\n builder.addRule(\"no-shadow\", \"off\")\n builder.addRule(\"@typescript-eslint/no-shadow\", [\n \"error\",\n {\n hoist: \"all\",\n allow: [\"resolve\", \"reject\", \"done\", \"next\", \"error\"],\n ignoreTypeValueShadow: true,\n ignoreFunctionTypeParameterNameValueShadow: true,\n },\n ])\n\n // Allow numbers in template literals — `${count}` is idiomatic JS\n // https://typescript-eslint.io/rules/restrict-template-expressions\n builder.overrideOptions(\"@typescript-eslint/restrict-template-expressions\", { allowNumber: true })\n\n // Require strict boolean expressions — no implicit truthiness checks\n // Prevents bugs like `if (count)` when count is 0 (falsy but valid)\n // https://typescript-eslint.io/rules/strict-boolean-expressions\n builder.addRule(\"@typescript-eslint/strict-boolean-expressions\", [\n \"error\",\n { allowNullableBoolean: true, allowNullableObject: true },\n ])\n\n // ── File overrides ────────────────────────────────────────────\n\n // Disable type-checked rules for plain JS files (no tsconfig coverage)\n // https://typescript-eslint.io/users/configs#disable-type-checked\n builder.addFileOverride(\n \"eslint-config-setup/typescript-js-compat\",\n [\"**/*.{js,mjs,cjs}\"],\n tseslint.configs.disableTypeChecked.rules ?? {},\n )\n\n if (isAi) {\n // ── AI mode: override severity ──────────────────────────────\n builder.overrideSeverity(\"@typescript-eslint/no-explicit-any\", \"error\")\n\n // ── AI mode: override rules with different options ───────────\n builder.overrideRule(\"@typescript-eslint/no-floating-promises\", [\n \"error\",\n { checkThenables: true, ignoreVoid: true },\n ])\n\n // ── AI mode: additional rules ───────────────────────────────\n builder.addRule(\"@typescript-eslint/no-magic-numbers\", [\n \"error\",\n {\n ignore: [-1, 0, 1, 2],\n ignoreArrayIndexes: true,\n ignoreDefaultValues: true,\n enforceConst: true,\n ignoreClassFieldInitialValues: true,\n ignoreEnums: true,\n ignoreNumericLiteralTypes: true,\n ignoreReadonlyClassProperties: true,\n ignoreTypeIndexes: true,\n },\n ])\n builder.addRule(\"@typescript-eslint/explicit-function-return-type\", [\n \"error\",\n {\n allowExpressions: true,\n allowTypedFunctionExpressions: true,\n allowHigherOrderFunctions: true,\n allowIIFEs: true,\n },\n ])\n builder.addRule(\n \"@typescript-eslint/explicit-member-accessibility\",\n \"error\",\n )\n builder.addRule(\n \"@typescript-eslint/prefer-enum-initializers\",\n \"error\",\n )\n builder.addRule(\"@typescript-eslint/naming-convention\", [\n \"error\",\n {\n selector: \"variable\",\n format: isReact\n ? [\"strictCamelCase\", \"UPPER_CASE\", \"StrictPascalCase\"]\n : [\"strictCamelCase\", \"UPPER_CASE\"],\n leadingUnderscore: \"allowSingleOrDouble\",\n trailingUnderscore: \"allow\",\n filter: { regex: \"[- ]\", match: false },\n },\n {\n selector: \"function\",\n format: isReact\n ? [\"strictCamelCase\", \"StrictPascalCase\"]\n : [\"strictCamelCase\"],\n },\n {\n selector: \"parameter\",\n format: [\"strictCamelCase\"],\n leadingUnderscore: \"allow\",\n },\n {\n selector: \"import\",\n format: [\"strictCamelCase\", \"StrictPascalCase\", \"UPPER_CASE\"],\n },\n {\n selector: [\n \"classProperty\",\n \"parameterProperty\",\n \"classMethod\",\n \"objectLiteralMethod\",\n \"typeMethod\",\n \"accessor\",\n ],\n format: [\"strictCamelCase\"],\n leadingUnderscore: \"allowSingleOrDouble\",\n trailingUnderscore: \"allow\",\n filter: { regex: \"[- ]\", match: false },\n },\n {\n selector: [\"objectLiteralProperty\", \"typeProperty\"],\n format: null,\n },\n { selector: \"typeLike\", format: [\"StrictPascalCase\"] },\n {\n selector: \"interface\",\n format: [\"StrictPascalCase\"],\n custom: { regex: \"^I[A-Z]\", match: false },\n },\n {\n selector: \"typeParameter\",\n format: [\"PascalCase\"],\n custom: {\n regex: \"^(T([A-Z][a-zA-Z]*)?|[A-Z])$\",\n match: true,\n },\n },\n {\n selector: \"variable\",\n types: [\"boolean\"],\n format: [\"StrictPascalCase\"],\n prefix: [\"is\", \"has\", \"can\", \"should\", \"will\", \"did\"],\n },\n {\n selector: [\"classProperty\", \"objectLiteralProperty\"],\n format: null,\n modifiers: [\"requiresQuotes\"],\n },\n ])\n builder.addRule(\"@typescript-eslint/member-ordering\", [\n \"warn\",\n {\n default: [\n \"signature\",\n \"call-signature\",\n \"public-static-field\",\n \"protected-static-field\",\n \"private-static-field\",\n \"#private-static-field\",\n \"static-field\",\n \"public-static-method\",\n \"protected-static-method\",\n \"private-static-method\",\n \"#private-static-method\",\n \"static-method\",\n \"public-decorated-field\",\n \"protected-decorated-field\",\n \"private-decorated-field\",\n \"public-instance-field\",\n \"protected-instance-field\",\n \"private-instance-field\",\n \"#private-instance-field\",\n \"public-abstract-field\",\n \"protected-abstract-field\",\n \"field\",\n \"public-constructor\",\n \"protected-constructor\",\n \"private-constructor\",\n \"constructor\",\n [\"public-get\", \"public-set\"],\n [\"protected-get\", \"protected-set\"],\n [\"private-get\", \"private-set\"],\n [\"#private-get\", \"#private-set\"],\n \"public-decorated-method\",\n \"protected-decorated-method\",\n \"private-decorated-method\",\n \"public-instance-method\",\n \"protected-instance-method\",\n \"private-instance-method\",\n \"#private-instance-method\",\n \"public-abstract-method\",\n \"protected-abstract-method\",\n \"method\",\n ],\n },\n ])\n }\n\n return builder.build()\n}\n","/* eslint-disable max-lines-per-function, max-statements -- Rule definition file: one function returning a flat list of rule entries. */\nimport unicornPlugin from \"eslint-plugin-unicorn\"\n\nimport type { FlatConfigArray } from \"../types\"\n\nimport { createConfig } from \"../build/config-builder\"\n\n/**\n * Unicorn config — modern JavaScript idioms and best practices.\n * We hand-pick rules instead of using `flat/recommended` because the\n * recommended preset includes opinionated rules we disagree with\n * (e.g., `no-null`, `no-nested-ternary`, `filename-case`).\n *\n * @see https://github.com/sindresorhus/eslint-plugin-unicorn#rules\n */\nexport function unicornConfig(opts?: { ai?: boolean }): FlatConfigArray {\n const isAi = opts?.ai === true\n\n const builder = createConfig({\n name: \"eslint-config-setup/unicorn\",\n presets: [{\n plugins: { unicorn: unicornPlugin },\n rules: {\n // ── Error prevention ──────────────────────────────────────────\n\n // Forbid `/* eslint-disable */` without specific rule — too broad\n // https://github.com/sindresorhus/eslint-plugin-unicorn/blob/main/docs/rules/no-abusive-eslint-disable.md\n \"unicorn/no-abusive-eslint-disable\": \"error\",\n\n // Disallow `instanceof` with built-in objects — use proper checks instead\n // https://github.com/sindresorhus/eslint-plugin-unicorn/blob/main/docs/rules/no-instanceof-builtins.md\n \"unicorn/no-instanceof-builtins\": \"error\",\n\n // Prevent passing non-function to removeEventListener — common mistake\n // https://github.com/sindresorhus/eslint-plugin-unicorn/blob/main/docs/rules/no-invalid-remove-event-listener.md\n \"unicorn/no-invalid-remove-event-listener\": \"error\",\n\n // Disallow invalid fetch() options — catches typos at lint time\n // https://github.com/sindresorhus/eslint-plugin-unicorn/blob/main/docs/rules/no-invalid-fetch-options.md\n \"unicorn/no-invalid-fetch-options\": \"error\",\n\n // Prefer direct undefined checks over typeof — cleaner with strict mode\n // https://github.com/sindresorhus/eslint-plugin-unicorn/blob/main/docs/rules/no-typeof-undefined.md\n \"unicorn/no-typeof-undefined\": \"error\",\n\n // Remove useless fallback in object spread ({ ...a, x: a.x ?? y })\n // https://github.com/sindresorhus/eslint-plugin-unicorn/blob/main/docs/rules/no-useless-fallback-in-spread.md\n \"unicorn/no-useless-fallback-in-spread\": \"error\",\n\n // Remove unnecessary .length checks before array operations\n // https://github.com/sindresorhus/eslint-plugin-unicorn/blob/main/docs/rules/no-useless-length-check.md\n \"unicorn/no-useless-length-check\": \"error\",\n\n // Remove unnecessary spread operators ([...array] when array already exists)\n // https://github.com/sindresorhus/eslint-plugin-unicorn/blob/main/docs/rules/no-useless-spread.md\n \"unicorn/no-useless-spread\": \"error\",\n\n // Remove useless Promise.resolve/reject wrappers — simplify async code\n // https://github.com/sindresorhus/eslint-plugin-unicorn/blob/main/docs/rules/no-useless-promise-resolve-reject.md\n \"unicorn/no-useless-promise-resolve-reject\": \"error\",\n\n // Disallow redundant undefined where omission preserves semantics.\n // Keep call arguments unchecked: TypeScript often needs explicit\n // `undefined` for required parameters typed as `T | undefined`.\n // https://github.com/sindresorhus/eslint-plugin-unicorn/blob/main/docs/rules/no-useless-undefined.md\n \"unicorn/no-useless-undefined\": [\"warn\", { checkArguments: false }],\n\n // Disallow `await` in Promise.all/race arguments — already a promise\n // https://github.com/sindresorhus/eslint-plugin-unicorn/blob/main/docs/rules/no-await-in-promise-methods.md\n \"unicorn/no-await-in-promise-methods\": \"error\",\n\n // Catch `!a === b` bugs — use `a !== b` instead\n // https://github.com/sindresorhus/eslint-plugin-unicorn/blob/main/docs/rules/no-negation-in-equality-check.md\n \"unicorn/no-negation-in-equality-check\": \"error\",\n\n // Disallow objects with `.then` property — prevents accidental thenables\n // https://github.com/sindresorhus/eslint-plugin-unicorn/blob/main/docs/rules/no-thenable.md\n \"unicorn/no-thenable\": \"error\",\n\n // Disallow `(await foo).bar` — assign to variable first for clarity\n // https://github.com/sindresorhus/eslint-plugin-unicorn/blob/main/docs/rules/no-await-expression-member.md\n \"unicorn/no-await-expression-member\": \"error\",\n\n // Disallow `const self = this` — use arrow functions instead\n // https://github.com/sindresorhus/eslint-plugin-unicorn/blob/main/docs/rules/no-this-assignment.md\n \"unicorn/no-this-assignment\": \"error\",\n\n // Disallow `await` on non-promise values — unnecessary overhead\n // https://github.com/sindresorhus/eslint-plugin-unicorn/blob/main/docs/rules/no-unnecessary-await.md\n \"unicorn/no-unnecessary-await\": \"error\",\n\n // Disallow unnecessary slice end argument — `.length` is the default\n // https://github.com/sindresorhus/eslint-plugin-unicorn/blob/main/docs/rules/no-unnecessary-slice-end.md\n \"unicorn/no-unnecessary-slice-end\": \"error\",\n\n // OFF: Stylistic — developers should decide their own array initialization pattern\n // https://github.com/sindresorhus/eslint-plugin-unicorn/blob/main/docs/rules/no-immediate-mutation.md\n \"unicorn/no-immediate-mutation\": \"off\",\n\n // Disallow recursive access in getters/setters — infinite loop risk\n // https://github.com/sindresorhus/eslint-plugin-unicorn/blob/main/docs/rules/no-accessor-recursion.md\n \"unicorn/no-accessor-recursion\": \"error\",\n\n // Disallow anonymous default exports — hard to find and refactor\n // https://github.com/sindresorhus/eslint-plugin-unicorn/blob/main/docs/rules/no-anonymous-default-export.md\n \"unicorn/no-anonymous-default-export\": \"error\",\n\n // Disallow `this` argument in array methods — use arrow functions\n // https://github.com/sindresorhus/eslint-plugin-unicorn/blob/main/docs/rules/no-array-method-this-argument.md\n \"unicorn/no-array-method-this-argument\": \"error\",\n\n // Disallow passing function references directly to iterator methods\n // Prevents bugs like `['1','2'].map(parseInt)` → [1, NaN]\n // https://github.com/sindresorhus/eslint-plugin-unicorn/blob/main/docs/rules/no-array-callback-reference.md\n \"unicorn/no-array-callback-reference\": \"error\",\n\n // Disallow unreadable IIFEs — extract to named function\n // https://github.com/sindresorhus/eslint-plugin-unicorn/blob/main/docs/rules/no-unreadable-iife.md\n \"unicorn/no-unreadable-iife\": \"error\",\n\n // Require Error messages — aids debugging\n // https://github.com/sindresorhus/eslint-plugin-unicorn/blob/main/docs/rules/error-message.md\n \"unicorn/error-message\": \"error\",\n\n // Require `new` keyword when throwing errors — consistent pattern\n // https://github.com/sindresorhus/eslint-plugin-unicorn/blob/main/docs/rules/throw-new-error.md\n \"unicorn/throw-new-error\": \"error\",\n\n // Prefer consistent types when spreading a ternary in an array literal\n // https://github.com/sindresorhus/eslint-plugin-unicorn/blob/main/docs/rules/consistent-empty-array-spread.md\n \"unicorn/consistent-empty-array-spread\": \"error\",\n\n // Prefer passing Date directly to constructor when cloning\n // https://github.com/sindresorhus/eslint-plugin-unicorn/blob/main/docs/rules/consistent-date-clone.md\n \"unicorn/consistent-date-clone\": \"error\",\n\n // Enforce consistent style for indexOf/findIndex existence checks\n // https://github.com/sindresorhus/eslint-plugin-unicorn/blob/main/docs/rules/consistent-existence-index-check.md\n \"unicorn/consistent-existence-index-check\": \"error\",\n\n // Move functions to the smallest possible scope — avoids re-creation on every call,\n // improves testability, and makes dependencies explicit\n // https://github.com/sindresorhus/eslint-plugin-unicorn/blob/main/docs/rules/consistent-function-scoping.md\n \"unicorn/consistent-function-scoping\": \"warn\",\n\n // Enforce consistent filename casing — camelCase, PascalCase, or kebab-case (no snake_case)\n // https://github.com/sindresorhus/eslint-plugin-unicorn/blob/main/docs/rules/filename-case.md\n \"unicorn/filename-case\": [\n \"error\",\n {\n cases: {\n camelCase: true,\n pascalCase: true,\n kebabCase: true,\n },\n ignore: [\"__tests__\"],\n },\n ],\n\n // Discourage Array.reduce() — hard to read for many developers, prefer for...of or other methods\n // https://github.com/sindresorhus/eslint-plugin-unicorn/blob/main/docs/rules/no-array-reduce.md\n \"unicorn/no-array-reduce\": \"warn\",\n\n // Prefer for...of over C-style for loops — more readable when index isn't needed\n // https://github.com/sindresorhus/eslint-plugin-unicorn/blob/main/docs/rules/no-for-loop.md\n \"unicorn/no-for-loop\": \"warn\",\n\n // ── Modern API preferences ────────────────────────────────────\n\n // Prefer .flatMap() over .map().flat() — single pass, more readable\n // https://github.com/sindresorhus/eslint-plugin-unicorn/blob/main/docs/rules/prefer-array-flat-map.md\n \"unicorn/prefer-array-flat-map\": \"error\",\n\n // Prefer .find() over .filter()[0] — stops at first match\n // https://github.com/sindresorhus/eslint-plugin-unicorn/blob/main/docs/rules/prefer-array-find.md\n \"unicorn/prefer-array-find\": \"error\",\n\n // Prefer .flat() over manual recursive flattening\n // https://github.com/sindresorhus/eslint-plugin-unicorn/blob/main/docs/rules/prefer-array-flat.md\n \"unicorn/prefer-array-flat\": \"error\",\n\n // Prefer .indexOf() over manual search loops\n // https://github.com/sindresorhus/eslint-plugin-unicorn/blob/main/docs/rules/prefer-array-index-of.md\n \"unicorn/prefer-array-index-of\": \"error\",\n\n // Prefer .some() over .find() !== undefined — semantic intent\n // https://github.com/sindresorhus/eslint-plugin-unicorn/blob/main/docs/rules/prefer-array-some.md\n \"unicorn/prefer-array-some\": \"error\",\n\n // Prefer .at(-1) over arr[arr.length - 1] — cleaner negative indexing\n // https://github.com/sindresorhus/eslint-plugin-unicorn/blob/main/docs/rules/prefer-at.md\n \"unicorn/prefer-at\": \"error\",\n\n // Prefer .includes() over .indexOf() !== -1 — boolean intent\n // https://github.com/sindresorhus/eslint-plugin-unicorn/blob/main/docs/rules/prefer-includes.md\n \"unicorn/prefer-includes\": \"error\",\n\n // Prefer .before()/.after()/.replaceWith() over parent.insertBefore()\n // https://github.com/sindresorhus/eslint-plugin-unicorn/blob/main/docs/rules/prefer-modern-dom-apis.md\n \"unicorn/prefer-modern-dom-apis\": \"error\",\n\n // Prefer element.dataset.foo over setAttribute('data-foo') — modern, readable\n // https://github.com/sindresorhus/eslint-plugin-unicorn/blob/main/docs/rules/prefer-dom-node-dataset.md\n \"unicorn/prefer-dom-node-dataset\": \"error\",\n\n // Prefer Math.log10/Math.hypot over manual math — accurate and readable\n // https://github.com/sindresorhus/eslint-plugin-unicorn/blob/main/docs/rules/prefer-modern-math-apis.md\n \"unicorn/prefer-modern-math-apis\": \"error\",\n\n // Prefer negative index over length-based — cleaner with .slice(-n)\n // https://github.com/sindresorhus/eslint-plugin-unicorn/blob/main/docs/rules/prefer-negative-index.md\n \"unicorn/prefer-negative-index\": \"error\",\n\n // Prefer Number.isFinite/Number.isNaN over global — no coercion\n // https://github.com/sindresorhus/eslint-plugin-unicorn/blob/main/docs/rules/prefer-number-properties.md\n \"unicorn/prefer-number-properties\": \"error\",\n\n // Prefer Object.fromEntries() over manual reduce for key-value mapping\n // https://github.com/sindresorhus/eslint-plugin-unicorn/blob/main/docs/rules/prefer-object-from-entries.md\n \"unicorn/prefer-object-from-entries\": \"error\",\n\n // Prefer Set.has() over Array.includes() for repeated lookups — O(1)\n // https://github.com/sindresorhus/eslint-plugin-unicorn/blob/main/docs/rules/prefer-set-has.md\n \"unicorn/prefer-set-has\": \"error\",\n\n // Prefer .replaceAll() over regex with global flag — clearer intent\n // https://github.com/sindresorhus/eslint-plugin-unicorn/blob/main/docs/rules/prefer-string-replace-all.md\n \"unicorn/prefer-string-replace-all\": \"error\",\n\n // Prefer .slice() over .substr()/.substring() — consistent, no gotchas\n // https://github.com/sindresorhus/eslint-plugin-unicorn/blob/main/docs/rules/prefer-string-slice.md\n \"unicorn/prefer-string-slice\": \"error\",\n\n // Prefer .startsWith()/.endsWith() over regex — simpler, faster\n // https://github.com/sindresorhus/eslint-plugin-unicorn/blob/main/docs/rules/prefer-string-starts-ends-with.md\n \"unicorn/prefer-string-starts-ends-with\": \"error\",\n\n // Prefer .trimStart()/.trimEnd() over .trimLeft()/.trimRight()\n // https://github.com/sindresorhus/eslint-plugin-unicorn/blob/main/docs/rules/prefer-string-trim-start-end.md\n \"unicorn/prefer-string-trim-start-end\": \"error\",\n\n // Prefer structuredClone() over JSON.parse(JSON.stringify()) — handles more types\n // https://github.com/sindresorhus/eslint-plugin-unicorn/blob/main/docs/rules/prefer-structured-clone.md\n \"unicorn/prefer-structured-clone\": \"error\",\n\n // Prefer top-level await over async IIFE — cleaner module pattern\n // https://github.com/sindresorhus/eslint-plugin-unicorn/blob/main/docs/rules/prefer-top-level-await.md\n \"unicorn/prefer-top-level-await\": \"error\",\n\n // Throw TypeError for type checks — correct error type\n // https://github.com/sindresorhus/eslint-plugin-unicorn/blob/main/docs/rules/prefer-type-error.md\n \"unicorn/prefer-type-error\": \"error\",\n\n // ── Regex ─────────────────────────────────────────────────────\n\n // Disabled — conflicts with regexp/strict from eslint-plugin-regexp.\n // Both rules auto-fix regex escaping but disagree on whether characters\n // like { } ] should be escaped, causing circular fixes.\n // regexp/strict is the more thorough rule, so we defer to it.\n \"unicorn/better-regex\": \"off\",\n\n // ── Misc ──────────────────────────────────────────────────────\n\n // Enforce `error` name in catch blocks — consistent naming\n // https://github.com/sindresorhus/eslint-plugin-unicorn/blob/main/docs/rules/catch-error-name.md\n \"unicorn/catch-error-name\": [\"error\", { name: \"error\" }],\n\n // Enforce `new` for builtins that require it (Map, Set, WeakMap, etc.)\n // https://github.com/sindresorhus/eslint-plugin-unicorn/blob/main/docs/rules/new-for-builtins.md\n \"unicorn/new-for-builtins\": \"error\",\n\n // Prefer Array.from({length}) or fill() over new Array(n) — explicit intent\n // https://github.com/sindresorhus/eslint-plugin-unicorn/blob/main/docs/rules/no-new-array.md\n \"unicorn/no-new-array\": \"error\",\n\n // Prefer Buffer.from()/Buffer.alloc() over new Buffer() — deprecated\n // https://github.com/sindresorhus/eslint-plugin-unicorn/blob/main/docs/rules/no-new-buffer.md\n \"unicorn/no-new-buffer\": \"error\",\n\n // Forbid unreadable destructuring like `const [,,, d] = arr`\n // https://github.com/sindresorhus/eslint-plugin-unicorn/blob/main/docs/rules/no-unreadable-array-destructuring.md\n \"unicorn/no-unreadable-array-destructuring\": \"error\",\n\n // Remove unnecessary `.0` in numbers (1.0 → 1) — cleaner\n // https://github.com/sindresorhus/eslint-plugin-unicorn/blob/main/docs/rules/no-zero-fractions.md\n \"unicorn/no-zero-fractions\": \"error\",\n\n // Enforce lowercase hex (0xff not 0xFF) — consistent\n // https://github.com/sindresorhus/eslint-plugin-unicorn/blob/main/docs/rules/number-literal-case.md\n \"unicorn/number-literal-case\": \"error\",\n\n // Enforce numeric separators (1_000_000 not 1000000) — readable large numbers\n // https://github.com/sindresorhus/eslint-plugin-unicorn/blob/main/docs/rules/numeric-separators-style.md\n \"unicorn/numeric-separators-style\": \"error\",\n\n // Prefer `export { x } from 'y'` over import then re-export\n // https://github.com/sindresorhus/eslint-plugin-unicorn/blob/main/docs/rules/prefer-export-from.md\n \"unicorn/prefer-export-from\": [\"error\", { checkUsedVariables: false }],\n\n // Prefer built-in coercion (String, Number, Boolean) over wrapper functions\n // https://github.com/sindresorhus/eslint-plugin-unicorn/blob/main/docs/rules/prefer-native-coercion-functions.md\n \"unicorn/prefer-native-coercion-functions\": \"error\",\n\n // Prefer .test() over .match() for boolean regex checks\n // https://github.com/sindresorhus/eslint-plugin-unicorn/blob/main/docs/rules/prefer-regexp-test.md\n \"unicorn/prefer-regexp-test\": \"error\",\n\n // Prefer [...iterable] spread over Array.from(iterable) — concise\n // https://github.com/sindresorhus/eslint-plugin-unicorn/blob/main/docs/rules/prefer-spread.md\n \"unicorn/prefer-spread\": \"error\",\n\n // Prefer relative URLs over absolute same-origin URLs\n // https://github.com/sindresorhus/eslint-plugin-unicorn/blob/main/docs/rules/relative-url-style.md\n \"unicorn/relative-url-style\": \"error\",\n\n // Prefer `node:fs` over `fs` — explicit built-in module protocol\n // https://github.com/sindresorhus/eslint-plugin-unicorn/blob/main/docs/rules/prefer-node-protocol.md\n \"unicorn/prefer-node-protocol\": \"error\",\n\n // Prefer `globalThis` over `window`/`self`/`global` — universal\n // https://github.com/sindresorhus/eslint-plugin-unicorn/blob/main/docs/rules/prefer-global-this.md\n \"unicorn/prefer-global-this\": \"error\",\n\n // Prefer omitting unused catch binding — cleaner syntax\n // https://github.com/sindresorhus/eslint-plugin-unicorn/blob/main/docs/rules/prefer-optional-catch-binding.md\n \"unicorn/prefer-optional-catch-binding\": \"error\",\n\n // Prefer `Date.now()` over `new Date().getTime()` — direct and readable\n // https://github.com/sindresorhus/eslint-plugin-unicorn/blob/main/docs/rules/prefer-date-now.md\n \"unicorn/prefer-date-now\": \"error\",\n\n // Enforce consistent `utf-8` casing for text encoding identifiers\n // https://github.com/sindresorhus/eslint-plugin-unicorn/blob/main/docs/rules/text-encoding-identifier-case.md\n \"unicorn/text-encoding-identifier-case\": \"error\",\n\n // Prefer `import.meta.url`/`import.meta.dirname` over `__filename`/`__dirname`\n // https://github.com/sindresorhus/eslint-plugin-unicorn/blob/main/docs/rules/prefer-import-meta-properties.md\n \"unicorn/prefer-import-meta-properties\": \"error\",\n\n // OFF: Sequential .push() is natural in codegen and conditional builders.\n // No real performance benefit in modern V8 — purely stylistic.\n // https://github.com/sindresorhus/eslint-plugin-unicorn/blob/main/docs/rules/prefer-single-call.md\n \"unicorn/prefer-single-call\": \"off\",\n },\n }],\n })\n\n if (isAi) {\n // Severity overrides: promote existing base rules from warn to error\n builder.overrideSeverity(\"unicorn/consistent-function-scoping\", \"error\")\n builder.overrideSeverity(\"unicorn/no-array-reduce\", \"error\")\n builder.overrideSeverity(\"unicorn/no-for-loop\", \"error\")\n\n // New AI-only rules\n builder.addRule(\"unicorn/no-for-each\", \"error\")\n builder.addRule(\"unicorn/prefer-ternary\", [\"error\", \"only-single-line\"])\n builder.addRule(\"unicorn/prefer-switch\", [\"error\", { minimumCases: 3 }])\n builder.addRule(\"unicorn/no-useless-switch-case\", \"error\")\n builder.addRule(\"unicorn/custom-error-definition\", \"error\")\n builder.addRule(\"unicorn/prefer-default-parameters\", \"error\")\n builder.addRule(\"unicorn/prefer-logical-operator-over-ternary\", \"error\")\n builder.addRule(\"unicorn/prefer-math-min-max\", \"error\")\n builder.addRule(\"unicorn/prefer-set-size\", \"error\")\n builder.addRule(\"unicorn/explicit-length-check\", \"error\")\n builder.addRule(\"unicorn/switch-case-braces\", \"error\")\n builder.addRule(\"unicorn/no-array-push-push\", \"error\")\n }\n\n return builder.build()\n}\n","import type { FlatConfigArray } from \"../types\"\n\n/**\n * Config file overrides — relaxed rules for tool configuration files.\n * Config files (vite, vitest, next, tailwind, postcss) have their own\n * patterns that conflict with strict app-code rules.\n *\n * File patterns: *.config.*, vite.config.*, vitest.config.*, etc.\n */\nexport function configFilesOverride(): FlatConfigArray {\n return [\n {\n name: \"eslint-config-setup/config-files\",\n files: [\n \"**/*.config.{ts,mts,cts,js,mjs,cjs}\",\n \"**/vite.config.*\",\n \"**/vitest.config.*\",\n \"**/next.config.*\",\n \"**/tailwind.config.*\",\n \"**/postcss.config.*\",\n ],\n rules: {\n // Config files often require default exports (Vite, Next.js, Tailwind)\n \"import/no-default-export\": \"off\",\n\n // Config files can have complex configuration objects\n complexity: \"off\",\n \"max-lines\": \"off\",\n \"max-lines-per-function\": \"off\",\n \"max-statements\": \"off\",\n\n // Config files may use require() for dynamic plugin loading\n \"@typescript-eslint/no-require-imports\": \"off\",\n\n // Config files may log build info to console\n \"no-console\": \"off\",\n\n // Config files often have magic numbers (ports, sizes, timeouts)\n \"no-magic-numbers\": \"off\",\n \"@typescript-eslint/no-magic-numbers\": \"off\",\n },\n },\n ]\n}\n","import type { FlatConfigArray } from \"../types\"\n\n/**\n * Declaration file overrides — minimal rules for `.d.ts` files.\n * Declaration files follow their own patterns (ambient declarations,\n * interface merging, namespaces) that conflict with app-code rules.\n *\n * File pattern: *.d.ts files\n */\nexport function declarationsOverride(): FlatConfigArray {\n return [\n {\n name: \"eslint-config-setup/declarations\",\n files: [\"**/*.d.ts\"],\n rules: {\n // Declaration files often have unused type parameters/variables\n \"@typescript-eslint/no-unused-vars\": \"off\",\n\n // Empty interfaces are valid for declaration merging\n \"@typescript-eslint/no-empty-interface\": \"off\",\n\n // Empty object types are used for extensible interfaces\n \"@typescript-eslint/no-empty-object-type\": \"off\",\n\n // `any` is sometimes necessary in third-party type declarations\n \"@typescript-eslint/no-explicit-any\": \"off\",\n\n // Both `type` and `interface` are valid in declarations\n \"@typescript-eslint/consistent-type-definitions\": \"off\",\n\n // Namespaces are standard in ambient declarations\n \"@typescript-eslint/no-namespace\": \"off\",\n\n // Duplicate imports happen with declaration merging\n \"import/no-duplicates\": \"off\",\n\n // Unused imports are common in re-export declaration files\n \"unused-imports/no-unused-imports\": \"off\",\n\n // ── AI mode rules that don't apply to declaration files ────────\n\n // Declarations inherit return types from the implementation\n \"@typescript-eslint/explicit-function-return-type\": \"off\",\n\n // Third-party naming conventions must be followed as-is\n \"@typescript-eslint/naming-convention\": \"off\",\n\n // Abbreviations in third-party types are unavoidable\n \"unicorn/prevent-abbreviations\": \"off\",\n\n // .d.ts filename is dictated by the module it declares\n \"unicorn/filename-case\": \"off\",\n },\n },\n ]\n}\n","import playwrightPlugin from \"eslint-plugin-playwright\"\n\nimport type { FlatConfigArray } from \"../types\"\n\n/**\n * E2E test overrides — Playwright rules + relaxed strictness for E2E tests.\n *\n * File pattern: *.spec.ts (Playwright convention)\n *\n * @see https://github.com/playwright-community/eslint-plugin-playwright#rules\n */\nexport function e2eOverride(): FlatConfigArray {\n return [\n {\n name: \"eslint-config-setup/e2e\",\n files: [\"**/*.spec.ts\"],\n plugins: {\n playwright: playwrightPlugin,\n },\n rules: {\n // ── Playwright rules ──────────────────────────────────────────\n\n // Every test must contain at least one expect()\n // https://github.com/playwright-community/eslint-plugin-playwright/blob/main/docs/rules/expect-expect.md\n \"playwright/expect-expect\": \"error\",\n\n // Limit describe nesting to 3 levels — keeps tests readable\n // https://github.com/playwright-community/eslint-plugin-playwright/blob/main/docs/rules/max-nested-describe.md\n \"playwright/max-nested-describe\": [\"error\", { max: 3 }],\n\n // Detect missing await on Playwright async methods — common mistake\n // https://github.com/playwright-community/eslint-plugin-playwright/blob/main/docs/rules/missing-playwright-await.md\n \"playwright/missing-playwright-await\": \"error\",\n\n // No expect() inside conditionals — tests should be deterministic\n // https://github.com/playwright-community/eslint-plugin-playwright/blob/main/docs/rules/no-conditional-expect.md\n \"playwright/no-conditional-expect\": \"error\",\n\n // Warn on conditional logic in tests — tests should be linear\n // https://github.com/playwright-community/eslint-plugin-playwright/blob/main/docs/rules/no-conditional-in-test.md\n \"playwright/no-conditional-in-test\": \"warn\",\n\n // Prefer locators over element handles — auto-retry, less flaky\n // https://github.com/playwright-community/eslint-plugin-playwright/blob/main/docs/rules/no-element-handle.md\n \"playwright/no-element-handle\": \"error\",\n\n // No page.evaluate with arbitrary code — brittle, hard to debug\n // https://github.com/playwright-community/eslint-plugin-playwright/blob/main/docs/rules/no-eval.md\n \"playwright/no-eval\": \"error\",\n\n // No test.only — prevents accidentally skipping tests in CI\n // https://github.com/playwright-community/eslint-plugin-playwright/blob/main/docs/rules/no-focused-test.md\n \"playwright/no-focused-test\": \"error\",\n\n // Warn on { force: true } — bypasses visibility/actionability checks\n // https://github.com/playwright-community/eslint-plugin-playwright/blob/main/docs/rules/no-force-option.md\n \"playwright/no-force-option\": \"warn\",\n\n // No waitUntil: \"networkidle\" — unreliable, use specific waits\n // https://github.com/playwright-community/eslint-plugin-playwright/blob/main/docs/rules/no-networkidle.md\n \"playwright/no-networkidle\": \"error\",\n\n // No page.pause() — debugging artifact, breaks CI\n // https://github.com/playwright-community/eslint-plugin-playwright/blob/main/docs/rules/no-page-pause.md\n \"playwright/no-page-pause\": \"error\",\n\n // Warn on test.skip — track disabled tests\n // https://github.com/playwright-community/eslint-plugin-playwright/blob/main/docs/rules/no-skipped-test.md\n \"playwright/no-skipped-test\": \"warn\",\n\n // No unnecessary await on non-promise values\n // https://github.com/playwright-community/eslint-plugin-playwright/blob/main/docs/rules/no-useless-await.md\n \"playwright/no-useless-await\": \"error\",\n\n // No double-negative assertions: expect(x).not.not...\n // https://github.com/playwright-community/eslint-plugin-playwright/blob/main/docs/rules/no-useless-not.md\n \"playwright/no-useless-not\": \"error\",\n\n // Warn on waitForSelector — prefer locators with auto-wait\n // https://github.com/playwright-community/eslint-plugin-playwright/blob/main/docs/rules/no-wait-for-selector.md\n \"playwright/no-wait-for-selector\": \"warn\",\n\n // No hardcoded timeouts — use Playwright's built-in waiting\n // https://github.com/playwright-community/eslint-plugin-playwright/blob/main/docs/rules/no-wait-for-timeout.md\n \"playwright/no-wait-for-timeout\": \"error\",\n\n // Prefer web-first assertions (toBeVisible, toHaveText) — auto-retry\n // https://github.com/playwright-community/eslint-plugin-playwright/blob/main/docs/rules/prefer-web-first-assertions.md\n \"playwright/prefer-web-first-assertions\": \"error\",\n\n // Validate expect() usage — proper matcher and argument count\n // https://github.com/playwright-community/eslint-plugin-playwright/blob/main/docs/rules/valid-expect.md\n \"playwright/valid-expect\": \"error\",\n\n // ── Relaxed rules for E2E tests ───────────────────────────────\n // E2E tests are long procedural scripts with many page interactions\n\n \"max-lines\": \"off\",\n \"max-lines-per-function\": \"off\",\n \"max-statements\": \"off\",\n },\n },\n ]\n}\n","import type { FlatConfigArray } from \"../types\"\n\n/**\n * Script file overrides — relaxed rules for build/dev scripts.\n * Scripts are CLI tools that legitimately use console.log and process.exit.\n *\n * File pattern: scripts dir (*.ts, *.mts, *.js, *.mjs)\n */\nexport function scriptsOverride(): FlatConfigArray {\n return [\n {\n name: \"eslint-config-setup/scripts\",\n files: [\"**/scripts/**/*.{ts,mts,js,mjs}\"],\n rules: {\n // Scripts use console for user-facing output\n \"no-console\": \"off\",\n\n // Scripts use process.exit for clean termination\n // https://github.com/eslint-community/eslint-plugin-n/blob/master/docs/rules/no-process-exit.md\n \"node/no-process-exit\": \"off\",\n\n // Scripts can be long (build pipelines, code generators)\n \"max-lines\": \"off\",\n \"max-lines-per-function\": \"off\",\n\n // Scripts are often procedural without explicit return types\n \"@typescript-eslint/explicit-function-return-type\": \"off\",\n\n // Scripts legitimately call process.exit()\n // https://github.com/sindresorhus/eslint-plugin-unicorn/blob/main/docs/rules/no-process-exit.md\n \"unicorn/no-process-exit\": \"off\",\n },\n },\n ]\n}\n","import storybookPlugin from \"eslint-plugin-storybook\"\n\nimport type { FlatConfigArray } from \"../types\"\n\n/**\n * Storybook overrides — Storybook best-practice rules for story files.\n *\n * File pattern: *.stories.{ts,tsx}\n *\n * @see https://github.com/storybookjs/eslint-plugin-storybook#supported-rules\n */\nexport function storiesOverride(): FlatConfigArray {\n return [\n {\n name: \"eslint-config-setup/stories\",\n files: [\"**/*.stories.{ts,tsx}\"],\n plugins: {\n storybook: storybookPlugin as Record<string, unknown>,\n },\n rules: {\n // ── Storybook rules ───────────────────────────────────────────\n\n // Await play function interactions — prevents race conditions\n // https://github.com/storybookjs/eslint-plugin-storybook/blob/main/docs/rules/await-interactions.md\n \"storybook/await-interactions\": \"error\",\n\n // Stories must have a default export (meta) — Storybook requirement\n // https://github.com/storybookjs/eslint-plugin-storybook/blob/main/docs/rules/default-exports.md\n \"storybook/default-exports\": \"error\",\n\n // Use / for hierarchy separators, not | or . — Storybook 7+ convention\n // https://github.com/storybookjs/eslint-plugin-storybook/blob/main/docs/rules/hierarchy-separator.md\n \"storybook/hierarchy-separator\": \"error\",\n\n // No redundant story names that match export name — DRY\n // https://github.com/storybookjs/eslint-plugin-storybook/blob/main/docs/rules/no-redundant-story-name.md\n \"storybook/no-redundant-story-name\": \"error\",\n\n // No deprecated storiesOf() API — use CSF (Component Story Format)\n // https://github.com/storybookjs/eslint-plugin-storybook/blob/main/docs/rules/no-stories-of.md\n \"storybook/no-stories-of\": \"error\",\n\n // Warn if title is in meta — auto-title is preferred in CSF 3\n // https://github.com/storybookjs/eslint-plugin-storybook/blob/main/docs/rules/no-title-property-in-meta.md\n \"storybook/no-title-property-in-meta\": \"warn\",\n\n // Story exports should be PascalCase — component naming convention\n // https://github.com/storybookjs/eslint-plugin-storybook/blob/main/docs/rules/prefer-pascal-case.md\n \"storybook/prefer-pascal-case\": \"error\",\n\n // File must export at least one story — prevents empty story files\n // https://github.com/storybookjs/eslint-plugin-storybook/blob/main/docs/rules/story-exports.md\n \"storybook/story-exports\": \"error\",\n\n // Use Storybook's expect() instead of Jest/Vitest in play functions\n // https://github.com/storybookjs/eslint-plugin-storybook/blob/main/docs/rules/use-storybook-expect.md\n \"storybook/use-storybook-expect\": \"error\",\n\n // Use Storybook's Testing Library, not direct import\n // https://github.com/storybookjs/eslint-plugin-storybook/blob/main/docs/rules/use-storybook-testing-library.md\n \"storybook/use-storybook-testing-library\": \"error\",\n\n // Enforce `satisfies Meta<typeof Component>` on default export — type-safe meta\n // https://github.com/storybookjs/eslint-plugin-storybook/blob/main/docs/rules/meta-satisfies-type.md\n \"storybook/meta-satisfies-type\": \"error\",\n\n // ── Relaxed rules for stories ─────────────────────────────────\n\n // Stories require default exports (meta object)\n \"import/no-default-export\": \"off\",\n\n // Stories can be long (many variants of a component)\n \"max-lines\": \"off\",\n \"max-lines-per-function\": \"off\",\n },\n },\n ]\n}\n","import type { Linter } from \"eslint\"\n\nimport vitestPlugin from \"@vitest/eslint-plugin\"\nimport testingLibraryPlugin from \"eslint-plugin-testing-library\"\n\nimport type { FlatConfigArray } from \"../types\"\n\nconst TEST_FILES = [\"**/*.test.{ts,tsx}\", \"**/__tests__/**/*.{ts,tsx}\"]\n\nconst VITEST_RULES: Linter.RulesRecord = {\n // ── Vitest rules ──────────────────────────────────────────────\n\n // Every test must contain at least one assertion\n // https://github.com/vitest-dev/eslint-plugin-vitest/blob/main/docs/rules/expect-expect.md\n \"vitest/expect-expect\": \"error\",\n\n // Prevent duplicate test titles within a describe block\n // https://github.com/vitest-dev/eslint-plugin-vitest/blob/main/docs/rules/no-identical-title.md\n \"vitest/no-identical-title\": \"error\",\n\n // No it.only / describe.only — prevents accidentally skipping tests in CI\n // https://github.com/vitest-dev/eslint-plugin-vitest/blob/main/docs/rules/no-focused-tests.md\n \"vitest/no-focused-tests\": \"error\",\n\n // Warn on it.skip / describe.skip — track disabled tests\n // https://github.com/vitest-dev/eslint-plugin-vitest/blob/main/docs/rules/no-disabled-tests.md\n \"vitest/no-disabled-tests\": \"warn\",\n\n // No duplicate beforeEach/afterEach hooks — merge them\n // https://github.com/vitest-dev/eslint-plugin-vitest/blob/main/docs/rules/no-duplicate-hooks.md\n \"vitest/no-duplicate-hooks\": \"error\",\n\n // Prefer .toBe() over .toEqual() for primitives — clearer intent\n // https://github.com/vitest-dev/eslint-plugin-vitest/blob/main/docs/rules/prefer-to-be.md\n \"vitest/prefer-to-be\": \"error\",\n\n // Prefer .toHaveLength() over .toBe(arr.length) — better errors\n // https://github.com/vitest-dev/eslint-plugin-vitest/blob/main/docs/rules/prefer-to-have-length.md\n \"vitest/prefer-to-have-length\": \"error\",\n\n // Validate expect() usage — no dangling expect without assertion\n // https://github.com/vitest-dev/eslint-plugin-vitest/blob/main/docs/rules/valid-expect.md\n \"vitest/valid-expect\": \"error\",\n\n // Validate test/describe title format — no empty or invalid titles\n // https://github.com/vitest-dev/eslint-plugin-vitest/blob/main/docs/rules/valid-title.md\n \"vitest/valid-title\": \"error\",\n\n // No conditional logic (if/else) inside tests — split into separate tests\n // https://github.com/vitest-dev/eslint-plugin-vitest/blob/main/docs/rules/no-conditional-in-test.md\n \"vitest/no-conditional-in-test\": \"error\",\n\n // No expect() inside conditional blocks — always assert unconditionally\n // https://github.com/vitest-dev/eslint-plugin-vitest/blob/main/docs/rules/no-conditional-expect.md\n \"vitest/no-conditional-expect\": \"error\",\n\n // No standalone expect() outside test blocks — always wrap in it/test\n // https://github.com/vitest-dev/eslint-plugin-vitest/blob/main/docs/rules/no-standalone-expect.md\n \"vitest/no-standalone-expect\": \"error\",\n\n // Prefer .toStrictEqual() over .toEqual() — catches undefined vs missing\n // https://github.com/vitest-dev/eslint-plugin-vitest/blob/main/docs/rules/prefer-strict-equal.md\n \"vitest/prefer-strict-equal\": \"error\",\n\n // Prefer vi.spyOn() over vi.fn() for method mocks — preserves original\n // https://github.com/vitest-dev/eslint-plugin-vitest/blob/main/docs/rules/prefer-spy-on.md\n \"vitest/prefer-spy-on\": \"error\",\n\n // Require message argument in toThrow/toThrowError — verify correct error\n // https://github.com/vitest-dev/eslint-plugin-vitest/blob/main/docs/rules/require-to-throw-message.md\n \"vitest/require-to-throw-message\": \"error\",\n\n // ── Relaxed rules for tests ───────────────────────────────────\n // Tests are naturally verbose and use patterns banned in prod code\n\n // Tests can be long (setup + many assertions)\n \"max-lines\": \"off\",\n \"max-lines-per-function\": \"off\",\n \"max-statements\": \"off\",\n\n // Tests often need `any` for mocking and type assertions\n \"@typescript-eslint/no-explicit-any\": \"off\",\n \"@typescript-eslint/no-non-null-assertion\": \"off\",\n \"@typescript-eslint/no-unsafe-assignment\": \"off\",\n \"@typescript-eslint/no-unsafe-member-access\": \"off\",\n}\n\nconst TESTING_LIBRARY_RULES: Linter.RulesRecord = {\n // ── Testing Library rules ───────────────────────────────────\n\n // Await async events (userEvent.click, etc.) — prevents race conditions\n // https://github.com/testing-library/eslint-plugin-testing-library/blob/main/docs/rules/await-async-events.md\n \"testing-library/await-async-events\": \"error\",\n\n // Await async queries (findBy*) — they return promises\n // https://github.com/testing-library/eslint-plugin-testing-library/blob/main/docs/rules/await-async-queries.md\n \"testing-library/await-async-queries\": \"error\",\n\n // Await async utilities (waitFor, waitForElementToBeRemoved)\n // https://github.com/testing-library/eslint-plugin-testing-library/blob/main/docs/rules/await-async-utils.md\n \"testing-library/await-async-utils\": \"error\",\n\n // Don't await synchronous events — misleading\n // https://github.com/testing-library/eslint-plugin-testing-library/blob/main/docs/rules/no-await-sync-events.md\n \"testing-library/no-await-sync-events\": \"error\",\n\n // Don't await synchronous queries (getBy*, queryBy*) — not promises\n // https://github.com/testing-library/eslint-plugin-testing-library/blob/main/docs/rules/no-await-sync-queries.md\n \"testing-library/no-await-sync-queries\": \"error\",\n\n // Don't use container.querySelector — use queries instead\n // https://github.com/testing-library/eslint-plugin-testing-library/blob/main/docs/rules/no-container.md\n \"testing-library/no-container\": \"error\",\n\n // Warn on debug()/prettyDOM() left in tests — debugging artifacts\n // https://github.com/testing-library/eslint-plugin-testing-library/blob/main/docs/rules/no-debugging-utils.md\n \"testing-library/no-debugging-utils\": \"warn\",\n\n // Don't access DOM nodes directly — use queries\n // https://github.com/testing-library/eslint-plugin-testing-library/blob/main/docs/rules/no-node-access.md\n \"testing-library/no-node-access\": \"error\",\n\n // Don't call render in beforeEach — call in each test\n // https://github.com/testing-library/eslint-plugin-testing-library/blob/main/docs/rules/no-render-in-lifecycle.md\n \"testing-library/no-render-in-lifecycle\": \"error\",\n\n // No unnecessary act() wrappers — TL handles this internally\n // https://github.com/testing-library/eslint-plugin-testing-library/blob/main/docs/rules/no-unnecessary-act.md\n \"testing-library/no-unnecessary-act\": \"error\",\n\n // One assertion per waitFor — multiple can mask failures\n // https://github.com/testing-library/eslint-plugin-testing-library/blob/main/docs/rules/no-wait-for-multiple-assertions.md\n \"testing-library/no-wait-for-multiple-assertions\": \"error\",\n\n // No side effects in waitFor — only assertions\n // https://github.com/testing-library/eslint-plugin-testing-library/blob/main/docs/rules/no-wait-for-side-effects.md\n \"testing-library/no-wait-for-side-effects\": \"error\",\n\n // Prefer findBy* over waitFor + getBy* — built-in combination\n // https://github.com/testing-library/eslint-plugin-testing-library/blob/main/docs/rules/prefer-find-by.md\n \"testing-library/prefer-find-by\": \"error\",\n\n // Use getBy* (throws) for present elements, queryBy* for absent\n // https://github.com/testing-library/eslint-plugin-testing-library/blob/main/docs/rules/prefer-presence-queries.md\n \"testing-library/prefer-presence-queries\": \"error\",\n\n // Use queryBy* for disappearance checks — returns null when gone\n // https://github.com/testing-library/eslint-plugin-testing-library/blob/main/docs/rules/prefer-query-by-disappearance.md\n \"testing-library/prefer-query-by-disappearance\": \"error\",\n\n // Use screen.getBy* over destructured render result — consistent\n // https://github.com/testing-library/eslint-plugin-testing-library/blob/main/docs/rules/prefer-screen-queries.md\n \"testing-library/prefer-screen-queries\": \"error\",\n\n // Name render result consistently (e.g., `const { getByText } = render(...)`)\n // https://github.com/testing-library/eslint-plugin-testing-library/blob/main/docs/rules/render-result-naming-convention.md\n \"testing-library/render-result-naming-convention\": \"error\",\n}\n\n/**\n * Test file overrides — Vitest rules + Testing Library + relaxed strictness.\n *\n * File patterns: *.test.{ts,tsx}, __tests__/*.{ts,tsx}\n *\n * @see https://github.com/vitest-dev/eslint-plugin-vitest#rules\n * @see https://github.com/testing-library/eslint-plugin-testing-library#supported-rules\n */\nexport function testsOverride(): FlatConfigArray {\n return [\n {\n name: \"eslint-config-setup/tests\",\n files: TEST_FILES,\n plugins: {\n vitest: vitestPlugin,\n },\n rules: VITEST_RULES,\n },\n {\n name: \"eslint-config-setup/tests-testing-library\",\n files: TEST_FILES,\n plugins: {\n \"testing-library\": testingLibraryPlugin,\n },\n rules: TESTING_LIBRARY_RULES,\n },\n ]\n}\n","import oxlintPlugin from \"eslint-plugin-oxlint\"\n\nimport type { ConfigOptions, FlatConfig, FlatConfigArray } from \"../types\"\n\n// eslint-disable-next-line @typescript-eslint/no-unsafe-type-assertion -- Typing the oxlint plugin's config shape\nconst typedPlugin = oxlintPlugin as unknown as {\n configs: Record<string, FlatConfig | FlatConfig[]>\n}\n\nfunction addOxlintConfig(\n configs: FlatConfigArray,\n configName: string,\n blockName: string,\n): void {\n const raw = typedPlugin.configs[configName]\n const items = Array.isArray(raw) ? raw : [raw]\n for (const [index, item] of items.entries()) {\n const suffix = items.length > 1 ? `-${index + 1}` : \"\"\n configs.push({ ...item, name: `eslint-config-setup/${blockName}${suffix}` })\n }\n}\n\nfunction addReactOxlintConfigs(\n configs: FlatConfigArray,\n opts: ConfigOptions,\n): void {\n if (!opts.react) {\n return\n }\n\n addOxlintConfig(configs, \"flat/react\", \"oxlint-react\")\n addOxlintConfig(configs, \"flat/jsx-a11y\", \"oxlint-jsx-a11y\")\n addOxlintConfig(configs, \"flat/react-hooks\", \"oxlint-react-hooks\")\n if (opts.ai) {\n addOxlintConfig(configs, \"flat/react-perf\", \"oxlint-react-perf\")\n }\n}\n\n/**\n * Appends eslint-plugin-oxlint configs that disable all ESLint rules\n * already covered by OxLint. Must be the LAST config in the array.\n *\n * This allows running `oxlint && eslint` where OxLint handles the fast\n * checks and ESLint only runs type-aware and specialty rules.\n */\nexport function oxlintIntegration(opts: ConfigOptions): FlatConfigArray {\n const configs: FlatConfigArray = []\n\n addOxlintConfig(configs, \"flat/recommended\", \"oxlint\")\n addReactOxlintConfigs(configs, opts)\n\n if (opts.node) {\n addOxlintConfig(configs, \"flat/node\", \"oxlint-node\")\n }\n\n // TypeScript and unicorn overlaps\n addOxlintConfig(configs, \"flat/typescript\", \"oxlint-typescript\")\n addOxlintConfig(configs, \"flat/unicorn\", \"oxlint-unicorn\")\n addOxlintConfig(configs, \"flat/import\", \"oxlint-import\")\n addOxlintConfig(configs, \"flat/jsdoc\", \"oxlint-jsdoc\")\n\n return configs\n}\n","import type { FlatConfigArray } from \"../types\"\n\n/**\n * Complexity preset — limits for production code that encourage small,\n * focused functions and aggressive extraction of helper functions.\n * @see https://eslint.org/docs/latest/rules/#suggestions (complexity rules)\n */\nexport function standardComplexity(): FlatConfigArray {\n return [\n {\n name: \"eslint-config-setup/complexity\",\n rules: {\n // Max cyclomatic complexity per function — 10 branches\n // https://eslint.org/docs/latest/rules/complexity\n complexity: [\"error\", 10],\n\n // Max nesting depth — 3 levels\n // https://eslint.org/docs/latest/rules/max-depth\n \"max-depth\": [\"error\", 3],\n\n // Max nested callbacks — 2 levels\n // https://eslint.org/docs/latest/rules/max-nested-callbacks\n \"max-nested-callbacks\": [\"error\", 2],\n\n // Max function parameters — 3 before using options object\n // https://eslint.org/docs/latest/rules/max-params\n \"max-params\": [\"error\", 3],\n\n // Max statements per function — 15\n // https://eslint.org/docs/latest/rules/max-statements\n \"max-statements\": [\"error\", 15],\n\n // Max lines per function — 50 (excluding blanks and comments)\n // https://eslint.org/docs/latest/rules/max-lines-per-function\n \"max-lines-per-function\": [\n \"error\",\n { max: 50, skipBlankLines: true, skipComments: true },\n ],\n\n // Max lines per file — 300 (excluding blanks and comments)\n // https://eslint.org/docs/latest/rules/max-lines\n \"max-lines\": [\n \"error\",\n { max: 300, skipBlankLines: true, skipComments: true },\n ],\n\n // Cognitive complexity — measures how hard code is to understand\n // https://sonarsource.github.io/rspec/#/rspec/S3776/javascript\n \"sonarjs/cognitive-complexity\": [\"error\", 10],\n },\n },\n {\n name: \"eslint-config-setup/complexity-tests-relaxed\",\n files: [\"**/*.test.{ts,tsx}\", \"**/__tests__/**/*.{ts,tsx}\", \"**/*.spec.ts\"],\n rules: {\n \"max-nested-callbacks\": \"off\",\n \"max-lines\": \"off\",\n \"max-lines-per-function\": \"off\",\n \"max-statements\": \"off\",\n },\n },\n ]\n}\n","import type { ConfigOptions, FlatConfigArray } from \"../types\"\n\nimport { aiConfig } from \"../configs/ai\"\nimport { baseConfig } from \"../configs/base\"\nimport { compatConfig } from \"../configs/compat\"\nimport { cspellConfig } from \"../configs/cspell\"\nimport { deMorganConfig } from \"../configs/de-morgan\"\nimport { importsConfig } from \"../configs/imports\"\nimport { jsdocConfig } from \"../configs/jsdoc\"\nimport { jsonConfig } from \"../configs/json\"\nimport { markdownConfig } from \"../configs/markdown\"\nimport { nodeConfig } from \"../configs/node\"\nimport { packageJsonAiConfig, packageJsonConfig } from \"../configs/package-json\"\nimport { perfectionistAiConfig, perfectionistConfig } from \"../configs/perfectionist\"\nimport { prettierCompatConfig } from \"../configs/prettier\"\nimport { reactConfig } from \"../configs/react\"\nimport { reactEffectConfig } from \"../configs/react-effect\"\nimport { regexpConfig } from \"../configs/regexp\"\nimport { securityConfig } from \"../configs/security\"\nimport { sonarjsConfig } from \"../configs/sonarjs\"\nimport { typescriptConfig } from \"../configs/typescript\"\nimport { unicornConfig } from \"../configs/unicorn\"\nimport { configFilesOverride } from \"../overrides/config-files\"\nimport { declarationsOverride } from \"../overrides/declarations\"\nimport { e2eOverride } from \"../overrides/e2e\"\nimport { scriptsOverride } from \"../overrides/scripts\"\nimport { storiesOverride } from \"../overrides/stories\"\nimport { testsOverride } from \"../overrides/tests\"\nimport { oxlintIntegration } from \"../oxlint/integration\"\nimport { standardComplexity } from \"../presets/standard\"\n\n/**\n * Composes a full flat config array from the given options.\n * This is the core logic used by the build system to generate configs.\n */\nfunction addCoreConfigs(config: FlatConfigArray, opts: ConfigOptions): void {\n const ai = opts.ai\n\n config.push(\n ...baseConfig({ ai }),\n ...typescriptConfig({ ai, react: opts.react }),\n ...importsConfig(),\n ...perfectionistConfig(),\n ...unicornConfig({ ai }),\n ...regexpConfig({ ai }),\n ...jsdocConfig({ ai }),\n ...cspellConfig(),\n ...sonarjsConfig({ ai }),\n ...securityConfig(),\n ...deMorganConfig(),\n )\n}\n\nfunction addConditionalConfigs(config: FlatConfigArray, opts: ConfigOptions): void {\n if (!opts.node) {\n config.push(...compatConfig())\n }\n\n if (!opts.ai) {\n config.push(...standardComplexity())\n }\n\n if (opts.node) {\n config.push(...nodeConfig({ ai: opts.ai }))\n }\n\n if (opts.react) {\n config.push(...reactConfig({ ai: opts.ai }))\n config.push(...reactEffectConfig())\n }\n\n if (opts.ai) {\n config.push(...aiConfig())\n config.push(...perfectionistAiConfig())\n config.push(...packageJsonAiConfig())\n }\n}\n\nfunction addFileTypeOverrides(config: FlatConfigArray): void {\n config.push(\n ...testsOverride(),\n ...e2eOverride(),\n ...storiesOverride(),\n ...configFilesOverride(),\n ...declarationsOverride(),\n ...scriptsOverride(),\n )\n}\n\nfunction addFinalConfigs(config: FlatConfigArray, opts: ConfigOptions): void {\n config.push(...jsonConfig(), ...packageJsonConfig(), ...markdownConfig(), ...prettierCompatConfig())\n\n if (opts.oxlint) {\n config.push(...oxlintIntegration(opts))\n }\n}\n\nexport function composeConfig(opts: ConfigOptions): FlatConfigArray {\n const config: FlatConfigArray = []\n\n addCoreConfigs(config, opts)\n addConditionalConfigs(config, opts)\n addFileTypeOverrides(config)\n addFinalConfigs(config, opts)\n\n return config\n}\n"],"mappings":"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","names":["presetRules","eslintReactPlugin","globals","presetRules","eslintReactPlugin","addRules","globals","plugin","TEST_FILES"]}
1
+ {"version":3,"file":"modules.js","names":["TEST_FILES","addRules","plugin","packageJsonConfigs","regexpConfigs"],"sources":["../src/configs/ai.ts","../src/build/config-builder.ts","../src/configs/base.ts","../src/configs/compat.ts","../src/configs/cspell.ts","../src/configs/de-morgan.ts","../src/configs/imports.ts","../src/configs/jsdoc.ts","../src/configs/json.ts","../src/configs/markdown.ts","../src/configs/node.ts","../src/configs/package-json.ts","../src/configs/perfectionist.ts","../src/configs/prettier.ts","../src/file-patterns.ts","../src/plugins/react-compat.ts","../src/configs/react.ts","../src/configs/react-effect.ts","../src/configs/regexp.ts","../src/configs/security.ts","../src/configs/sonarjs.ts","../src/configs/typescript.ts","../src/configs/unicorn.ts","../src/overrides/config-files.ts","../src/overrides/declarations.ts","../src/overrides/e2e.ts","../src/overrides/scripts.ts","../src/overrides/stories.ts","../src/overrides/tests.ts","../src/oxlint/integration.ts","../src/presets/standard.ts","../src/build/compose.ts"],"sourcesContent":["import type { FlatConfigArray } from \"../types\"\n\n/**\n * AI mode — cross-cutting concerns that span multiple domains.\n *\n * Domain-specific AI rules live in their respective configs (base.ts,\n * typescript.ts, react.ts, unicorn.ts, sonarjs.ts, regexp.ts, jsdoc.ts,\n * node.ts) behind an `ai` flag. This file only contains:\n *\n * 1. Test framework rules (vitest) — no dedicated domain config\n * 2. File-scoped relaxations — cross-domain, must come last to override\n *\n * @see ADR-0006: docs/adr/0006-ai-mode-as-dedicated-flag.md\n */\nconst TEST_FILES = [\"**/*.test.{ts,tsx}\", \"**/__tests__/**/*.{ts,tsx}\"]\nconst E2E_FILES = [\"**/*.spec.ts\"]\nconst CONFIG_FILES = [\n \"**/*.config.{ts,mts,cts,js,mjs,cjs}\",\n \"**/vite.config.*\",\n \"**/vitest.config.*\",\n \"**/next.config.*\",\n]\n\nconst AI_TESTS_STRICT_CONFIG: FlatConfigArray[number] = {\n name: \"eslint-config-setup/ai-tests-strict\",\n files: TEST_FILES,\n rules: {\n // Every test must be inside a describe block — organized test suites\n \"vitest/require-top-level-describe\": \"error\",\n\n // Hooks (beforeEach, afterEach) must be at the top of describe — predictable setup\n \"vitest/prefer-hooks-on-top\": \"error\",\n },\n}\n\nconst AI_TESTS_RELAXED_CONFIG: FlatConfigArray[number] = {\n name: \"eslint-config-setup/ai-tests-relaxed\",\n files: TEST_FILES,\n rules: {\n \"max-lines\": \"off\",\n \"max-lines-per-function\": \"off\",\n \"max-statements\": \"off\",\n \"max-nested-callbacks\": \"off\",\n \"@typescript-eslint/no-magic-numbers\": \"off\",\n \"sonarjs/no-duplicate-string\": \"off\",\n \"@typescript-eslint/explicit-function-return-type\": \"off\",\n \"@typescript-eslint/naming-convention\": \"off\",\n \"unicorn/prevent-abbreviations\": \"off\",\n },\n}\n\nconst AI_E2E_RELAXED_CONFIG: FlatConfigArray[number] = {\n name: \"eslint-config-setup/ai-e2e-relaxed\",\n files: E2E_FILES,\n rules: {\n \"max-lines\": \"off\",\n \"max-lines-per-function\": \"off\",\n \"max-statements\": \"off\",\n \"@typescript-eslint/no-magic-numbers\": \"off\",\n \"@typescript-eslint/explicit-function-return-type\": \"off\",\n },\n}\n\nconst AI_CONFIG_RELAXED_CONFIG: FlatConfigArray[number] = {\n name: \"eslint-config-setup/ai-config-relaxed\",\n files: CONFIG_FILES,\n rules: {\n complexity: \"off\",\n \"max-lines\": \"off\",\n \"max-lines-per-function\": \"off\",\n \"max-statements\": \"off\",\n \"@typescript-eslint/no-magic-numbers\": \"off\",\n \"@typescript-eslint/explicit-function-return-type\": \"off\",\n \"@typescript-eslint/naming-convention\": \"off\",\n },\n}\n\nconst AI_DECLARATIONS_RELAXED_CONFIG: FlatConfigArray[number] = {\n name: \"eslint-config-setup/ai-declarations-relaxed\",\n files: [\"**/*.d.ts\"],\n rules: {\n \"@typescript-eslint/explicit-function-return-type\": \"off\",\n \"@typescript-eslint/naming-convention\": \"off\",\n \"@typescript-eslint/no-explicit-any\": \"off\",\n \"@typescript-eslint/no-magic-numbers\": \"off\",\n \"unicorn/prevent-abbreviations\": \"off\",\n \"unicorn/filename-case\": \"off\",\n },\n}\n\nexport function aiConfig(): FlatConfigArray {\n return [\n AI_TESTS_STRICT_CONFIG,\n AI_TESTS_RELAXED_CONFIG,\n AI_E2E_RELAXED_CONFIG,\n AI_CONFIG_RELAXED_CONFIG,\n AI_DECLARATIONS_RELAXED_CONFIG,\n ]\n}\n","/* eslint-disable max-lines-per-function, max-statements, max-depth, complexity, sonarjs/cognitive-complexity -- Config builder: merges presets, rules, and overrides in a single pass. Inherent complexity from ESLint's config format. */\nimport type { Linter } from \"eslint\"\n\nimport type { FlatConfig, FlatConfigArray } from \"../types\"\n\ntype RuleValue = Linter.RuleEntry\n\ntype ConfigBuilderOptions = {\n name: string\n presets?: FlatConfig[]\n passthrough?: FlatConfigArray\n plugins?: NonNullable<FlatConfig[\"plugins\"]>\n languageOptions?: NonNullable<FlatConfig[\"languageOptions\"]>\n settings?: NonNullable<FlatConfig[\"settings\"]>\n files?: NonNullable<FlatConfig[\"files\"]>\n ignores?: NonNullable<FlatConfig[\"ignores\"]>\n}\n\ntype Severity = \"error\" | \"off\" | \"warn\"\n\ntype ConfigBuilder = {\n /** Override an existing preset rule. THROWS if rule not in preset. */\n overrideRule: (name: string, value: RuleValue) => ConfigBuilder\n /** Change only the severity of an existing preset rule, keeping its options. THROWS if not in preset. */\n overrideSeverity: (name: string, severity: Severity) => ConfigBuilder\n /** Change only the options of an existing preset rule, keeping its severity. THROWS if not in preset. */\n overrideOptions: (name: string, ...options: unknown[]) => ConfigBuilder\n /** Add a new rule. THROWS if rule already exists in preset or was already added. */\n addRule: (name: string, value: RuleValue) => ConfigBuilder\n /** Disable an existing preset rule (set to \"off\"). THROWS if not found. */\n disableRule: (name: string) => ConfigBuilder\n /** Remove a rule entirely from output. THROWS if not found. */\n removeRule: (name: string) => ConfigBuilder\n /** Add an extra output block with specific files and rules (not validated against preset). */\n addFileOverride: (\n name: string,\n files: string[],\n rules: Partial<Linter.RulesRecord>,\n ) => ConfigBuilder\n /** Materialize into FlatConfigArray. */\n build: () => FlatConfigArray\n}\n\nexport function createConfig(options: ConfigBuilderOptions): ConfigBuilder {\n // Expand presets: merge all rules from preset objects into one map\n const presetRules = new Map<string, RuleValue>()\n const presetPlugins: NonNullable<FlatConfig[\"plugins\"]> = {}\n\n if (options.presets) {\n for (const preset of options.presets) {\n if (preset.plugins) {\n Object.assign(presetPlugins, preset.plugins)\n }\n if (preset.rules) {\n for (const [name, value] of Object.entries(preset.rules)) {\n if (value !== undefined) {\n presetRules.set(name, value)\n }\n }\n }\n }\n }\n\n // Mutable builder state\n const overrides = new Map<string, RuleValue>()\n const additions = new Map<string, RuleValue>()\n const disabled = new Set<string>()\n const removed = new Set<string>()\n const fileOverrides: Array<{\n name: string\n files: string[]\n rules: Partial<Linter.RulesRecord>\n }> = []\n\n const builder: ConfigBuilder = {\n overrideRule(name: string, value: RuleValue): ConfigBuilder {\n if (!presetRules.has(name)) {\n throw new Error(\n `overrideRule(\"${name}\"): rule not found in preset. ` +\n `Cannot override a rule that doesn't exist in the preset.`,\n )\n }\n overrides.set(name, value)\n return builder\n },\n\n overrideSeverity(name: string, severity: Severity): ConfigBuilder {\n if (!presetRules.has(name)) {\n throw new Error(\n `overrideSeverity(\"${name}\"): rule not found in preset. ` +\n `Cannot override severity of a rule that doesn't exist in the preset.`,\n )\n }\n const existing = presetRules.get(name)\n if (Array.isArray(existing)) {\n const [, ...restOptions] = existing\n // eslint-disable-next-line @typescript-eslint/no-unsafe-assignment -- Spreading rule options from preset\n overrides.set(name, [severity, ...restOptions])\n } else {\n overrides.set(name, severity)\n }\n return builder\n },\n\n overrideOptions(name: string, ...ruleOptions: unknown[]): ConfigBuilder {\n if (!presetRules.has(name)) {\n throw new Error(\n `overrideOptions(\"${name}\"): rule not found in preset. ` +\n `Cannot override options of a rule that doesn't exist in the preset.`,\n )\n }\n const existing = presetRules.get(name)\n const severity = Array.isArray(existing) ? existing[0] : existing\n // eslint-disable-next-line @typescript-eslint/no-unsafe-type-assertion -- Severity extracted from preset rule entry\n overrides.set(name, [severity as Severity, ...ruleOptions])\n return builder\n },\n\n addRule(name: string, value: RuleValue): ConfigBuilder {\n if (presetRules.has(name)) {\n throw new Error(\n `addRule(\"${name}\"): rule already exists in preset. ` +\n `Use overrideRule() to change its value, or removeRule() to drop it.`,\n )\n }\n if (additions.has(name)) {\n throw new Error(\n `addRule(\"${name}\"): rule was already added. ` +\n `Each rule can only be added once.`,\n )\n }\n additions.set(name, value)\n return builder\n },\n\n disableRule(name: string): ConfigBuilder {\n if (!presetRules.has(name) && !additions.has(name)) {\n throw new Error(\n `disableRule(\"${name}\"): rule not found in preset or additions. ` +\n `Cannot disable a rule that doesn't exist.`,\n )\n }\n disabled.add(name)\n return builder\n },\n\n removeRule(name: string): ConfigBuilder {\n if (!presetRules.has(name) && !additions.has(name)) {\n throw new Error(\n `removeRule(\"${name}\"): rule not found in preset or additions. ` +\n `Cannot remove a rule that doesn't exist.`,\n )\n }\n removed.add(name)\n return builder\n },\n\n addFileOverride(\n name: string,\n files: string[],\n rules: Partial<Linter.RulesRecord>,\n ): ConfigBuilder {\n fileOverrides.push({ name, files, rules })\n return builder\n },\n\n build(): FlatConfigArray {\n // Start with all preset rules\n const rules: Linter.RulesRecord = {}\n for (const [name, value] of presetRules) {\n if (!removed.has(name)) {\n rules[name] = value\n }\n }\n\n // Apply overrides\n for (const [name, value] of overrides) {\n if (!removed.has(name)) {\n rules[name] = value\n }\n }\n\n // Apply additions\n for (const [name, value] of additions) {\n if (!removed.has(name)) {\n rules[name] = value\n }\n }\n\n // Apply disabled\n for (const name of disabled) {\n if (!removed.has(name)) {\n rules[name] = \"off\"\n }\n }\n\n // Build the main config block\n const mainBlock: FlatConfig = {\n name: options.name,\n rules,\n }\n\n // Merge plugins from preset + user\n const mergedPlugins = { ...presetPlugins, ...options.plugins }\n if (Object.keys(mergedPlugins).length > 0) {\n mainBlock.plugins = mergedPlugins\n }\n\n if (options.languageOptions) {\n mainBlock.languageOptions = options.languageOptions\n }\n if (options.settings) {\n mainBlock.settings = options.settings\n }\n if (options.files) {\n mainBlock.files = options.files\n }\n if (options.ignores) {\n mainBlock.ignores = options.ignores\n }\n\n const result: FlatConfigArray = []\n\n // Passthrough blocks first\n if (options.passthrough) {\n result.push(...options.passthrough)\n }\n\n // Main validated block\n result.push(mainBlock)\n\n // File override blocks\n for (const fo of fileOverrides) {\n result.push({\n name: fo.name,\n files: fo.files,\n rules: fo.rules,\n })\n }\n\n return result\n },\n }\n\n return builder\n}\n","import type { Linter } from \"eslint\"\n\nimport eslint from \"@eslint/js\"\n\nimport type { FlatConfigArray } from \"../types\"\n\nimport { createConfig } from \"../build/config-builder\"\n\ntype Builder = ReturnType<typeof createConfig>\n\nconst ERROR_PREVENTION_RULES = {\n \"accessor-pairs\": [\"error\", { enforceForClassMembers: true }],\n \"array-callback-return\": [\"error\", { allowImplicit: true }],\n \"no-constructor-return\": \"error\",\n \"no-promise-executor-return\": \"error\",\n \"no-self-compare\": \"error\",\n \"no-template-curly-in-string\": \"error\",\n \"no-unreachable-loop\": \"error\",\n \"require-atomic-updates\": \"error\",\n \"no-unmodified-loop-condition\": \"error\",\n \"grouped-accessor-pairs\": [\"error\", \"getBeforeSet\"],\n \"no-useless-rename\": \"error\",\n \"no-useless-computed-key\": [\"error\", { enforceForClassMembers: true }],\n} satisfies Linter.RulesRecord\n\nconst DANGEROUS_PATTERN_RULES = {\n \"no-eval\": \"error\",\n \"no-alert\": \"error\",\n \"no-caller\": \"error\",\n \"no-extend-native\": \"error\",\n \"no-new-func\": \"error\",\n \"no-new-wrappers\": \"error\",\n \"no-object-constructor\": \"error\",\n \"no-proto\": \"error\",\n \"no-iterator\": \"error\",\n \"no-script-url\": \"error\",\n \"no-octal-escape\": \"error\",\n \"no-implicit-globals\": \"error\",\n} satisfies Linter.RulesRecord\n\nconst CODE_QUALITY_RULES = {\n eqeqeq: [\"error\", \"smart\"],\n \"guard-for-in\": \"error\",\n \"default-case-last\": \"error\",\n radix: \"error\",\n yoda: \"error\",\n \"no-sequences\": [\"error\", { allowInParentheses: false }],\n \"no-new\": \"error\",\n \"no-labels\": \"error\",\n \"no-extra-bind\": \"error\",\n \"no-lone-blocks\": \"error\",\n \"no-useless-call\": \"error\",\n \"no-useless-concat\": \"error\",\n \"no-useless-return\": \"error\",\n \"no-return-assign\": [\"error\", \"always\"],\n \"no-multi-str\": \"error\",\n \"prefer-regex-literals\": [\"error\", { disallowRedundantWrapping: true }],\n} satisfies Linter.RulesRecord\n\nconst MODERN_STYLE_RULES = {\n \"no-var\": \"error\",\n \"prefer-const\": [\"error\", { destructuring: \"all\" }],\n \"prefer-object-has-own\": \"error\",\n \"prefer-object-spread\": \"error\",\n \"prefer-rest-params\": \"error\",\n \"prefer-spread\": \"error\",\n \"symbol-description\": \"error\",\n \"prefer-numeric-literals\": \"error\",\n \"object-shorthand\": [\"error\", \"always\", { avoidExplicitReturnArrows: true, avoidQuotes: true }],\n} satisfies Linter.RulesRecord\n\nconst AI_STRUCTURAL_RULES = {\n curly: [\"error\", \"all\"],\n \"no-else-return\": [\"error\", { allowElseIf: false }],\n \"no-nested-ternary\": \"error\",\n \"no-unneeded-ternary\": \"error\",\n \"no-negated-condition\": \"error\",\n \"no-lonely-if\": \"error\",\n \"no-param-reassign\": [\"error\", { props: true }],\n \"no-multi-assign\": \"error\",\n \"one-var\": [\"error\", \"never\"],\n \"no-implicit-coercion\": \"error\",\n \"arrow-body-style\": \"error\",\n \"prefer-arrow-callback\": [\"error\", { allowNamedFunctions: true }],\n \"logical-assignment-operators\": [\"error\", \"always\", { enforceForIfStatements: true }],\n \"max-statements-per-line\": [\"error\", { max: 1 }],\n \"prefer-exponentiation-operator\": \"error\",\n \"prefer-named-capture-group\": \"error\",\n \"require-unicode-regexp\": \"error\",\n \"no-warning-comments\": \"warn\",\n \"no-await-in-loop\": \"error\",\n} satisfies Linter.RulesRecord\n\nfunction addRules(builder: Builder, rules: Linter.RulesRecord): void {\n for (const [ruleName, value] of Object.entries(rules)) {\n builder.addRule(ruleName, value)\n }\n}\n\nfunction addBaseOverrides(builder: Builder): void {\n builder.overrideRule(\"use-isnan\", [\"error\", { enforceForIndexOf: true, enforceForSwitchCase: true }])\n builder.overrideRule(\"valid-typeof\", [\"error\", { requireStringLiterals: true }])\n}\n\nfunction addComplexityRules(builder: Builder, isAi: boolean): void {\n builder.addRule(\"complexity\", [\"error\", isAi ? 10 : 20])\n builder.addRule(\"max-depth\", [\"error\", isAi ? 3 : 5])\n builder.addRule(\"max-nested-callbacks\", [\"error\", isAi ? 2 : 4])\n builder.addRule(\"max-params\", [\"error\", isAi ? 3 : 5])\n builder.addRule(\"max-statements\", [\"error\", isAi ? 15 : 25])\n builder.addRule(\"max-lines-per-function\", [\n \"error\",\n { max: isAi ? 100 : 200, skipBlankLines: true, skipComments: true },\n ])\n builder.addRule(\"max-lines\", [\n \"error\",\n { max: isAi ? 300 : 500, skipBlankLines: true, skipComments: true },\n ])\n builder.addRule(\"sonarjs/cognitive-complexity\", [\"error\", isAi ? 10 : 20])\n}\n\nfunction addModernStyleRules(builder: Builder, isAi: boolean): void {\n addRules(builder, MODERN_STYLE_RULES)\n builder.addRule(\"prefer-template\", isAi ? \"error\" : \"warn\")\n}\n\n/**\n * Base ESLint config — extends `eslint.configs.recommended` with additional\n * best-practice rules for error prevention and modern JS style.\n *\n * Rules with TypeScript equivalents (no-implied-eval, dot-notation, etc.)\n * are NOT included here — they are handled by the typescript-eslint presets.\n *\n * Preset: `@eslint/js` recommended\n * @see https://eslint.org/docs/latest/rules/\n */\nexport function baseConfig(opts?: { ai?: boolean }): FlatConfigArray {\n const isAi = opts?.ai ?? false\n\n const builder = createConfig({\n name: \"eslint-config-setup/base\",\n presets: [eslint.configs.recommended],\n })\n\n addRules(builder, ERROR_PREVENTION_RULES)\n addBaseOverrides(builder)\n addRules(builder, DANGEROUS_PATTERN_RULES)\n addRules(builder, CODE_QUALITY_RULES)\n addComplexityRules(builder, isAi)\n addModernStyleRules(builder, isAi)\n\n if (isAi) {\n addRules(builder, AI_STRUCTURAL_RULES)\n }\n\n return builder.build()\n}\n","import compatPlugin from \"eslint-plugin-compat\"\n\nimport type { FlatConfigArray } from \"../types\"\n\n/**\n * Browser compatibility config — checks that browser APIs are available\n * in the project's browserslist targets. Uses MDN compatibility data.\n *\n * Activated automatically for non-Node projects (when `node: false`).\n * If no browserslist config exists, the default applies:\n * `> 0.5%, last 2 versions, Firefox ESR, not dead`\n *\n * @see https://github.com/amilajack/eslint-plugin-compat\n * @see https://browsersl.ist/\n */\nexport function compatConfig(): FlatConfigArray {\n return [\n {\n name: \"eslint-config-setup/compat\",\n plugins: {\n compat: compatPlugin,\n },\n rules: {\n // Warn when using browser APIs not supported in browserslist targets\n // https://github.com/amilajack/eslint-plugin-compat#usage\n \"compat/compat\": \"warn\",\n },\n },\n ]\n}\n","import cspellPlugin from \"@cspell/eslint-plugin\"\n\nimport type { FlatConfigArray } from \"../types\"\n\n/**\n * CSpell config — spell checking for identifiers and comments.\n * Catches typos in variable names, function names, and documentation.\n * Severity is \"warn\" because dictionary misses are common for domain terms.\n *\n * @see https://github.com/streetsidesoftware/cspell/tree/main/packages/cspell-eslint-plugin#readme\n */\nexport function cspellConfig(): FlatConfigArray {\n return [\n {\n name: \"eslint-config-setup/cspell\",\n plugins: {\n \"@cspell\": cspellPlugin,\n },\n rules: {\n // Check spelling in identifiers and comments — catches typos in API names\n // Strings are excluded (may contain user-facing text, URLs, etc.)\n // Auto-fix disabled — spelling corrections need human review\n // https://github.com/streetsidesoftware/cspell/tree/main/packages/cspell-eslint-plugin#rules\n \"@cspell/spellchecker\": [\n \"warn\",\n {\n checkComments: true,\n checkIdentifiers: true,\n checkStrings: false,\n autoFix: false,\n },\n ],\n },\n },\n ]\n}\n","import deMorganPlugin from \"eslint-plugin-de-morgan\"\n\nimport type { FlatConfigArray } from \"../types\"\n\n/**\n * De Morgan config — enforces De Morgan's laws on negated boolean expressions.\n * Both rules are auto-fixable: !(A && B) → !A || !B and !(A || B) → !A && !B.\n *\n * Complements sonarjs/no-inverted-boolean-check (which handles simple !(a === b) → a !== b)\n * by targeting compound expressions with && and ||.\n *\n * @see https://github.com/azat-io/eslint-plugin-de-morgan\n */\nexport function deMorganConfig(): FlatConfigArray {\n return [\n {\n name: \"eslint-config-setup/de-morgan\",\n plugins: {\n \"de-morgan\": deMorganPlugin,\n },\n rules: {\n // Transform !(A && B) → !A || !B — more readable negated conjunction\n // https://github.com/azat-io/eslint-plugin-de-morgan/blob/main/docs/no-negated-conjunction.md\n \"de-morgan/no-negated-conjunction\": \"error\",\n\n // Transform !(A || B) → !A && !B — more readable negated disjunction\n // https://github.com/azat-io/eslint-plugin-de-morgan/blob/main/docs/no-negated-disjunction.md\n \"de-morgan/no-negated-disjunction\": \"error\",\n },\n },\n ]\n}\n","import importXPlugin from \"eslint-plugin-import-x\"\nimport unusedImportsPlugin from \"eslint-plugin-unused-imports\"\n\nimport type { FlatConfigArray } from \"../types\"\n\n/**\n * Import/export config — two plugins with clear separation of concerns:\n * - `import-x` handles import **validation** (cycles, duplicates, etc.)\n * - `unused-imports` handles **removal** of unused imports (auto-fixable)\n *\n * Import/export **ordering** is handled by perfectionist (see perfectionist.ts).\n *\n * @see https://github.com/un-ts/eslint-plugin-import-x\n * @see https://github.com/sweepline/eslint-plugin-unused-imports\n */\nexport function importsConfig(): FlatConfigArray {\n return [\n {\n name: \"eslint-config-setup/imports\",\n plugins: {\n // eslint-disable-next-line @typescript-eslint/no-unsafe-type-assertion -- Plugin type is compatible\n \"import\": importXPlugin as unknown as Record<string, unknown>,\n \"unused-imports\": unusedImportsPlugin,\n },\n rules: {\n // ── Validation (import-x) ────────────────────────────────────\n\n // Merge duplicate import paths into one statement — reduces noise\n // https://github.com/un-ts/eslint-plugin-import/blob/master/docs/rules/no-duplicates.md\n \"import/no-duplicates\": \"error\",\n\n // Forbid a module from importing itself — always a bug\n // https://github.com/un-ts/eslint-plugin-import/blob/master/docs/rules/no-self-import.md\n \"import/no-self-import\": \"error\",\n\n // Detect circular dependencies — limited to depth 3 for performance\n // https://github.com/un-ts/eslint-plugin-import/blob/master/docs/rules/no-cycle.md\n \"import/no-cycle\": [\"error\", { maxDepth: 3 }],\n\n // Remove unnecessary path segments (e.g., ./foo/../foo → ./foo)\n // https://github.com/un-ts/eslint-plugin-import/blob/master/docs/rules/no-useless-path-segments.md\n \"import/no-useless-path-segments\": \"error\",\n\n // Forbid mutable export bindings — prevents shared mutable state\n // https://github.com/un-ts/eslint-plugin-import/blob/master/docs/rules/no-mutable-exports.md\n \"import/no-mutable-exports\": \"error\",\n\n // Imports must come before other statements — consistent module structure\n // https://github.com/un-ts/eslint-plugin-import/blob/master/docs/rules/first.md\n \"import/first\": \"error\",\n\n // Require blank line after import block — visual separation\n // https://github.com/un-ts/eslint-plugin-import/blob/master/docs/rules/newline-after-import.md\n \"import/newline-after-import\": \"error\",\n\n // Detect `import Foo from './Foo'` when Foo is also a named export — likely wrong\n // https://github.com/un-ts/eslint-plugin-import-x/blob/master/docs/rules/no-named-as-default.md\n \"import/no-named-as-default\": \"error\",\n\n // Detect `Foo.bar` when `bar` is a named export — use `import { bar }` instead\n // https://github.com/un-ts/eslint-plugin-import-x/blob/master/docs/rules/no-named-as-default-member.md\n \"import/no-named-as-default-member\": \"error\",\n\n // Detect empty `import {} from 'foo'` — leftover after refactoring\n // https://github.com/un-ts/eslint-plugin-import-x/blob/master/docs/rules/no-empty-named-blocks.md\n \"import/no-empty-named-blocks\": \"error\",\n\n // Forbid absolute file paths in imports — not portable across machines\n // https://github.com/un-ts/eslint-plugin-import-x/blob/master/docs/rules/no-absolute-path.md\n \"import/no-absolute-path\": \"error\",\n\n // Forbid imports of packages not listed in package.json — catches phantom deps\n // https://github.com/un-ts/eslint-plugin-import-x/blob/master/docs/rules/no-extraneous-dependencies.md\n \"import/no-extraneous-dependencies\": [\"error\", { includeTypes: true }],\n\n // Forbid side-effect-only imports — make dependencies explicit\n // https://github.com/un-ts/eslint-plugin-import-x/blob/master/docs/rules/no-unassigned-import.md\n \"import/no-unassigned-import\": [\n \"error\",\n {\n allow: [\n \"@babel/polyfill\",\n \"**/register\",\n \"**/register.*\",\n \"**/register/**\",\n \"**/register/**.*\",\n \"**/*.css\",\n \"**/*.scss\",\n \"**/*.sass\",\n \"**/*.less\",\n ],\n },\n ],\n\n // Forbid `import { default as Foo }` — use `import Foo` instead\n // https://github.com/un-ts/eslint-plugin-import-x/blob/master/docs/rules/no-named-default.md\n \"import/no-named-default\": \"error\",\n\n // ── Disabled: ordering handled by perfectionist ────────────────\n\n // https://github.com/un-ts/eslint-plugin-import/blob/master/docs/rules/order.md\n \"import/order\": \"off\",\n // https://github.com/un-ts/eslint-plugin-import/blob/master/docs/rules/sort-imports.md\n \"import/sort-imports\": \"off\",\n\n // ── Unused import removal ─────────────────────────────────────\n\n // Auto-remove unused imports — keeps imports clean (auto-fixable)\n // https://github.com/sweepline/eslint-plugin-unused-imports#usage\n \"unused-imports/no-unused-imports\": \"error\",\n },\n },\n ]\n}\n","import jsdocPlugin from \"eslint-plugin-jsdoc\"\n\nimport type { FlatConfigArray } from \"../types\"\n\nimport { createConfig } from \"../build/config-builder\"\n\n/**\n * JSDoc config — validates existing JSDoc annotations without requiring them.\n *\n * Preset: `flat/recommended-typescript-error` — all recommended JSDoc rules\n * adapted for TypeScript (types are in TS, not JSDoc).\n *\n * Overrides:\n * - `require-jsdoc` OFF — we validate existing JSDoc, we don't mandate it\n * - param/return descriptions downgraded to warn — helpful but not blocking\n * @see https://github.com/gajus/eslint-plugin-jsdoc#rules\n */\nexport function jsdocConfig(opts?: { ai?: boolean }): FlatConfigArray {\n const isAi = opts?.ai ?? false\n\n const builder = createConfig({\n name: \"eslint-config-setup/jsdoc\",\n presets: [jsdocPlugin.configs[\"flat/recommended-typescript-error\"]],\n })\n // OFF: Don't require JSDoc on everything — only validate what exists\n // https://github.com/gajus/eslint-plugin-jsdoc/blob/main/docs/rules/require-jsdoc.md\n .overrideRule(\"jsdoc/require-jsdoc\", \"off\")\n\n // OFF: Too strict for normal usage — requiring @param/@returns on every\n // documented function adds noise. Enabled in AI mode where completeness matters.\n .overrideRule(\"jsdoc/require-param\", \"off\")\n .overrideRule(\"jsdoc/require-returns\", \"off\")\n .overrideRule(\"jsdoc/require-yields\", \"off\")\n\n // Warn if @param descriptions are missing — helpful but not blocking\n // https://github.com/gajus/eslint-plugin-jsdoc/blob/main/docs/rules/require-param-description.md\n .overrideRule(\"jsdoc/require-param-description\", \"warn\")\n\n // Warn if @returns description is missing — helpful but not blocking\n // https://github.com/gajus/eslint-plugin-jsdoc/blob/main/docs/rules/require-returns-description.md\n .overrideRule(\"jsdoc/require-returns-description\", \"warn\")\n\n // Override preset's typed option — use plain error without options\n // https://github.com/gajus/eslint-plugin-jsdoc/blob/main/docs/rules/check-tag-names.md\n .overrideRule(\"jsdoc/check-tag-names\", \"error\")\n\n // Enable detection of references to undefined types in JSDoc (off in preset)\n // https://github.com/gajus/eslint-plugin-jsdoc/blob/main/docs/rules/no-undefined-types.md\n .overrideRule(\"jsdoc/no-undefined-types\", \"error\")\n\n // OFF: Allow blank lines between description and tags — keeps JSDoc readable\n // The preset enforces no blank lines before tags, but visual separation helps.\n .overrideRule(\"jsdoc/tag-lines\", \"off\")\n\n if (isAi) {\n builder.overrideRule(\"jsdoc/require-param\", \"error\")\n builder.overrideRule(\"jsdoc/require-returns\", \"error\")\n builder.overrideRule(\"jsdoc/informative-docs\", \"error\")\n }\n\n return builder.build()\n}\n","import type { ESLint } from \"eslint\"\n\nimport jsonPlugin from \"@eslint/json\"\n\nimport type { FlatConfigArray } from \"../types\"\n\n// eslint-disable-next-line @typescript-eslint/no-unsafe-type-assertion -- Typing the JSON plugin\nconst plugin = jsonPlugin as unknown as ESLint.Plugin\n\n/**\n * JSON/JSONC config — native JSON linting using the official `@eslint/json` plugin.\n * Two blocks: strict JSON for most files, JSONC (with comments) for tsconfig etc.\n *\n * @see https://github.com/eslint/json#rules\n */\nexport function jsonConfig(): FlatConfigArray {\n return [\n {\n name: \"eslint-config-setup/json\",\n files: [\"**/*.json\"],\n ignores: [\"**/package-lock.json\"],\n language: \"json/json\",\n plugins: {\n json: plugin,\n },\n rules: {\n // Detect duplicate keys in JSON — last-write-wins is confusing\n // https://github.com/eslint/json#rules\n \"json/no-duplicate-keys\": \"error\",\n\n // Detect empty string keys — likely a mistake\n // https://github.com/eslint/json#rules\n \"json/no-empty-keys\": \"error\",\n\n // Detect unsafe values (NaN, Infinity, lone surrogates) — invalid JSON\n // https://github.com/eslint/json#rules\n \"json/no-unsafe-values\": \"error\",\n\n // Detect unnormalized Unicode keys — prevents invisible key mismatches\n // https://github.com/eslint/json#rules\n \"json/no-unnormalized-keys\": \"error\",\n },\n },\n {\n name: \"eslint-config-setup/jsonc\",\n files: [\n \"**/tsconfig.json\",\n \"**/tsconfig.*.json\",\n \"**/.vscode/*.json\",\n \"**/turbo.json\",\n ],\n language: \"json/jsonc\",\n plugins: {\n json: plugin,\n },\n rules: {\n // Detect duplicate keys in JSONC — same rationale as JSON\n // https://github.com/eslint/json#rules\n \"json/no-duplicate-keys\": \"error\",\n\n // Detect empty string keys — likely a mistake\n // https://github.com/eslint/json#rules\n \"json/no-empty-keys\": \"error\",\n\n // Detect unsafe values (NaN, Infinity, lone surrogates) — invalid JSON\n // https://github.com/eslint/json#rules\n \"json/no-unsafe-values\": \"error\",\n\n // Detect unnormalized Unicode keys — prevents invisible key mismatches\n // https://github.com/eslint/json#rules\n \"json/no-unnormalized-keys\": \"error\",\n },\n },\n ]\n}\n","import * as mdxPlugin from \"eslint-plugin-mdx\"\n\nimport type { FlatConfigArray } from \"../types\"\n\n/**\n * Markdown & MDX config — lints code blocks inside Markdown and MDX files\n * using eslint-plugin-mdx. Code examples in docs get the same ESLint rules\n * as your source code. Covers both `.md` and `.mdx` files.\n *\n * Markdown structure linting (headings, links, etc.) is intentionally left\n * to dedicated tools like markdownlint.\n *\n * @see https://github.com/mdx-js/eslint-mdx\n * @see https://github.com/DavidAnson/markdownlint-cli2 (recommended for Markdown structure linting)\n */\nexport function markdownConfig(): FlatConfigArray {\n const codeBlockLanguageOptions =\n mdxPlugin.flatCodeBlocks.languageOptions ?? {}\n const codeBlockParserOptions =\n codeBlockLanguageOptions.parserOptions ?? {}\n\n return [\n // ── MDX / Markdown parsing ─────────────────────────────────────\n {\n ...mdxPlugin.flat,\n processor: mdxPlugin.createRemarkProcessor({\n lintCodeBlocks: true,\n languageMapper: {},\n }),\n },\n\n // ── Code block linting ─────────────────────────────────────────\n // Applies ESLint rules to fenced code blocks extracted from .md/.mdx.\n // Relaxes rules that don't apply to incomplete code snippets.\n {\n ...mdxPlugin.flatCodeBlocks,\n languageOptions: {\n ...codeBlockLanguageOptions,\n parserOptions: {\n ...codeBlockParserOptions,\n projectService: false,\n },\n },\n rules: {\n ...mdxPlugin.flatCodeBlocks.rules,\n // Snippets don't need trailing newlines\n \"eol-last\": \"off\",\n // Variables may be defined elsewhere\n \"no-undef\": \"off\",\n // Snippets often show standalone expressions\n \"no-unused-expressions\": \"off\",\n // Variables are often declared for demonstration\n \"no-unused-vars\": \"off\",\n // Padding is irrelevant in snippets\n \"padded-blocks\": \"off\",\n // Strict mode is irrelevant in snippets\n strict: \"off\",\n // BOM is irrelevant in snippets\n \"unicode-bom\": \"off\",\n },\n },\n ]\n}\n","import nodePlugin from \"eslint-plugin-n\"\nimport globals from \"globals\"\n\nimport type { FlatConfigArray } from \"../types\"\n\nimport { createConfig } from \"../build/config-builder\"\n\n/**\n * Node.js config — rules for server-side JavaScript/TypeScript.\n * Hand-picked subset of eslint-plugin-n. We don't use the full preset because\n * module resolution rules (`no-missing-import`, `no-unpublished-import`) are\n * handled better by TypeScript.\n *\n * @see https://github.com/eslint-community/eslint-plugin-n#-rules\n */\nexport function nodeConfig(opts?: { ai?: boolean }): FlatConfigArray {\n const isAi = opts?.ai ?? false\n\n const builder = createConfig({\n name: \"eslint-config-setup/node\",\n presets: [\n {\n rules: {\n // Detect usage of deprecated Node.js APIs (fs.exists, url.parse, etc.)\n // https://github.com/eslint-community/eslint-plugin-n/blob/master/docs/rules/no-deprecated-api.md\n \"node/no-deprecated-api\": \"error\",\n\n // Prevent `module.exports = ...` assignment in ES modules\n // https://github.com/eslint-community/eslint-plugin-n/blob/master/docs/rules/no-exports-assign.md\n \"node/no-exports-assign\": \"error\",\n\n // OFF: TypeScript resolves imports — this rule has false positives\n // https://github.com/eslint-community/eslint-plugin-n/blob/master/docs/rules/no-missing-import.md\n \"node/no-missing-import\": \"off\",\n\n // OFF: TypeScript resolves requires — this rule has false positives\n // https://github.com/eslint-community/eslint-plugin-n/blob/master/docs/rules/no-missing-require.md\n \"node/no-missing-require\": \"off\",\n\n // Warn on process.exit() — prefer throwing errors for clean shutdown\n // https://github.com/eslint-community/eslint-plugin-n/blob/master/docs/rules/no-process-exit.md\n \"node/no-process-exit\": \"warn\",\n\n // OFF: Too many false positives with monorepos and devDependencies\n // https://github.com/eslint-community/eslint-plugin-n/blob/master/docs/rules/no-unpublished-import.md\n \"node/no-unpublished-import\": \"off\",\n\n // Validate hashbang lines — correct syntax, Unix linebreaks, only in entry files\n // https://github.com/eslint-community/eslint-plugin-n/blob/master/docs/rules/hashbang.md\n \"node/hashbang\": \"error\",\n\n // Detect `__dirname + '/foo'` — use path.join() instead (breaks on Windows)\n // https://github.com/eslint-community/eslint-plugin-n/blob/master/docs/rules/no-path-concat.md\n \"node/no-path-concat\": \"error\",\n\n // Treat process.exit() as throw — prevents false positives in unreachable code analysis\n // https://github.com/eslint-community/eslint-plugin-n/blob/master/docs/rules/process-exit-as-throw.md\n \"node/process-exit-as-throw\": \"error\",\n\n // Ensure error parameters in callbacks are handled — don't silently swallow errors\n // https://github.com/eslint-community/eslint-plugin-n/blob/master/docs/rules/handle-callback-err.md\n \"node/handle-callback-err\": \"error\",\n\n // ── Prefer global builtins ────────────────────────────────────\n\n // Use global Buffer instead of require('buffer').Buffer\n // https://github.com/eslint-community/eslint-plugin-n/blob/master/docs/rules/prefer-global/buffer.md\n \"node/prefer-global/buffer\": [\"error\", \"always\"],\n\n // Use global console — always available in Node.js\n // https://github.com/eslint-community/eslint-plugin-n/blob/master/docs/rules/prefer-global/console.md\n \"node/prefer-global/console\": [\"error\", \"always\"],\n\n // Use global process — always available in Node.js\n // https://github.com/eslint-community/eslint-plugin-n/blob/master/docs/rules/prefer-global/process.md\n \"node/prefer-global/process\": [\"error\", \"always\"],\n\n // Use global URL — available since Node.js 10\n // https://github.com/eslint-community/eslint-plugin-n/blob/master/docs/rules/prefer-global/url.md\n \"node/prefer-global/url\": [\"error\", \"always\"],\n\n // Use global URLSearchParams — available since Node.js 10\n // https://github.com/eslint-community/eslint-plugin-n/blob/master/docs/rules/prefer-global/url-search-params.md\n \"node/prefer-global/url-search-params\": [\"error\", \"always\"],\n\n // ── Prefer promise-based APIs ─────────────────────────────────\n\n // Use dns.promises instead of callback-based dns — modern async\n // https://github.com/eslint-community/eslint-plugin-n/blob/master/docs/rules/prefer-promises/dns.md\n \"node/prefer-promises/dns\": \"error\",\n\n // Use fs.promises instead of callback-based fs — modern async\n // https://github.com/eslint-community/eslint-plugin-n/blob/master/docs/rules/prefer-promises/fs.md\n \"node/prefer-promises/fs\": \"error\",\n },\n },\n ],\n plugins: { node: nodePlugin },\n languageOptions: { globals: { ...globals.node } },\n })\n\n if (isAi) {\n builder.addRule(\"node/no-unsupported-features/node-builtins\", \"error\")\n }\n\n return builder.build()\n}\n","import { configs as packageJsonConfigs } from \"eslint-plugin-package-json\"\n\nimport type { FlatConfigArray } from \"../types\"\n\n/**\n * Package.json config — semantic validation of package.json files.\n *\n * Uses the recommended preset from eslint-plugin-package-json which includes:\n * - All valid-* rules (only fire on malformed existing fields, never on missing)\n * - Conservative require-* rules with ignorePrivate: true by default\n * - Quality rules (no-empty-fields, unique-dependencies, etc.)\n *\n * Sorting/ordering rules are off by default — enabled only in AI mode.\n *\n * @see https://github.com/JoshuaKGoldberg/eslint-plugin-package-json\n */\nexport function packageJsonConfig(): FlatConfigArray {\n const recommended = packageJsonConfigs.recommended\n\n return [\n {\n ...recommended,\n name: \"eslint-config-setup/package-json\",\n },\n ]\n}\n\n/**\n * Package.json AI config — enables ordering and sorting rules.\n * Only active in AI mode where deterministic structure is enforced.\n */\nexport function packageJsonAiConfig(): FlatConfigArray {\n return [\n {\n name: \"eslint-config-setup/package-json-ai\",\n files: [\"**/package.json\"],\n rules: {\n // Enforce consistent property ordering in package.json\n // https://github.com/JoshuaKGoldberg/eslint-plugin-package-json\n \"package-json/order-properties\": \"error\",\n\n // Sort dependencies, scripts, exports, etc. alphabetically\n // https://github.com/JoshuaKGoldberg/eslint-plugin-package-json\n \"package-json/sort-collections\": \"error\",\n },\n },\n ]\n}\n","import perfectionistPlugin from \"eslint-plugin-perfectionist\"\n\nimport type { FlatConfigArray } from \"../types\"\n\n/**\n * Perfectionist config — deterministic sorting of code elements.\n *\n * Sorts everything Prettier doesn't: imports, exports, union types,\n * object keys, interface members, etc. Especially valuable for\n * AI-generated code where ordering is arbitrary.\n *\n * Replaces `simple-import-sort` — perfectionist handles everything\n * simple-import-sort does, plus TypeScript path alias recognition\n * and named import sorting.\n *\n * Core philosophy: `partitionByNewLine: true` globally — semantic\n * grouping via blank lines is preserved, within groups natural sort.\n *\n * @see https://perfectionist.dev\n */\n\n/**\n * Mechanical sorting rules — always active.\n * These have no semantic dimension: the order of imports, named exports,\n * or union type members carries no meaning.\n */\nexport function perfectionistConfig(): FlatConfigArray {\n return [\n {\n name: \"eslint-config-setup/perfectionist\",\n plugins: {\n perfectionist: perfectionistPlugin,\n },\n settings: {\n perfectionist: {\n type: \"natural\",\n order: \"asc\",\n partitionByNewLine: true,\n },\n },\n rules: {\n // Auto-sort import statements — deterministic ordering regardless of input\n // Replaces simple-import-sort/imports\n // https://perfectionist.dev/rules/sort-imports\n \"perfectionist/sort-imports\": [\n \"error\",\n {\n partitionByNewLine: false,\n },\n ],\n\n // Sort specifiers inside `import { a, b, c }` — deterministic\n // https://perfectionist.dev/rules/sort-named-imports\n \"perfectionist/sort-named-imports\": \"error\",\n\n // Sort specifiers inside `export { a, b, c }` — deterministic\n // https://perfectionist.dev/rules/sort-named-exports\n \"perfectionist/sort-named-exports\": \"error\",\n\n // Auto-sort export statements — deterministic ordering\n // Replaces simple-import-sort/exports\n // https://perfectionist.dev/rules/sort-exports\n \"perfectionist/sort-exports\": \"error\",\n\n // Sort union type members — `number | string` has no semantic order\n // https://perfectionist.dev/rules/sort-union-types\n \"perfectionist/sort-union-types\": \"error\",\n\n // Sort intersection type members — `A & B` has no semantic order\n // https://perfectionist.dev/rules/sort-intersection-types\n \"perfectionist/sort-intersection-types\": \"error\",\n },\n },\n ]\n}\n\n/**\n * Structural sorting rules — AI mode only.\n * These sort code elements that *could* have semantic ordering\n * (e.g., object keys grouped by concern). Enforcing alphabetical\n * order here is a trade-off: consistency over intent. Worth it\n * for AI-generated code where \"intent\" is often random.\n */\nexport function perfectionistAiConfig(): FlatConfigArray {\n return [\n {\n name: \"eslint-config-setup/perfectionist-ai\",\n rules: {\n // Sort interface members — consistent shape definitions\n // https://perfectionist.dev/rules/sort-interfaces\n \"perfectionist/sort-interfaces\": \"error\",\n\n // Sort object type members — consistent type definitions\n // https://perfectionist.dev/rules/sort-object-types\n \"perfectionist/sort-object-types\": \"error\",\n\n // Sort enum members — consistent enum definitions\n // https://perfectionist.dev/rules/sort-enums\n \"perfectionist/sort-enums\": \"error\",\n\n // Sort JSX props — consistent component usage\n // https://perfectionist.dev/rules/sort-jsx-props\n \"perfectionist/sort-jsx-props\": \"error\",\n\n // Sort object keys — consistent object literals\n // https://perfectionist.dev/rules/sort-objects\n \"perfectionist/sort-objects\": \"error\",\n\n // Sort class members — consistent class structure\n // https://perfectionist.dev/rules/sort-classes\n \"perfectionist/sort-classes\": \"error\",\n\n // Sort switch cases — consistent case ordering\n // https://perfectionist.dev/rules/sort-switch-case\n \"perfectionist/sort-switch-case\": \"error\",\n\n // Sort Map entries — consistent Map initialization\n // https://perfectionist.dev/rules/sort-maps\n \"perfectionist/sort-maps\": \"error\",\n\n // Sort Set entries — consistent Set initialization\n // https://perfectionist.dev/rules/sort-sets\n \"perfectionist/sort-sets\": \"error\",\n\n // Sort array.includes() members — consistent membership checks\n // https://perfectionist.dev/rules/sort-array-includes\n \"perfectionist/sort-array-includes\": \"error\",\n },\n },\n ]\n}\n","import prettierConfig from \"eslint-config-prettier\"\n\nimport type { FlatConfigArray } from \"../types\"\n\nimport { createConfig } from \"../build/config-builder\"\n\n/**\n * Prettier compat config — disables all ESLint rules that conflict with Prettier.\n * Must be the last config block (before OxLint if enabled).\n *\n * Preset: eslint-config-prettier (turns off ~30 formatting rules)\n * @see https://github.com/prettier/eslint-config-prettier#readme\n */\nexport function prettierCompatConfig(): FlatConfigArray {\n return createConfig({\n name: \"eslint-config-setup/prettier\",\n presets: [prettierConfig],\n }).build()\n}\n","export const TYPESCRIPT_SOURCE_FILES = [\n \"**/*.ts\",\n \"**/*.tsx\",\n \"**/*.mts\",\n \"**/*.cts\",\n] as const\n\nexport const MARKDOWN_DOCUMENT_FILES = [\"**/*.{md,mdx}\"] as const\nexport const MARKDOWN_CODE_BLOCK_FILES = [\"**/*.{md,mdx}/**\"] as const\n","import type { ESLint, Linter, Rule } from \"eslint\"\n\n/**\n * React Compat Plugin — merges all `@eslint-react` sub-plugins into a single\n * `react` namespace and re-exports rules under legacy `eslint-plugin-react`\n * names where a 1:1 equivalent exists.\n *\n * **Why?** OxLint implements many React rules under the classic `react/` prefix\n * with legacy names (e.g. `react/jsx-key`, `react/no-danger`). By registering\n * the modern `@eslint-react` rule implementations under those legacy names, we\n * get automatic OxLint coverage — OxLint runs the fast Rust check and ESLint\n * skips the JS version via `eslint-plugin-oxlint`'s `flat/react` config.\n *\n * Rules without a legacy equivalent keep their `@eslint-react` short name\n * (e.g. `react/no-context-provider`, `react/no-leaked-event-listener`).\n * As OxLint expands React support, more rules will automatically be covered.\n *\n * @see https://eslint-react.xyz/docs/rules/overview - `@eslint-react` rules overview\n * @see https://oxc.rs/docs/guide/usage/linter/rules.html - OxLint rules\n */\nimport eslintReactPlugin from \"@eslint-react/eslint-plugin\"\n\ntype PluginRules = Record<string, Rule.RuleModule>\n\n// eslint-disable-next-line @typescript-eslint/no-unsafe-type-assertion -- Typing the rules export\nconst coreRules = eslintReactPlugin.rules as PluginRules\n\nfunction selectPrefixedRules(prefix: string): PluginRules {\n const result: PluginRules = {}\n\n for (const [name, rule] of Object.entries(coreRules)) {\n if (name.startsWith(prefix)) {\n result[name.slice(prefix.length)] = rule\n }\n }\n\n return result\n}\n\nconst domRules = selectPrefixedRules(\"dom-\")\nconst jsxRules = selectPrefixedRules(\"jsx-\")\nconst namingRules = selectPrefixedRules(\"naming-convention-\")\nconst rscRules = selectPrefixedRules(\"rsc-\")\nconst webApiRules = selectPrefixedRules(\"web-api-\")\n\n// ── Legacy name mapping ─────────────────────────────────────────────────────\n// Maps legacy eslint-plugin-react name → { source rules object, original name }\n// Based on @eslint-react's `disable-conflict-eslint-plugin-react` config.\n// Only 1:1 mappings are included — 1:many (e.g. `no-unsafe` → 3 rules) are skipped.\n\nexport const REACT_COMPAT_LEGACY_ALIAS_NAMES = [\n \"button-has-type\",\n \"display-name\",\n \"forward-ref-uses-ref\",\n \"hook-use-state\",\n \"iframe-missing-sandbox\",\n \"jsx-key\",\n \"jsx-key-before-spread\",\n \"jsx-no-comment-textnodes\",\n \"jsx-no-constructed-context-values\",\n \"jsx-no-leaked-render\",\n \"jsx-no-script-url\",\n \"jsx-no-target-blank\",\n \"jsx-no-useless-fragment\",\n \"no-access-state-in-setstate\",\n \"no-array-index-key\",\n \"no-children-prop\",\n \"no-danger\",\n \"no-danger-with-children\",\n \"no-did-mount-set-state\",\n \"no-did-update-set-state\",\n \"no-direct-mutation-state\",\n \"no-find-dom-node\",\n \"no-namespace\",\n \"no-object-type-as-default-prop\",\n \"no-render-return-value\",\n \"no-unknown-property\",\n \"no-unstable-nested-components\",\n \"no-unused-class-component-members\",\n \"no-unused-state\",\n \"no-will-update-set-state\",\n \"style-prop-object\",\n \"void-dom-elements-no-children\",\n] as const\n\nconst LEGACY_ALIASES =\n {\n // ── Core: identical names ──────────────────────────────────────────\n \"no-access-state-in-setstate\": [coreRules, \"no-access-state-in-setstate\"],\n \"no-array-index-key\": [coreRules, \"no-array-index-key\"],\n \"no-children-prop\": [jsxRules, \"no-children-prop\"],\n \"no-direct-mutation-state\": [coreRules, \"no-direct-mutation-state\"],\n \"no-unused-class-component-members\": [\n coreRules,\n \"no-unused-class-component-members\",\n ],\n \"no-unused-state\": [coreRules, \"no-unused-state\"],\n \"jsx-no-comment-textnodes\": [jsxRules, \"no-comment-textnodes\"],\n\n // ── Core: renamed 1:1 ──────────────────────────────────────────────\n \"jsx-key\": [coreRules, \"no-missing-key\"],\n \"jsx-key-before-spread\": [jsxRules, \"no-key-after-spread\"],\n \"jsx-no-constructed-context-values\": [\n coreRules,\n \"no-unstable-context-value\",\n ],\n \"jsx-no-leaked-render\": [coreRules, \"no-leaked-conditional-rendering\"],\n \"jsx-no-useless-fragment\": [jsxRules, \"no-useless-fragment\"],\n \"no-object-type-as-default-prop\": [coreRules, \"no-unstable-default-props\"],\n \"no-unstable-nested-components\": [\n coreRules,\n \"no-nested-component-definitions\",\n ],\n \"display-name\": [coreRules, \"no-missing-component-display-name\"],\n \"forward-ref-uses-ref\": [coreRules, \"no-forward-ref\"],\n \"no-did-mount-set-state\": [\n coreRules,\n \"no-set-state-in-component-did-mount\",\n ],\n \"no-did-update-set-state\": [\n coreRules,\n \"no-set-state-in-component-did-update\",\n ],\n \"no-will-update-set-state\": [\n coreRules,\n \"no-set-state-in-component-will-update\",\n ],\n\n // ── Naming convention → legacy names ───────────────────────────────\n \"hook-use-state\": [coreRules, \"use-state\"],\n\n // ── DOM → legacy react/ names (not react-dom/) ─────────────────────\n \"no-danger\": [domRules, \"no-dangerously-set-innerhtml\"],\n \"no-danger-with-children\": [\n domRules,\n \"no-dangerously-set-innerhtml-with-children\",\n ],\n \"no-find-dom-node\": [domRules, \"no-find-dom-node\"],\n \"no-namespace\": [jsxRules, \"no-namespace\"],\n \"no-render-return-value\": [domRules, \"no-render-return-value\"],\n \"jsx-no-script-url\": [domRules, \"no-script-url\"],\n \"jsx-no-target-blank\": [domRules, \"no-unsafe-target-blank\"],\n \"no-unknown-property\": [domRules, \"no-unknown-property\"],\n \"void-dom-elements-no-children\": [\n domRules,\n \"no-void-elements-with-children\",\n ],\n \"button-has-type\": [domRules, \"no-missing-button-type\"],\n \"iframe-missing-sandbox\": [domRules, \"no-missing-iframe-sandbox\"],\n \"style-prop-object\": [domRules, \"no-string-style-prop\"],\n } satisfies Record<\n (typeof REACT_COMPAT_LEGACY_ALIAS_NAMES)[number],\n [source: PluginRules, originalName: string]\n >\n\n// Build the set of original rule names that are aliased to a legacy name.\n// These will NOT be included under their original name to avoid duplicates.\nconst aliasedOriginals = new Set<string>()\nfor (const [source, originalName] of Object.values(LEGACY_ALIASES)) {\n if (source === coreRules) {\n aliasedOriginals.add(originalName)\n } else if (source === domRules) {\n aliasedOriginals.add(`dom-${originalName}`)\n } else if (source === jsxRules) {\n aliasedOriginals.add(`jsx-${originalName}`)\n } else if (source === namingRules) {\n aliasedOriginals.add(`naming-convention-${originalName}`)\n } else if (source === rscRules) {\n aliasedOriginals.add(`rsc-${originalName}`)\n } else if (source === webApiRules) {\n aliasedOriginals.add(`web-api-${originalName}`)\n }\n}\n\n// ── Merge all rules ─────────────────────────────────────────────────────────\nconst mergedRules: PluginRules = {}\n\n// 1. Core rules — skip those that have a legacy alias\nfor (const [name, rule] of Object.entries(coreRules)) {\n if (!aliasedOriginals.has(name)) {\n mergedRules[name] = rule\n }\n}\n\n// 2. Sub-plugin rules — use short name (strip sub-plugin prefix).\n// Skip `prefer-namespace-import` from dom (collides with core).\nconst subPlugins: Array<[PluginRules, Set<string>]> = [\n [domRules, new Set([\"prefer-namespace-import\"])],\n [jsxRules, new Set()],\n [webApiRules, new Set()],\n [namingRules, new Set()],\n [rscRules, new Set()],\n]\n\nfor (const [rules, skip] of subPlugins) {\n for (const [name, rule] of Object.entries(rules)) {\n if (skip.has(name)) continue\n // Skip sub-plugin rules that are aliased to a legacy name\n const isAliased = Object.values(LEGACY_ALIASES).some(\n ([source, originalName]) => source === rules && originalName === name,\n )\n if (!isAliased) {\n mergedRules[name] = rule\n }\n }\n}\n\n// 3. Legacy aliases — register under legacy name pointing to the implementation\nfor (const [legacyName, [source, originalName]] of Object.entries(\n LEGACY_ALIASES,\n)) {\n mergedRules[legacyName] = source[originalName]\n}\n\n// ── Reverse map: original name → compat name ────────────────────────────────\n// Used by translatePresetRules to convert @eslint-react preset keys to react/ keys.\nconst originalToCompat = new Map<string, string>()\nfor (const [legacyName, [source, originalName]] of Object.entries(LEGACY_ALIASES)) {\n originalToCompat.set(originalName, legacyName)\n if (source === domRules) {\n originalToCompat.set(`dom-${originalName}`, legacyName)\n } else if (source === jsxRules) {\n originalToCompat.set(`jsx-${originalName}`, legacyName)\n } else if (source === namingRules) {\n originalToCompat.set(`naming-convention-${originalName}`, legacyName)\n } else if (source === rscRules) {\n originalToCompat.set(`rsc-${originalName}`, legacyName)\n } else if (source === webApiRules) {\n originalToCompat.set(`web-api-${originalName}`, legacyName)\n }\n}\n\n/**\n * Translates rules from an `@eslint-react` preset (e.g. `recommended`, `strict`)\n * into `react/` compat names that match our unified plugin namespace.\n *\n * Example: `\"@eslint-react/no-missing-key\": \"error\"` → `\"react/jsx-key\": \"error\"`\n */\nexport function translatePresetRules(\n presetRules: Linter.RulesRecord,\n): Linter.RulesRecord {\n const result: Linter.RulesRecord = {}\n\n for (const [key, value] of Object.entries(presetRules)) {\n // Strip plugin prefix: @eslint-react/dom/X → X, @eslint-react/X → X\n const shortName = key\n .replace(\n /^@eslint-react\\/(?:dom|web-api|naming-convention|rsc)\\//,\n \"\",\n )\n .replace(/^@eslint-react\\//, \"\")\n .replace(/^(?:dom|web-api|naming-convention|rsc)-/, \"\")\n\n const compatName = originalToCompat.get(shortName) ?? shortName\n if (compatName in mergedRules) {\n result[`react/${compatName}`] = value\n }\n }\n\n return result\n}\n\n/**\n * Unified React plugin registered as `react` in ESLint flat config.\n * Contains all `@eslint-react` rule implementations under OxLint-compatible names.\n */\nexport const reactCompatPlugin: ESLint.Plugin = {\n meta: {\n name: \"react-compat\",\n version: \"1.0.0\",\n },\n rules: mergedRules,\n}\n","import type { Linter } from \"eslint\"\n\nimport eslintReactPlugin from \"@eslint-react/eslint-plugin\"\nimport stylisticPlugin from \"@stylistic/eslint-plugin\"\n// @ts-expect-error -- no type declarations available\nimport jsxA11yPlugin from \"eslint-plugin-jsx-a11y\"\nimport reactHooksPlugin from \"eslint-plugin-react-hooks\"\n// @ts-expect-error -- no type declarations available\nimport reactPerfPlugin from \"eslint-plugin-react-perf\"\nimport reactRefreshPlugin from \"eslint-plugin-react-refresh\"\nimport globals from \"globals\"\n\nimport type { FlatConfigArray } from \"../types\"\n\nimport { createConfig } from \"../build/config-builder\"\nimport {\n TYPESCRIPT_SOURCE_FILES,\n} from \"../file-patterns\"\nimport {\n reactCompatPlugin,\n translatePresetRules,\n} from \"../plugins/react-compat\"\n\ntype Builder = ReturnType<typeof createConfig>\n\n// ── Derive react/ rules from @eslint-react presets ──────────────────────────\n// strict-type-checked is translated to react/ compat names. Hook/compiler rules\n// are intentionally supplied by eslint-plugin-react-hooks under react-hooks/*.\n// eslint-disable-next-line @typescript-eslint/no-unsafe-type-assertion -- Typing the eslint-react configs shape\nconst typedConfigs = eslintReactPlugin.configs as unknown as Record<\n string,\n { rules: Linter.RulesRecord }\n>\nconst strictTypeCheckedRules = typedConfigs[\"strict-type-checked\"].rules\n\nexport const REACT_HOOKS_REPLACED_ESLINT_REACT_RULES = [\n \"error-boundaries\",\n \"exhaustive-deps\",\n \"purity\",\n \"rules-of-hooks\",\n \"set-state-in-effect\",\n \"set-state-in-render\",\n \"static-components\",\n \"unsupported-syntax\",\n \"use-memo\",\n] as const\n\nconst reactHooksReplacedRules = new Set<string>(\n REACT_HOOKS_REPLACED_ESLINT_REACT_RULES,\n)\n\nfunction filterReactHooksRules(rules: Linter.RulesRecord): Linter.RulesRecord {\n const filtered: Linter.RulesRecord = {}\n\n for (const [ruleName, value] of Object.entries(rules)) {\n const shortName = ruleName.replace(/^@eslint-react\\//, \"\")\n if (!reactHooksReplacedRules.has(shortName)) {\n filtered[ruleName] = value\n }\n }\n\n return filtered\n}\n\nconst presetRules = translatePresetRules(filterReactHooksRules(strictTypeCheckedRules))\n\nconst reactHooksRecommendedLatest = reactHooksPlugin.configs.flat[\n \"recommended-latest\"\n] as Linter.Config\n// eslint-disable-next-line @typescript-eslint/no-unsafe-type-assertion -- The plugin ships flat config metadata outside ESLint's Plugin type.\nconst reactHooksPluginForEslint = reactHooksPlugin as unknown as Record<string, unknown>\n\nconst EXTRA_REACT_RULES = {\n \"react/no-duplicate-key\": \"error\",\n \"react/no-implicit-key\": \"error\",\n \"react/no-unknown-property\": \"error\",\n \"react/style-prop-object\": \"error\",\n} satisfies Linter.RulesRecord\n\nexport const AI_ADDED_REACT_RULES = {\n \"react/no-unused-state\": \"error\",\n} satisfies Linter.RulesRecord\n\nexport const AI_REACT_PERF_RULES = {\n \"react-perf/jsx-no-jsx-as-prop\": \"error\",\n \"react-perf/jsx-no-new-array-as-prop\": \"error\",\n \"react-perf/jsx-no-new-function-as-prop\": \"error\",\n \"react-perf/jsx-no-new-object-as-prop\": \"error\",\n} satisfies Linter.RulesRecord\n\nconst JSX_A11Y_ERROR_RULES = {\n \"jsx-a11y/alt-text\": \"error\",\n \"jsx-a11y/anchor-has-content\": \"error\",\n \"jsx-a11y/anchor-is-valid\": \"error\",\n \"jsx-a11y/aria-activedescendant-has-tabindex\": \"error\",\n \"jsx-a11y/aria-props\": \"error\",\n \"jsx-a11y/aria-proptypes\": \"error\",\n \"jsx-a11y/aria-role\": \"error\",\n \"jsx-a11y/aria-unsupported-elements\": \"error\",\n \"jsx-a11y/click-events-have-key-events\": \"error\",\n \"jsx-a11y/heading-has-content\": \"error\",\n \"jsx-a11y/html-has-lang\": \"error\",\n \"jsx-a11y/img-redundant-alt\": \"error\",\n \"jsx-a11y/label-has-associated-control\": \"error\",\n \"jsx-a11y/mouse-events-have-key-events\": \"error\",\n \"jsx-a11y/no-access-key\": \"error\",\n \"jsx-a11y/no-distracting-elements\": \"error\",\n \"jsx-a11y/no-redundant-roles\": \"error\",\n \"jsx-a11y/role-has-required-aria-props\": \"error\",\n \"jsx-a11y/role-supports-aria-props\": \"error\",\n \"jsx-a11y/scope\": \"error\",\n \"jsx-a11y/tabindex-no-positive\": \"error\",\n \"jsx-a11y/lang\": \"error\",\n \"jsx-a11y/autocomplete-valid\": \"error\",\n} satisfies Linter.RulesRecord\n\nexport const AI_PROMOTED_REACT_RULES = [\n \"react/jsx-no-comment-textnodes\",\n \"react/jsx-no-useless-fragment\",\n \"react/jsx-no-constructed-context-values\",\n \"react/no-array-index-key\",\n \"react/no-object-type-as-default-prop\",\n \"react/jsx-no-target-blank\",\n \"react/button-has-type\",\n \"react/iframe-missing-sandbox\",\n \"react/forward-ref-uses-ref\",\n \"react/no-context-provider\",\n \"react/no-use-context\",\n \"react/no-leaked-event-listener\",\n \"react/no-leaked-interval\",\n \"react/no-leaked-timeout\",\n \"react/no-leaked-resize-observer\",\n] as const\n\nconst AI_A11Y_RULES = [\n \"jsx-a11y/no-static-element-interactions\",\n \"jsx-a11y/no-noninteractive-element-interactions\",\n \"jsx-a11y/interactive-supports-focus\",\n] as const\n\nfunction addRules(builder: Builder, rules: Linter.RulesRecord): void {\n for (const [ruleName, value] of Object.entries(rules)) {\n builder.addRule(ruleName, value)\n }\n}\n\nfunction addExtraReactRules(builder: Builder): void {\n addRules(builder, EXTRA_REACT_RULES)\n}\n\nfunction addStylisticReactRules(builder: Builder): void {\n builder.addRule(\"@stylistic/jsx-self-closing-comp\", \"error\")\n builder.addRule(\"@stylistic/jsx-curly-brace-presence\", [\n \"error\",\n { props: \"never\", children: \"never\" },\n ])\n}\n\nfunction addReactRefreshRules(builder: Builder): void {\n builder.addRule(\"react-refresh/only-export-components\", [\n \"warn\",\n { allowConstantExport: true },\n ])\n}\n\nfunction addAccessibilityRules(builder: Builder): void {\n addRules(builder, JSX_A11Y_ERROR_RULES)\n builder.addRule(\"jsx-a11y/no-autofocus\", [\"error\", { ignoreNonDOM: true }])\n}\n\nfunction applyAiReactRules(builder: Builder): void {\n for (const ruleName of AI_PROMOTED_REACT_RULES) {\n builder.overrideSeverity(ruleName, \"error\")\n }\n\n addRules(builder, AI_ADDED_REACT_RULES)\n addRules(builder, AI_REACT_PERF_RULES)\n\n for (const ruleName of AI_A11Y_RULES) {\n builder.addRule(ruleName, \"error\")\n }\n}\n\nfunction addReactFileOverrides(builder: Builder): void {\n builder.addFileOverride(\n \"eslint-config-setup/react-typescript\",\n [...TYPESCRIPT_SOURCE_FILES],\n {\n // Allow async event handlers — onClick={async () => {...}} is idiomatic React\n \"@typescript-eslint/no-misused-promises\": [\n \"error\",\n { checksVoidReturn: false },\n ],\n },\n )\n}\n\n/**\n * React config — React 19+, Hooks, JSX accessibility, and Web API leak detection.\n *\n * Uses `@eslint-react` (eslint-plugin-react-x) for React, DOM, Web API,\n * naming-convention, and RSC rules under the `react/` compat namespace.\n * Rules of Hooks and React Compiler linting come from Meta's\n * eslint-plugin-react-hooks under the native `react-hooks/` namespace.\n *\n * Base React severities come from the `@eslint-react` `strict-type-checked` preset.\n * When `ai: true`, preset \"warn\" rules that AI should always get right are\n * promoted to \"error\", and React performance rules are enabled as errors.\n *\n * @see https://eslint-react.xyz/docs/rules/overview\n * @see https://www.npmjs.com/package/eslint-plugin-react-hooks\n * @see https://github.com/cvazac/eslint-plugin-react-perf\n * @see https://github.com/ArnaudBarre/eslint-plugin-react-refresh\n * @see https://github.com/jsx-eslint/eslint-plugin-jsx-a11y#supported-rules\n */\nexport function reactConfig(opts?: { ai?: boolean }): FlatConfigArray {\n const isAi = opts?.ai ?? false\n\n const builder = createConfig({\n name: \"eslint-config-setup/react\",\n presets: [{ rules: presetRules }, reactHooksRecommendedLatest],\n plugins: {\n react: reactCompatPlugin,\n \"@stylistic\": stylisticPlugin,\n \"react-hooks\": reactHooksPluginForEslint,\n // eslint-disable-next-line @typescript-eslint/no-unsafe-type-assertion -- Plugin from untyped module\n \"react-perf\": reactPerfPlugin as Record<string, unknown>,\n \"react-refresh\": reactRefreshPlugin,\n // eslint-disable-next-line @typescript-eslint/no-unsafe-type-assertion -- Plugin from untyped module\n \"jsx-a11y\": jsxA11yPlugin as Record<string, unknown>,\n },\n languageOptions: {\n globals: {\n ...globals.browser,\n },\n parserOptions: {\n ecmaFeatures: {\n jsx: true,\n },\n },\n },\n })\n\n addExtraReactRules(builder)\n addStylisticReactRules(builder)\n addReactRefreshRules(builder)\n addAccessibilityRules(builder)\n\n // ── AI mode: promote preset \"warn\" rules to \"error\" ───────────────\n // These rules catch real bugs or patterns AI should always avoid.\n // overrideSeverity validates that the rule exists in the preset —\n // if a future @eslint-react version removes one, we get a build error.\n if (isAi) {\n applyAiReactRules(builder)\n }\n\n addReactFileOverrides(builder)\n\n return builder.build()\n}\n","import reactEffectPlugin from \"eslint-plugin-react-you-might-not-need-an-effect\"\n\nimport type { FlatConfigArray } from \"../types\"\n\n/**\n * React effect config — catches unnecessary useEffect anti-patterns.\n * Codifies the patterns from the React docs article \"You Might Not Need an Effect\".\n *\n * Complements react-hooks (which checks dependency arrays are correct) by\n * detecting when the entire effect is unnecessary — derived state, chained\n * state updates, prop-triggered resets, and more.\n *\n * @see https://react.dev/learn/you-might-not-need-an-effect\n * @see https://github.com/nickjvandyke/eslint-plugin-react-you-might-not-need-an-effect\n */\nexport function reactEffectConfig(): FlatConfigArray {\n return [\n {\n name: \"eslint-config-setup/react-effect\",\n plugins: {\n \"react-you-might-not-need-an-effect\": reactEffectPlugin,\n },\n rules: {\n // Disallow storing derived state in an effect — compute at render time or useMemo\n // https://github.com/nickjvandyke/eslint-plugin-react-you-might-not-need-an-effect\n \"react-you-might-not-need-an-effect/no-derived-state\": \"error\",\n\n // Disallow chaining state updates in an effect — update together instead\n // https://github.com/nickjvandyke/eslint-plugin-react-you-might-not-need-an-effect\n \"react-you-might-not-need-an-effect/no-chain-state-updates\": \"error\",\n\n // Disallow using state + effect as an event handler — call logic directly\n // https://github.com/nickjvandyke/eslint-plugin-react-you-might-not-need-an-effect\n \"react-you-might-not-need-an-effect/no-event-handler\": \"error\",\n\n // Disallow adjusting state when a prop changes — compute inline during render\n // https://github.com/nickjvandyke/eslint-plugin-react-you-might-not-need-an-effect\n \"react-you-might-not-need-an-effect/no-adjust-state-on-prop-change\": \"warn\",\n\n // Disallow resetting all state when a prop changes — use the key prop instead\n // https://github.com/nickjvandyke/eslint-plugin-react-you-might-not-need-an-effect\n \"react-you-might-not-need-an-effect/no-reset-all-state-on-prop-change\": \"error\",\n\n // Disallow passing live state to parent via effect — lift state up instead\n // https://github.com/nickjvandyke/eslint-plugin-react-you-might-not-need-an-effect\n \"react-you-might-not-need-an-effect/no-pass-live-state-to-parent\": \"error\",\n\n // Disallow passing fetched data to parent via effect — fetch in parent instead\n // https://github.com/nickjvandyke/eslint-plugin-react-you-might-not-need-an-effect\n \"react-you-might-not-need-an-effect/no-pass-data-to-parent\": \"error\",\n\n // Disallow external-store subscriptions in an effect — use useSyncExternalStore\n // https://github.com/nickjvandyke/eslint-plugin-react-you-might-not-need-an-effect\n \"react-you-might-not-need-an-effect/no-external-store-subscription\": \"error\",\n\n // Disallow initializing state in an effect — pass initial value to useState\n // https://github.com/nickjvandyke/eslint-plugin-react-you-might-not-need-an-effect\n \"react-you-might-not-need-an-effect/no-initialize-state\": \"error\",\n },\n },\n ]\n}\n","import { configs as regexpConfigs } from \"eslint-plugin-regexp\"\n\nimport type { FlatConfigArray } from \"../types\"\n\nimport { createConfig } from \"../build/config-builder\"\n\n/**\n * RegExp config — uses the full `flat/recommended` preset from eslint-plugin-regexp.\n * Validates regular expression syntax, detects common mistakes, and suggests\n * simpler patterns.\n *\n * Preset: eslint-plugin-regexp flat/recommended (all rules at their default severity)\n * @see https://ota-meshi.github.io/eslint-plugin-regexp/\n * @see https://ota-meshi.github.io/eslint-plugin-regexp/rules/\n */\nexport function regexpConfig(opts?: { ai?: boolean }): FlatConfigArray {\n const isAi = opts?.ai ?? false\n\n const builder = createConfig({\n name: \"eslint-config-setup/regexp\",\n presets: [regexpConfigs[\"flat/recommended\"]],\n })\n\n // ── Beyond recommended ──────────────────────────────────────────\n\n // Disallow invisible control characters in regex — almost always a paste artifact\n // https://ota-meshi.github.io/eslint-plugin-regexp/rules/no-control-character.html\n .addRule(\"regexp/no-control-character\", \"error\")\n\n // Disallow ambiguous octal escapes — use \\x01 or named backreference instead\n // https://ota-meshi.github.io/eslint-plugin-regexp/rules/no-octal.html\n .addRule(\"regexp/no-octal\", \"error\")\n\n // Disallow standalone backslashes — /\\a/ silently ignores the backslash\n // https://ota-meshi.github.io/eslint-plugin-regexp/rules/no-standalone-backslash.html\n .addRule(\"regexp/no-standalone-backslash\", \"error\")\n\n // Detect patterns with quadratic move behavior — subtle ReDoS variant\n // https://ota-meshi.github.io/eslint-plugin-regexp/rules/no-super-linear-move.html\n .addRule(\"regexp/no-super-linear-move\", \"error\")\n\n // Require $$ for literal dollar signs in replacement strings — prevents bugs\n // https://ota-meshi.github.io/eslint-plugin-regexp/rules/prefer-escape-replacement-dollar-char.html\n .addRule(\"regexp/prefer-escape-replacement-dollar-char\", \"error\")\n\n if (isAi) {\n builder.addRule(\"regexp/prefer-lookaround\", \"error\")\n builder.addRule(\"regexp/prefer-named-backreference\", \"error\")\n builder.addRule(\"regexp/prefer-named-replacement\", \"error\")\n builder.addRule(\"regexp/prefer-quantifier\", \"error\")\n builder.addRule(\"regexp/prefer-result-array-groups\", \"error\")\n builder.addRule(\"regexp/require-unicode-sets-regexp\", \"error\")\n }\n\n return builder.build()\n}\n","import type { ESLint } from \"eslint\"\n\n// @ts-expect-error -- no type declarations available\nimport securityPlugin from \"eslint-plugin-security\"\n\nimport type { FlatConfigArray } from \"../types\"\n\n// eslint-disable-next-line @typescript-eslint/no-unsafe-type-assertion -- Typing the security plugin\nconst plugin = securityPlugin as unknown as ESLint.Plugin\n\n/**\n * Security config — Node.js security patterns from eslint-plugin-security.\n * We manually select rules instead of using the preset because the preset\n * enables `detect-object-injection` which produces too many false positives.\n *\n * @see https://github.com/eslint-community/eslint-plugin-security#rules\n */\nexport function securityConfig(): FlatConfigArray {\n return [\n {\n name: \"eslint-config-setup/security\",\n plugins: {\n security: plugin,\n },\n rules: {\n // ── Errors: dangerous patterns that should never appear ────────\n\n // Detect Buffer read/write without noAssert — can read out of bounds\n // https://github.com/eslint-community/eslint-plugin-security/blob/main/docs/rules/detect-buffer-noassert.md\n \"security/detect-buffer-noassert\": \"error\",\n\n // Detect child_process usage — potential command injection vector\n // https://github.com/eslint-community/eslint-plugin-security/blob/main/docs/rules/detect-child-process.md\n \"security/detect-child-process\": \"error\",\n\n // Detect disabled mustache escaping — XSS risk in templates\n // https://github.com/eslint-community/eslint-plugin-security/blob/main/docs/rules/detect-disable-mustache-escape.md\n \"security/detect-disable-mustache-escape\": \"error\",\n\n // Detect eval() with variable arguments — code injection risk\n // https://github.com/eslint-community/eslint-plugin-security/blob/main/docs/rules/detect-eval-with-expression.md\n \"security/detect-eval-with-expression\": \"error\",\n\n // Detect new Buffer(n) — deprecated, use Buffer.alloc() instead\n // https://github.com/eslint-community/eslint-plugin-security/blob/main/docs/rules/detect-new-buffer.md\n \"security/detect-new-buffer\": \"error\",\n\n // Detect CSRF middleware placed after method-override — CSRF bypass\n // https://github.com/eslint-community/eslint-plugin-security/blob/main/docs/rules/detect-no-csrf-before-method-override.md\n \"security/detect-no-csrf-before-method-override\": \"error\",\n\n // Detect Math.random() / pseudoRandomBytes — not cryptographically secure\n // https://github.com/eslint-community/eslint-plugin-security/blob/main/docs/rules/detect-pseudoRandomBytes.md\n \"security/detect-pseudoRandomBytes\": \"error\",\n\n // Detect regexes vulnerable to ReDoS (catastrophic backtracking)\n // https://github.com/eslint-community/eslint-plugin-security/blob/main/docs/rules/detect-unsafe-regex.md\n \"security/detect-unsafe-regex\": \"error\",\n\n // ── Warnings: worth reviewing but may have legitimate uses ─────\n\n // Detect dynamic fs paths — potential path traversal (many false positives)\n // https://github.com/eslint-community/eslint-plugin-security/blob/main/docs/rules/detect-non-literal-fs-filename.md\n \"security/detect-non-literal-fs-filename\": \"warn\",\n\n // Detect dynamic regex construction — potential ReDoS\n // https://github.com/eslint-community/eslint-plugin-security/blob/main/docs/rules/detect-non-literal-regexp.md\n \"security/detect-non-literal-regexp\": \"warn\",\n\n // Detect dynamic require() — potential code injection\n // https://github.com/eslint-community/eslint-plugin-security/blob/main/docs/rules/detect-non-literal-require.md\n \"security/detect-non-literal-require\": \"warn\",\n\n // Detect string comparisons that may leak timing info — side-channel risk\n // https://github.com/eslint-community/eslint-plugin-security/blob/main/docs/rules/detect-possible-timing-attacks.md\n \"security/detect-possible-timing-attacks\": \"warn\",\n\n // Detect Unicode bidirectional control characters — source code trojan attack\n // https://github.com/eslint-community/eslint-plugin-security/blob/main/docs/rules/detect-bidi-characters.md\n \"security/detect-bidi-characters\": \"error\",\n\n // ── Disabled: too many false positives ────────────────────────\n\n // Flags all bracket notation (obj[key]) — nearly every codebase triggers this\n // https://github.com/eslint-community/eslint-plugin-security/blob/main/docs/rules/detect-object-injection.md\n \"security/detect-object-injection\": \"off\",\n },\n },\n ]\n}\n","import sonarjsPlugin from \"eslint-plugin-sonarjs\"\n\nimport type { FlatConfigArray } from \"../types\"\n\nimport { createConfig } from \"../build/config-builder\"\n\n/**\n * SonarJS config — code-quality rules from SonarSource.\n * Hand-picked subset focused on bug detection and code smells.\n * We don't use the full preset because many SonarJS rules overlap with\n * typescript-eslint and unicorn.\n *\n * @see https://github.com/SonarSource/SonarJS/tree/master/packages/jsts/src/rules#readme\n */\nexport function sonarjsConfig(opts?: { ai?: boolean }): FlatConfigArray {\n const isAi = opts?.ai === true\n\n const builder = createConfig({\n name: \"eslint-config-setup/sonarjs\",\n presets: [{\n plugins: { sonarjs: sonarjsPlugin },\n rules: {\n // Detect copy-pasted functions — extract to shared helper instead\n // https://sonarsource.github.io/rspec/#/rspec/S4144/javascript\n \"sonarjs/no-identical-functions\": \"error\",\n\n // Merge nested if-statements that can be combined — reduces nesting\n // https://sonarsource.github.io/rspec/#/rspec/S1066/javascript\n \"sonarjs/no-collapsible-if\": \"error\",\n\n // Simplify `if (x) return true; else return false;` → `return x`\n // https://sonarsource.github.io/rspec/#/rspec/S1125/javascript\n \"sonarjs/no-redundant-boolean\": \"error\",\n\n // Detect collections that are populated but never read — dead code\n // https://sonarsource.github.io/rspec/#/rspec/S4030/javascript\n \"sonarjs/no-unused-collection\": \"error\",\n\n // Return value directly instead of storing in temp variable first\n // https://sonarsource.github.io/rspec/#/rspec/S1488/javascript\n \"sonarjs/prefer-immediate-return\": \"error\",\n\n // Simplify boolean return patterns — `return cond` instead of `if/else`\n // https://sonarsource.github.io/rspec/#/rspec/S1126/javascript\n \"sonarjs/prefer-single-boolean-return\": \"error\",\n\n // Detect identical sub-expressions on both sides of operator (x && x)\n // https://sonarsource.github.io/rspec/#/rspec/S1764/javascript\n \"sonarjs/no-identical-expressions\": \"error\",\n\n // Simplify `!(a === b)` → `a !== b` — more readable\n // https://sonarsource.github.io/rspec/#/rspec/S1940/javascript\n \"sonarjs/no-inverted-boolean-check\": \"error\",\n\n // Detect size/length comparisons that are always true/false\n // https://sonarsource.github.io/rspec/#/rspec/S3981/javascript\n \"sonarjs/no-collection-size-mischeck\": \"error\",\n\n // Detect duplicate conditions in if/else-if chains — copy-paste bug\n // https://sonarsource.github.io/rspec/#/rspec/S1862/javascript\n \"sonarjs/no-identical-conditions\": \"error\",\n\n // Detect identical code in if and else branches — refactoring leftover\n // https://sonarsource.github.io/rspec/#/rspec/S1871/javascript\n \"sonarjs/no-duplicated-branches\": \"error\",\n\n // Detect .filter()/.map()/.slice() called without using the result\n // https://sonarsource.github.io/rspec/#/rspec/S2201/javascript\n \"sonarjs/no-ignored-return\": \"error\",\n\n // Detect redundant return/break/continue at end of block\n // https://sonarsource.github.io/rspec/#/rspec/S3626/javascript\n \"sonarjs/no-redundant-jump\": \"error\",\n\n // Prevent .only() from being committed — blocks CI for others\n // https://sonarsource.github.io/rspec/#/rspec/S6426/javascript\n \"sonarjs/no-exclusive-tests\": \"error\",\n\n // Detect `const sorted = arr.sort()` — .sort() mutates the original\n // https://sonarsource.github.io/rspec/#/rspec/S4043/javascript\n \"sonarjs/no-misleading-array-reverse\": \"error\",\n\n // Require initial value for .reduce() — crashes on empty arrays without it\n // https://sonarsource.github.io/rspec/#/rspec/S6959/javascript\n \"sonarjs/reduce-initial-value\": \"error\",\n\n // Disallow async operations in constructors — use factory methods\n // https://sonarsource.github.io/rspec/#/rspec/S7059/javascript\n \"sonarjs/no-async-constructor\": \"error\",\n\n // Detect `field?: string | undefined` — the `?` already implies undefined\n // https://sonarsource.github.io/rspec/#/rspec/S4782/javascript\n \"sonarjs/no-redundant-optional\": \"error\",\n\n // Detect `string | number | string` — duplicate constituents in unions\n // https://sonarsource.github.io/rspec/#/rspec/S4621/javascript\n \"sonarjs/no-duplicate-in-composite\": \"error\",\n\n // Detect hardcoded secrets (API keys, passwords, tokens) in source code\n // https://sonarsource.github.io/rspec/#/rspec/S6418/javascript\n \"sonarjs/no-hardcoded-secrets\": \"warn\",\n },\n }],\n })\n\n if (isAi) {\n // New AI-only rules (not already in base config)\n builder.addRule(\"sonarjs/no-nested-switch\", \"error\")\n builder.addRule(\"sonarjs/no-nested-template-literals\", \"error\")\n builder.addRule(\"sonarjs/max-union-size\", [\"error\", { threshold: 5 }])\n builder.addRule(\"sonarjs/prefer-type-guard\", \"error\")\n builder.addRule(\"sonarjs/public-static-readonly\", \"error\")\n builder.addRule(\"sonarjs/no-duplicate-string\", [\"error\", { threshold: 3 }])\n }\n\n return builder.build()\n}\n","/* eslint-disable max-lines-per-function, max-statements, complexity -- Rule definition file: sequential builder calls that configure the TypeScript preset. */\nimport tseslint from \"typescript-eslint\"\n\nimport type { FlatConfig, FlatConfigArray } from \"../types\"\n\nimport { createConfig } from \"../build/config-builder\"\nimport { MARKDOWN_CODE_BLOCK_FILES, TYPESCRIPT_SOURCE_FILES } from \"../file-patterns\"\n\n/**\n * TypeScript config — extends typescript-eslint strict presets with project-wide type checking.\n *\n * Presets used:\n * - `tseslint.configs.strictTypeChecked` — all recommended + strict rules with type info\n * - `tseslint.configs.stylisticTypeChecked` — consistent code style with type info\n *\n * The presets already handle many core ESLint rules by disabling them and enabling\n * TS-aware equivalents (no-implied-eval, dot-notation, no-throw-literal, etc.).\n *\n * @see https://typescript-eslint.io/getting-started/\n * @see https://typescript-eslint.io/rules/\n */\nexport function typescriptConfig(opts?: { ai?: boolean; react?: boolean }): FlatConfigArray {\n const isAi = opts?.ai ?? false\n const isReact = opts?.react ?? false\n\n const typeChecked = tseslint.configs.strictTypeChecked\n const stylistic = tseslint.configs.stylisticTypeChecked\n\n // Blocks 0+1: parser setup + ESLint-core replacements (structural, not validated)\n // Block 2 from each: the actual @typescript-eslint/* rules (validated)\n const structuralBlocks = typeChecked.slice(0, 2) as FlatConfigArray\n const ruleBlocks = [typeChecked[2], stylistic[2]] as FlatConfig[]\n\n const builder = createConfig({\n name: \"eslint-config-setup/typescript\",\n passthrough: structuralBlocks,\n presets: ruleBlocks,\n files: [...TYPESCRIPT_SOURCE_FILES],\n ignores: [...MARKDOWN_CODE_BLOCK_FILES],\n languageOptions: {\n parserOptions: {\n // Use project service for automatic tsconfig resolution\n // https://typescript-eslint.io/packages/parser#projectservice\n projectService: true,\n },\n },\n })\n\n // ── Override preset defaults ──────────────────────────────────\n\n // Override bare `error` with underscore-ignore pattern — universal convention\n // Preset sets bare `error` with no options (no ignoreRestSiblings, no _ pattern)\n // https://typescript-eslint.io/rules/no-unused-vars\n builder.overrideRule(\"@typescript-eslint/no-unused-vars\", [\n \"error\",\n {\n args: \"all\",\n argsIgnorePattern: \"^_\",\n caughtErrors: \"all\",\n caughtErrorsIgnorePattern: \"^_\",\n destructuredArrayIgnorePattern: \"^_\",\n varsIgnorePattern: \"^_\",\n ignoreRestSiblings: true,\n },\n ])\n\n // Enforce T[] for simple types, Array<T> for complex — readable array types\n // (in stylisticTypeChecked preset as bare \"error\", we add options)\n // https://typescript-eslint.io/rules/array-type\n builder.overrideRule(\"@typescript-eslint/array-type\", [\n \"error\",\n { default: \"array-simple\" },\n ])\n\n // Override return-await from \"error-handling-correctness-only\" to \"in-try-catch\"\n // https://typescript-eslint.io/rules/return-await\n builder.overrideRule(\"@typescript-eslint/return-await\", [\n \"error\",\n \"in-try-catch\",\n ])\n\n // Downgrade from error to warn — stay current but don't block\n // https://typescript-eslint.io/rules/no-deprecated\n builder.overrideSeverity(\"@typescript-eslint/no-deprecated\", \"warn\")\n\n // Downgrade from error to warn — nudge towards unknown, don't block\n // https://typescript-eslint.io/rules/no-explicit-any\n builder.overrideRule(\"@typescript-eslint/no-explicit-any\", [\n \"warn\",\n { fixToUnknown: true },\n ])\n\n // Enforce `type` over `interface` — consistent, prevents accidental declaration merging\n // https://typescript-eslint.io/rules/consistent-type-definitions\n builder.overrideRule(\"@typescript-eslint/consistent-type-definitions\", [\n \"error\",\n \"type\",\n ])\n\n // Require description for @ts-expect-error — document why you override the compiler\n // https://typescript-eslint.io/rules/ban-ts-comment\n builder.overrideOptions(\"@typescript-eslint/ban-ts-comment\", {\n \"ts-expect-error\": \"allow-with-description\",\n })\n\n // Catch unhandled thenables (not just Promises) and allow async IIFEs\n // https://typescript-eslint.io/rules/no-floating-promises\n builder.overrideOptions(\"@typescript-eslint/no-floating-promises\", {\n checkThenables: true,\n ignoreIIFE: true,\n })\n\n // ── Beyond presets: import/export hygiene ──────────────────\n\n // Enforce `import type { T }` — separate type imports for clarity\n // https://typescript-eslint.io/rules/consistent-type-imports\n builder.addRule(\"@typescript-eslint/consistent-type-imports\", [\n \"error\",\n { fixStyle: isAi ? \"inline-type-imports\" : \"separate-type-imports\" },\n ])\n\n // Enforce `export type { T }` — matches import convention\n // https://typescript-eslint.io/rules/consistent-type-exports\n builder.addRule(\"@typescript-eslint/consistent-type-exports\", [\n \"error\",\n { fixMixedExportsWithInlineTypeSpecifier: true },\n ])\n\n // Prevent type-only imports from triggering side effects\n // https://typescript-eslint.io/rules/no-import-type-side-effects\n builder.addRule(\"@typescript-eslint/no-import-type-side-effects\", \"error\")\n\n // Remove unnecessary namespace qualifiers — cleaner code\n // https://typescript-eslint.io/rules/no-unnecessary-qualifier\n builder.addRule(\"@typescript-eslint/no-unnecessary-qualifier\", \"error\")\n\n // Remove useless `export {}` — keeps module boundaries clean\n // https://typescript-eslint.io/rules/no-useless-empty-export\n builder.addRule(\"@typescript-eslint/no-useless-empty-export\", \"error\")\n\n // Detect redundant `this.x = x` after constructor parameter property\n // https://typescript-eslint.io/rules/no-unnecessary-parameter-property-assignment\n builder.addRule(\n \"@typescript-eslint/no-unnecessary-parameter-property-assignment\",\n \"error\",\n )\n\n // Void-returning callbacks must not accidentally return values\n // Catches: `forEach(x => map.set(x, 1))` — .set() returns the map, but forEach expects void\n // https://typescript-eslint.io/rules/strict-void-return\n builder.addRule(\"@typescript-eslint/strict-void-return\", \"error\")\n\n // Suggest readonly for properties that are never reassigned — clarifies intent\n // https://typescript-eslint.io/rules/prefer-readonly\n builder.addRule(\"@typescript-eslint/prefer-readonly\", isAi ? \"error\" : \"warn\")\n\n // Require comparator for Array.sort() — [10,2,1].sort() → [1,10,2] without one\n // https://typescript-eslint.io/rules/require-array-sort-compare\n builder.addRule(\"@typescript-eslint/require-array-sort-compare\", [\n \"error\",\n { ignoreStringArrays: true },\n ])\n\n // Disallow unsafe type assertions — use type guards instead of `as Type`\n // https://typescript-eslint.io/rules/no-unsafe-type-assertion\n builder.addRule(\"@typescript-eslint/no-unsafe-type-assertion\", \"error\")\n\n // Exhaustive switch — all union/enum values must be handled, no redundant defaults\n // https://typescript-eslint.io/rules/switch-exhaustiveness-check\n builder.addRule(\"@typescript-eslint/switch-exhaustiveness-check\", [\n \"error\",\n {\n allowDefaultCaseForExhaustiveSwitch: false,\n requireDefaultForNonUnion: true,\n },\n ])\n\n // Require async keyword on functions returning Promises — intent is immediately visible\n // https://typescript-eslint.io/rules/promise-function-async\n builder.addRule(\"@typescript-eslint/promise-function-async\", \"error\")\n\n // Enforce property-style signatures — safer due to strict parameter contra-variance\n // https://typescript-eslint.io/rules/method-signature-style\n builder.addRule(\"@typescript-eslint/method-signature-style\", [\n \"error\",\n \"property\",\n ])\n\n // ── Beyond presets: safety & correctness ──────────────────────\n\n // Prevent variable shadowing — catches bugs where inner var hides outer\n // Not in any preset. TS-aware version avoids false positives with type/value merging.\n // https://typescript-eslint.io/rules/no-shadow\n builder.addRule(\"no-shadow\", \"off\")\n builder.addRule(\"@typescript-eslint/no-shadow\", [\n \"error\",\n {\n hoist: \"all\",\n allow: [\"resolve\", \"reject\", \"done\", \"next\", \"error\"],\n ignoreTypeValueShadow: true,\n ignoreFunctionTypeParameterNameValueShadow: true,\n },\n ])\n\n // Allow numbers in template literals — `${count}` is idiomatic JS\n // https://typescript-eslint.io/rules/restrict-template-expressions\n builder.overrideOptions(\"@typescript-eslint/restrict-template-expressions\", { allowNumber: true })\n\n // Require strict boolean expressions — no implicit truthiness checks\n // Prevents bugs like `if (count)` when count is 0 (falsy but valid)\n // https://typescript-eslint.io/rules/strict-boolean-expressions\n builder.addRule(\"@typescript-eslint/strict-boolean-expressions\", [\n \"error\",\n { allowNullableBoolean: true, allowNullableObject: true },\n ])\n\n // ── File overrides ────────────────────────────────────────────\n\n // Disable type-checked rules for plain JS files (no tsconfig coverage)\n // https://typescript-eslint.io/users/configs#disable-type-checked\n builder.addFileOverride(\n \"eslint-config-setup/typescript-js-compat\",\n [\"**/*.{js,mjs,cjs}\"],\n tseslint.configs.disableTypeChecked.rules ?? {},\n )\n\n if (isAi) {\n // ── AI mode: override severity ──────────────────────────────\n builder.overrideSeverity(\"@typescript-eslint/no-explicit-any\", \"error\")\n\n // ── AI mode: override rules with different options ───────────\n builder.overrideRule(\"@typescript-eslint/no-floating-promises\", [\n \"error\",\n { checkThenables: true, ignoreVoid: true },\n ])\n\n // ── AI mode: additional rules ───────────────────────────────\n builder.addRule(\"@typescript-eslint/no-magic-numbers\", [\n \"error\",\n {\n ignore: [-1, 0, 1, 2],\n ignoreArrayIndexes: true,\n ignoreDefaultValues: true,\n enforceConst: true,\n ignoreClassFieldInitialValues: true,\n ignoreEnums: true,\n ignoreNumericLiteralTypes: true,\n ignoreReadonlyClassProperties: true,\n ignoreTypeIndexes: true,\n },\n ])\n builder.addRule(\"@typescript-eslint/explicit-function-return-type\", [\n \"error\",\n {\n allowExpressions: true,\n allowTypedFunctionExpressions: true,\n allowHigherOrderFunctions: true,\n allowIIFEs: true,\n },\n ])\n builder.addRule(\n \"@typescript-eslint/explicit-member-accessibility\",\n \"error\",\n )\n builder.addRule(\n \"@typescript-eslint/prefer-enum-initializers\",\n \"error\",\n )\n builder.addRule(\"@typescript-eslint/naming-convention\", [\n \"error\",\n {\n selector: \"variable\",\n format: isReact\n ? [\"strictCamelCase\", \"UPPER_CASE\", \"StrictPascalCase\"]\n : [\"strictCamelCase\", \"UPPER_CASE\"],\n leadingUnderscore: \"allowSingleOrDouble\",\n trailingUnderscore: \"allow\",\n filter: { regex: \"[- ]\", match: false },\n },\n {\n selector: \"function\",\n format: isReact\n ? [\"strictCamelCase\", \"StrictPascalCase\"]\n : [\"strictCamelCase\"],\n },\n {\n selector: \"parameter\",\n format: [\"strictCamelCase\"],\n leadingUnderscore: \"allow\",\n },\n {\n selector: \"import\",\n format: [\"strictCamelCase\", \"StrictPascalCase\", \"UPPER_CASE\"],\n },\n {\n selector: [\n \"classProperty\",\n \"parameterProperty\",\n \"classMethod\",\n \"objectLiteralMethod\",\n \"typeMethod\",\n \"accessor\",\n ],\n format: [\"strictCamelCase\"],\n leadingUnderscore: \"allowSingleOrDouble\",\n trailingUnderscore: \"allow\",\n filter: { regex: \"[- ]\", match: false },\n },\n {\n selector: [\"objectLiteralProperty\", \"typeProperty\"],\n format: null,\n },\n { selector: \"typeLike\", format: [\"StrictPascalCase\"] },\n {\n selector: \"interface\",\n format: [\"StrictPascalCase\"],\n custom: { regex: \"^I[A-Z]\", match: false },\n },\n {\n selector: \"typeParameter\",\n format: [\"PascalCase\"],\n custom: {\n regex: \"^(T([A-Z][a-zA-Z]*)?|[A-Z])$\",\n match: true,\n },\n },\n {\n selector: \"variable\",\n types: [\"boolean\"],\n format: [\"StrictPascalCase\"],\n prefix: [\"is\", \"has\", \"can\", \"should\", \"will\", \"did\"],\n },\n {\n selector: [\"classProperty\", \"objectLiteralProperty\"],\n format: null,\n modifiers: [\"requiresQuotes\"],\n },\n ])\n builder.addRule(\"@typescript-eslint/member-ordering\", [\n \"warn\",\n {\n default: [\n \"signature\",\n \"call-signature\",\n \"public-static-field\",\n \"protected-static-field\",\n \"private-static-field\",\n \"#private-static-field\",\n \"static-field\",\n \"public-static-method\",\n \"protected-static-method\",\n \"private-static-method\",\n \"#private-static-method\",\n \"static-method\",\n \"public-decorated-field\",\n \"protected-decorated-field\",\n \"private-decorated-field\",\n \"public-instance-field\",\n \"protected-instance-field\",\n \"private-instance-field\",\n \"#private-instance-field\",\n \"public-abstract-field\",\n \"protected-abstract-field\",\n \"field\",\n \"public-constructor\",\n \"protected-constructor\",\n \"private-constructor\",\n \"constructor\",\n [\"public-get\", \"public-set\"],\n [\"protected-get\", \"protected-set\"],\n [\"private-get\", \"private-set\"],\n [\"#private-get\", \"#private-set\"],\n \"public-decorated-method\",\n \"protected-decorated-method\",\n \"private-decorated-method\",\n \"public-instance-method\",\n \"protected-instance-method\",\n \"private-instance-method\",\n \"#private-instance-method\",\n \"public-abstract-method\",\n \"protected-abstract-method\",\n \"method\",\n ],\n },\n ])\n }\n\n return builder.build()\n}\n","/* eslint-disable max-lines-per-function, max-statements -- Rule definition file: one function returning a flat list of rule entries. */\nimport unicornPlugin from \"eslint-plugin-unicorn\"\n\nimport type { FlatConfigArray } from \"../types\"\n\nimport { createConfig } from \"../build/config-builder\"\n\n/**\n * Unicorn config — modern JavaScript idioms and best practices.\n * We hand-pick rules instead of using `flat/recommended` because the\n * recommended preset includes opinionated rules we disagree with\n * (e.g., `no-null`, `no-nested-ternary`, `filename-case`).\n *\n * @see https://github.com/sindresorhus/eslint-plugin-unicorn#rules\n */\nexport function unicornConfig(opts?: { ai?: boolean }): FlatConfigArray {\n const isAi = opts?.ai === true\n\n const builder = createConfig({\n name: \"eslint-config-setup/unicorn\",\n presets: [{\n plugins: { unicorn: unicornPlugin },\n rules: {\n // ── Error prevention ──────────────────────────────────────────\n\n // Forbid `/* eslint-disable */` without specific rule — too broad\n // https://github.com/sindresorhus/eslint-plugin-unicorn/blob/main/docs/rules/no-abusive-eslint-disable.md\n \"unicorn/no-abusive-eslint-disable\": \"error\",\n\n // Disallow `instanceof` with built-in objects — use proper checks instead\n // https://github.com/sindresorhus/eslint-plugin-unicorn/blob/main/docs/rules/no-instanceof-builtins.md\n \"unicorn/no-instanceof-builtins\": \"error\",\n\n // Prevent passing non-function to removeEventListener — common mistake\n // https://github.com/sindresorhus/eslint-plugin-unicorn/blob/main/docs/rules/no-invalid-remove-event-listener.md\n \"unicorn/no-invalid-remove-event-listener\": \"error\",\n\n // Disallow invalid fetch() options — catches typos at lint time\n // https://github.com/sindresorhus/eslint-plugin-unicorn/blob/main/docs/rules/no-invalid-fetch-options.md\n \"unicorn/no-invalid-fetch-options\": \"error\",\n\n // Prefer direct undefined checks over typeof — cleaner with strict mode\n // https://github.com/sindresorhus/eslint-plugin-unicorn/blob/main/docs/rules/no-typeof-undefined.md\n \"unicorn/no-typeof-undefined\": \"error\",\n\n // Remove useless fallback in object spread ({ ...a, x: a.x ?? y })\n // https://github.com/sindresorhus/eslint-plugin-unicorn/blob/main/docs/rules/no-useless-fallback-in-spread.md\n \"unicorn/no-useless-fallback-in-spread\": \"error\",\n\n // Remove unnecessary .length checks before array operations\n // https://github.com/sindresorhus/eslint-plugin-unicorn/blob/main/docs/rules/no-useless-length-check.md\n \"unicorn/no-useless-length-check\": \"error\",\n\n // Remove unnecessary spread operators ([...array] when array already exists)\n // https://github.com/sindresorhus/eslint-plugin-unicorn/blob/main/docs/rules/no-useless-spread.md\n \"unicorn/no-useless-spread\": \"error\",\n\n // Remove useless Promise.resolve/reject wrappers — simplify async code\n // https://github.com/sindresorhus/eslint-plugin-unicorn/blob/main/docs/rules/no-useless-promise-resolve-reject.md\n \"unicorn/no-useless-promise-resolve-reject\": \"error\",\n\n // Disallow redundant undefined where omission preserves semantics.\n // Keep call arguments unchecked: TypeScript often needs explicit\n // `undefined` for required parameters typed as `T | undefined`.\n // https://github.com/sindresorhus/eslint-plugin-unicorn/blob/main/docs/rules/no-useless-undefined.md\n \"unicorn/no-useless-undefined\": [\"warn\", { checkArguments: false }],\n\n // Disallow `await` in Promise.all/race arguments — already a promise\n // https://github.com/sindresorhus/eslint-plugin-unicorn/blob/main/docs/rules/no-await-in-promise-methods.md\n \"unicorn/no-await-in-promise-methods\": \"error\",\n\n // Catch `!a === b` bugs — use `a !== b` instead\n // https://github.com/sindresorhus/eslint-plugin-unicorn/blob/main/docs/rules/no-negation-in-equality-check.md\n \"unicorn/no-negation-in-equality-check\": \"error\",\n\n // Disallow objects with `.then` property — prevents accidental thenables\n // https://github.com/sindresorhus/eslint-plugin-unicorn/blob/main/docs/rules/no-thenable.md\n \"unicorn/no-thenable\": \"error\",\n\n // Disallow `(await foo).bar` — assign to variable first for clarity\n // https://github.com/sindresorhus/eslint-plugin-unicorn/blob/main/docs/rules/no-await-expression-member.md\n \"unicorn/no-await-expression-member\": \"error\",\n\n // Disallow `const self = this` — use arrow functions instead\n // https://github.com/sindresorhus/eslint-plugin-unicorn/blob/main/docs/rules/no-this-assignment.md\n \"unicorn/no-this-assignment\": \"error\",\n\n // Disallow `await` on non-promise values — unnecessary overhead\n // https://github.com/sindresorhus/eslint-plugin-unicorn/blob/main/docs/rules/no-unnecessary-await.md\n \"unicorn/no-unnecessary-await\": \"error\",\n\n // Disallow unnecessary slice end argument — `.length` is the default\n // https://github.com/sindresorhus/eslint-plugin-unicorn/blob/main/docs/rules/no-unnecessary-slice-end.md\n \"unicorn/no-unnecessary-slice-end\": \"error\",\n\n // OFF: Stylistic — developers should decide their own array initialization pattern\n // https://github.com/sindresorhus/eslint-plugin-unicorn/blob/main/docs/rules/no-immediate-mutation.md\n \"unicorn/no-immediate-mutation\": \"off\",\n\n // Disallow recursive access in getters/setters — infinite loop risk\n // https://github.com/sindresorhus/eslint-plugin-unicorn/blob/main/docs/rules/no-accessor-recursion.md\n \"unicorn/no-accessor-recursion\": \"error\",\n\n // Disallow anonymous default exports — hard to find and refactor\n // https://github.com/sindresorhus/eslint-plugin-unicorn/blob/main/docs/rules/no-anonymous-default-export.md\n \"unicorn/no-anonymous-default-export\": \"error\",\n\n // Disallow `this` argument in array methods — use arrow functions\n // https://github.com/sindresorhus/eslint-plugin-unicorn/blob/main/docs/rules/no-array-method-this-argument.md\n \"unicorn/no-array-method-this-argument\": \"error\",\n\n // Disallow passing function references directly to iterator methods\n // Prevents bugs like `['1','2'].map(parseInt)` → [1, NaN]\n // https://github.com/sindresorhus/eslint-plugin-unicorn/blob/main/docs/rules/no-array-callback-reference.md\n \"unicorn/no-array-callback-reference\": \"error\",\n\n // Disallow unreadable IIFEs — extract to named function\n // https://github.com/sindresorhus/eslint-plugin-unicorn/blob/main/docs/rules/no-unreadable-iife.md\n \"unicorn/no-unreadable-iife\": \"error\",\n\n // Require Error messages — aids debugging\n // https://github.com/sindresorhus/eslint-plugin-unicorn/blob/main/docs/rules/error-message.md\n \"unicorn/error-message\": \"error\",\n\n // Require `new` keyword when throwing errors — consistent pattern\n // https://github.com/sindresorhus/eslint-plugin-unicorn/blob/main/docs/rules/throw-new-error.md\n \"unicorn/throw-new-error\": \"error\",\n\n // Prefer consistent types when spreading a ternary in an array literal\n // https://github.com/sindresorhus/eslint-plugin-unicorn/blob/main/docs/rules/consistent-empty-array-spread.md\n \"unicorn/consistent-empty-array-spread\": \"error\",\n\n // Prefer passing Date directly to constructor when cloning\n // https://github.com/sindresorhus/eslint-plugin-unicorn/blob/main/docs/rules/consistent-date-clone.md\n \"unicorn/consistent-date-clone\": \"error\",\n\n // Enforce consistent style for indexOf/findIndex existence checks\n // https://github.com/sindresorhus/eslint-plugin-unicorn/blob/main/docs/rules/consistent-existence-index-check.md\n \"unicorn/consistent-existence-index-check\": \"error\",\n\n // Move functions to the smallest possible scope — avoids re-creation on every call,\n // improves testability, and makes dependencies explicit\n // https://github.com/sindresorhus/eslint-plugin-unicorn/blob/main/docs/rules/consistent-function-scoping.md\n \"unicorn/consistent-function-scoping\": \"warn\",\n\n // Enforce consistent filename casing — camelCase, PascalCase, or kebab-case (no snake_case)\n // https://github.com/sindresorhus/eslint-plugin-unicorn/blob/main/docs/rules/filename-case.md\n \"unicorn/filename-case\": [\n \"error\",\n {\n cases: {\n camelCase: true,\n pascalCase: true,\n kebabCase: true,\n },\n ignore: [\"__tests__\"],\n },\n ],\n\n // Discourage Array.reduce() — hard to read for many developers, prefer for...of or other methods\n // https://github.com/sindresorhus/eslint-plugin-unicorn/blob/main/docs/rules/no-array-reduce.md\n \"unicorn/no-array-reduce\": \"warn\",\n\n // Prefer for...of over C-style for loops — more readable when index isn't needed\n // https://github.com/sindresorhus/eslint-plugin-unicorn/blob/main/docs/rules/no-for-loop.md\n \"unicorn/no-for-loop\": \"warn\",\n\n // ── Modern API preferences ────────────────────────────────────\n\n // Prefer .flatMap() over .map().flat() — single pass, more readable\n // https://github.com/sindresorhus/eslint-plugin-unicorn/blob/main/docs/rules/prefer-array-flat-map.md\n \"unicorn/prefer-array-flat-map\": \"error\",\n\n // Prefer .find() over .filter()[0] — stops at first match\n // https://github.com/sindresorhus/eslint-plugin-unicorn/blob/main/docs/rules/prefer-array-find.md\n \"unicorn/prefer-array-find\": \"error\",\n\n // Prefer .flat() over manual recursive flattening\n // https://github.com/sindresorhus/eslint-plugin-unicorn/blob/main/docs/rules/prefer-array-flat.md\n \"unicorn/prefer-array-flat\": \"error\",\n\n // Prefer .indexOf() over manual search loops\n // https://github.com/sindresorhus/eslint-plugin-unicorn/blob/main/docs/rules/prefer-array-index-of.md\n \"unicorn/prefer-array-index-of\": \"error\",\n\n // Prefer .some() over .find() !== undefined — semantic intent\n // https://github.com/sindresorhus/eslint-plugin-unicorn/blob/main/docs/rules/prefer-array-some.md\n \"unicorn/prefer-array-some\": \"error\",\n\n // Prefer .at(-1) over arr[arr.length - 1] — cleaner negative indexing\n // https://github.com/sindresorhus/eslint-plugin-unicorn/blob/main/docs/rules/prefer-at.md\n \"unicorn/prefer-at\": \"error\",\n\n // Prefer .includes() over .indexOf() !== -1 — boolean intent\n // https://github.com/sindresorhus/eslint-plugin-unicorn/blob/main/docs/rules/prefer-includes.md\n \"unicorn/prefer-includes\": \"error\",\n\n // Prefer .before()/.after()/.replaceWith() over parent.insertBefore()\n // https://github.com/sindresorhus/eslint-plugin-unicorn/blob/main/docs/rules/prefer-modern-dom-apis.md\n \"unicorn/prefer-modern-dom-apis\": \"error\",\n\n // Prefer element.dataset.foo over setAttribute('data-foo') — modern, readable\n // https://github.com/sindresorhus/eslint-plugin-unicorn/blob/main/docs/rules/prefer-dom-node-dataset.md\n \"unicorn/prefer-dom-node-dataset\": \"error\",\n\n // Prefer Math.log10/Math.hypot over manual math — accurate and readable\n // https://github.com/sindresorhus/eslint-plugin-unicorn/blob/main/docs/rules/prefer-modern-math-apis.md\n \"unicorn/prefer-modern-math-apis\": \"error\",\n\n // Prefer negative index over length-based — cleaner with .slice(-n)\n // https://github.com/sindresorhus/eslint-plugin-unicorn/blob/main/docs/rules/prefer-negative-index.md\n \"unicorn/prefer-negative-index\": \"error\",\n\n // Prefer Number.isFinite/Number.isNaN over global — no coercion\n // https://github.com/sindresorhus/eslint-plugin-unicorn/blob/main/docs/rules/prefer-number-properties.md\n \"unicorn/prefer-number-properties\": \"error\",\n\n // Prefer Object.fromEntries() over manual reduce for key-value mapping\n // https://github.com/sindresorhus/eslint-plugin-unicorn/blob/main/docs/rules/prefer-object-from-entries.md\n \"unicorn/prefer-object-from-entries\": \"error\",\n\n // Prefer Set.has() over Array.includes() for repeated lookups — O(1)\n // https://github.com/sindresorhus/eslint-plugin-unicorn/blob/main/docs/rules/prefer-set-has.md\n \"unicorn/prefer-set-has\": \"error\",\n\n // Prefer .replaceAll() over regex with global flag — clearer intent\n // https://github.com/sindresorhus/eslint-plugin-unicorn/blob/main/docs/rules/prefer-string-replace-all.md\n \"unicorn/prefer-string-replace-all\": \"error\",\n\n // Prefer .slice() over .substr()/.substring() — consistent, no gotchas\n // https://github.com/sindresorhus/eslint-plugin-unicorn/blob/main/docs/rules/prefer-string-slice.md\n \"unicorn/prefer-string-slice\": \"error\",\n\n // Prefer .startsWith()/.endsWith() over regex — simpler, faster\n // https://github.com/sindresorhus/eslint-plugin-unicorn/blob/main/docs/rules/prefer-string-starts-ends-with.md\n \"unicorn/prefer-string-starts-ends-with\": \"error\",\n\n // Prefer .trimStart()/.trimEnd() over .trimLeft()/.trimRight()\n // https://github.com/sindresorhus/eslint-plugin-unicorn/blob/main/docs/rules/prefer-string-trim-start-end.md\n \"unicorn/prefer-string-trim-start-end\": \"error\",\n\n // Prefer structuredClone() over JSON.parse(JSON.stringify()) — handles more types\n // https://github.com/sindresorhus/eslint-plugin-unicorn/blob/main/docs/rules/prefer-structured-clone.md\n \"unicorn/prefer-structured-clone\": \"error\",\n\n // Prefer top-level await over async IIFE — cleaner module pattern\n // https://github.com/sindresorhus/eslint-plugin-unicorn/blob/main/docs/rules/prefer-top-level-await.md\n \"unicorn/prefer-top-level-await\": \"error\",\n\n // Throw TypeError for type checks — correct error type\n // https://github.com/sindresorhus/eslint-plugin-unicorn/blob/main/docs/rules/prefer-type-error.md\n \"unicorn/prefer-type-error\": \"error\",\n\n // ── Regex ─────────────────────────────────────────────────────\n\n // Disabled — conflicts with regexp/strict from eslint-plugin-regexp.\n // Both rules auto-fix regex escaping but disagree on whether characters\n // like { } ] should be escaped, causing circular fixes.\n // regexp/strict is the more thorough rule, so we defer to it.\n \"unicorn/better-regex\": \"off\",\n\n // ── Misc ──────────────────────────────────────────────────────\n\n // Enforce `error` name in catch blocks — consistent naming\n // https://github.com/sindresorhus/eslint-plugin-unicorn/blob/main/docs/rules/catch-error-name.md\n \"unicorn/catch-error-name\": [\"error\", { name: \"error\" }],\n\n // Enforce `new` for builtins that require it (Map, Set, WeakMap, etc.)\n // https://github.com/sindresorhus/eslint-plugin-unicorn/blob/main/docs/rules/new-for-builtins.md\n \"unicorn/new-for-builtins\": \"error\",\n\n // Prefer Array.from({length}) or fill() over new Array(n) — explicit intent\n // https://github.com/sindresorhus/eslint-plugin-unicorn/blob/main/docs/rules/no-new-array.md\n \"unicorn/no-new-array\": \"error\",\n\n // Prefer Buffer.from()/Buffer.alloc() over new Buffer() — deprecated\n // https://github.com/sindresorhus/eslint-plugin-unicorn/blob/main/docs/rules/no-new-buffer.md\n \"unicorn/no-new-buffer\": \"error\",\n\n // Forbid unreadable destructuring like `const [,,, d] = arr`\n // https://github.com/sindresorhus/eslint-plugin-unicorn/blob/main/docs/rules/no-unreadable-array-destructuring.md\n \"unicorn/no-unreadable-array-destructuring\": \"error\",\n\n // Remove unnecessary `.0` in numbers (1.0 → 1) — cleaner\n // https://github.com/sindresorhus/eslint-plugin-unicorn/blob/main/docs/rules/no-zero-fractions.md\n \"unicorn/no-zero-fractions\": \"error\",\n\n // Enforce lowercase hex (0xff not 0xFF) — consistent\n // https://github.com/sindresorhus/eslint-plugin-unicorn/blob/main/docs/rules/number-literal-case.md\n \"unicorn/number-literal-case\": \"error\",\n\n // Enforce numeric separators (1_000_000 not 1000000) — readable large numbers\n // https://github.com/sindresorhus/eslint-plugin-unicorn/blob/main/docs/rules/numeric-separators-style.md\n \"unicorn/numeric-separators-style\": \"error\",\n\n // Prefer `export { x } from 'y'` over import then re-export\n // https://github.com/sindresorhus/eslint-plugin-unicorn/blob/main/docs/rules/prefer-export-from.md\n \"unicorn/prefer-export-from\": [\"error\", { checkUsedVariables: false }],\n\n // Prefer built-in coercion (String, Number, Boolean) over wrapper functions\n // https://github.com/sindresorhus/eslint-plugin-unicorn/blob/main/docs/rules/prefer-native-coercion-functions.md\n \"unicorn/prefer-native-coercion-functions\": \"error\",\n\n // Prefer .test() over .match() for boolean regex checks\n // https://github.com/sindresorhus/eslint-plugin-unicorn/blob/main/docs/rules/prefer-regexp-test.md\n \"unicorn/prefer-regexp-test\": \"error\",\n\n // Prefer [...iterable] spread over Array.from(iterable) — concise\n // https://github.com/sindresorhus/eslint-plugin-unicorn/blob/main/docs/rules/prefer-spread.md\n \"unicorn/prefer-spread\": \"error\",\n\n // Prefer relative URLs over absolute same-origin URLs\n // https://github.com/sindresorhus/eslint-plugin-unicorn/blob/main/docs/rules/relative-url-style.md\n \"unicorn/relative-url-style\": \"error\",\n\n // Prefer `node:fs` over `fs` — explicit built-in module protocol\n // https://github.com/sindresorhus/eslint-plugin-unicorn/blob/main/docs/rules/prefer-node-protocol.md\n \"unicorn/prefer-node-protocol\": \"error\",\n\n // Prefer `globalThis` over `window`/`self`/`global` — universal\n // https://github.com/sindresorhus/eslint-plugin-unicorn/blob/main/docs/rules/prefer-global-this.md\n \"unicorn/prefer-global-this\": \"error\",\n\n // Prefer omitting unused catch binding — cleaner syntax\n // https://github.com/sindresorhus/eslint-plugin-unicorn/blob/main/docs/rules/prefer-optional-catch-binding.md\n \"unicorn/prefer-optional-catch-binding\": \"error\",\n\n // Prefer `Date.now()` over `new Date().getTime()` — direct and readable\n // https://github.com/sindresorhus/eslint-plugin-unicorn/blob/main/docs/rules/prefer-date-now.md\n \"unicorn/prefer-date-now\": \"error\",\n\n // Enforce consistent `utf-8` casing for text encoding identifiers\n // https://github.com/sindresorhus/eslint-plugin-unicorn/blob/main/docs/rules/text-encoding-identifier-case.md\n \"unicorn/text-encoding-identifier-case\": \"error\",\n\n // Prefer `import.meta.url`/`import.meta.dirname` over `__filename`/`__dirname`\n // https://github.com/sindresorhus/eslint-plugin-unicorn/blob/main/docs/rules/prefer-import-meta-properties.md\n \"unicorn/prefer-import-meta-properties\": \"error\",\n\n // OFF: Sequential .push() is natural in codegen and conditional builders.\n // No real performance benefit in modern V8 — purely stylistic.\n // https://github.com/sindresorhus/eslint-plugin-unicorn/blob/main/docs/rules/prefer-single-call.md\n \"unicorn/prefer-single-call\": \"off\",\n },\n }],\n })\n\n if (isAi) {\n // Severity overrides: promote existing base rules from warn to error\n builder.overrideSeverity(\"unicorn/consistent-function-scoping\", \"error\")\n builder.overrideSeverity(\"unicorn/no-array-reduce\", \"error\")\n builder.overrideSeverity(\"unicorn/no-for-loop\", \"error\")\n\n // New AI-only rules\n builder.addRule(\"unicorn/no-for-each\", \"error\")\n builder.addRule(\"unicorn/prefer-ternary\", [\"error\", \"only-single-line\"])\n builder.addRule(\"unicorn/prefer-switch\", [\"error\", { minimumCases: 3 }])\n builder.addRule(\"unicorn/no-useless-switch-case\", \"error\")\n builder.addRule(\"unicorn/custom-error-definition\", \"error\")\n builder.addRule(\"unicorn/prefer-default-parameters\", \"error\")\n builder.addRule(\"unicorn/prefer-logical-operator-over-ternary\", \"error\")\n builder.addRule(\"unicorn/prefer-math-min-max\", \"error\")\n builder.addRule(\"unicorn/prefer-set-size\", \"error\")\n builder.addRule(\"unicorn/explicit-length-check\", \"error\")\n builder.addRule(\"unicorn/switch-case-braces\", \"error\")\n builder.addRule(\"unicorn/no-array-push-push\", \"error\")\n }\n\n return builder.build()\n}\n","import type { FlatConfigArray } from \"../types\"\n\n/**\n * Config file overrides — relaxed rules for tool configuration files.\n * Config files (vite, vitest, next, tailwind, postcss) have their own\n * patterns that conflict with strict app-code rules.\n *\n * File patterns: *.config.*, vite.config.*, vitest.config.*, etc.\n */\nexport function configFilesOverride(): FlatConfigArray {\n return [\n {\n name: \"eslint-config-setup/config-files\",\n files: [\n \"**/*.config.{ts,mts,cts,js,mjs,cjs}\",\n \"**/vite.config.*\",\n \"**/vitest.config.*\",\n \"**/next.config.*\",\n \"**/tailwind.config.*\",\n \"**/postcss.config.*\",\n ],\n rules: {\n // Config files often require default exports (Vite, Next.js, Tailwind)\n \"import/no-default-export\": \"off\",\n\n // Config files can have complex configuration objects\n complexity: \"off\",\n \"max-lines\": \"off\",\n \"max-lines-per-function\": \"off\",\n \"max-statements\": \"off\",\n\n // Config files may use require() for dynamic plugin loading\n \"@typescript-eslint/no-require-imports\": \"off\",\n\n // Config files may log build info to console\n \"no-console\": \"off\",\n\n // Config files often have magic numbers (ports, sizes, timeouts)\n \"no-magic-numbers\": \"off\",\n \"@typescript-eslint/no-magic-numbers\": \"off\",\n },\n },\n ]\n}\n","import type { FlatConfigArray } from \"../types\"\n\n/**\n * Declaration file overrides — minimal rules for `.d.ts` files.\n * Declaration files follow their own patterns (ambient declarations,\n * interface merging, namespaces) that conflict with app-code rules.\n *\n * File pattern: *.d.ts files\n */\nexport function declarationsOverride(): FlatConfigArray {\n return [\n {\n name: \"eslint-config-setup/declarations\",\n files: [\"**/*.d.ts\"],\n rules: {\n // Declaration files often have unused type parameters/variables\n \"@typescript-eslint/no-unused-vars\": \"off\",\n\n // Empty interfaces are valid for declaration merging\n \"@typescript-eslint/no-empty-interface\": \"off\",\n\n // Empty object types are used for extensible interfaces\n \"@typescript-eslint/no-empty-object-type\": \"off\",\n\n // `any` is sometimes necessary in third-party type declarations\n \"@typescript-eslint/no-explicit-any\": \"off\",\n\n // Both `type` and `interface` are valid in declarations\n \"@typescript-eslint/consistent-type-definitions\": \"off\",\n\n // Namespaces are standard in ambient declarations\n \"@typescript-eslint/no-namespace\": \"off\",\n\n // Duplicate imports happen with declaration merging\n \"import/no-duplicates\": \"off\",\n\n // Unused imports are common in re-export declaration files\n \"unused-imports/no-unused-imports\": \"off\",\n\n // ── AI mode rules that don't apply to declaration files ────────\n\n // Declarations inherit return types from the implementation\n \"@typescript-eslint/explicit-function-return-type\": \"off\",\n\n // Third-party naming conventions must be followed as-is\n \"@typescript-eslint/naming-convention\": \"off\",\n\n // Abbreviations in third-party types are unavoidable\n \"unicorn/prevent-abbreviations\": \"off\",\n\n // .d.ts filename is dictated by the module it declares\n \"unicorn/filename-case\": \"off\",\n },\n },\n ]\n}\n","import playwrightPlugin from \"eslint-plugin-playwright\"\n\nimport type { FlatConfigArray } from \"../types\"\n\n/**\n * E2E test overrides — Playwright rules + relaxed strictness for E2E tests.\n *\n * File pattern: *.spec.ts (Playwright convention)\n *\n * @see https://github.com/playwright-community/eslint-plugin-playwright#rules\n */\nexport function e2eOverride(): FlatConfigArray {\n return [\n {\n name: \"eslint-config-setup/e2e\",\n files: [\"**/*.spec.ts\"],\n plugins: {\n playwright: playwrightPlugin,\n },\n rules: {\n // ── Playwright rules ──────────────────────────────────────────\n\n // Every test must contain at least one expect()\n // https://github.com/playwright-community/eslint-plugin-playwright/blob/main/docs/rules/expect-expect.md\n \"playwright/expect-expect\": \"error\",\n\n // Limit describe nesting to 3 levels — keeps tests readable\n // https://github.com/playwright-community/eslint-plugin-playwright/blob/main/docs/rules/max-nested-describe.md\n \"playwright/max-nested-describe\": [\"error\", { max: 3 }],\n\n // Detect missing await on Playwright async methods — common mistake\n // https://github.com/playwright-community/eslint-plugin-playwright/blob/main/docs/rules/missing-playwright-await.md\n \"playwright/missing-playwright-await\": \"error\",\n\n // No expect() inside conditionals — tests should be deterministic\n // https://github.com/playwright-community/eslint-plugin-playwright/blob/main/docs/rules/no-conditional-expect.md\n \"playwright/no-conditional-expect\": \"error\",\n\n // Warn on conditional logic in tests — tests should be linear\n // https://github.com/playwright-community/eslint-plugin-playwright/blob/main/docs/rules/no-conditional-in-test.md\n \"playwright/no-conditional-in-test\": \"warn\",\n\n // Prefer locators over element handles — auto-retry, less flaky\n // https://github.com/playwright-community/eslint-plugin-playwright/blob/main/docs/rules/no-element-handle.md\n \"playwright/no-element-handle\": \"error\",\n\n // No page.evaluate with arbitrary code — brittle, hard to debug\n // https://github.com/playwright-community/eslint-plugin-playwright/blob/main/docs/rules/no-eval.md\n \"playwright/no-eval\": \"error\",\n\n // No test.only — prevents accidentally skipping tests in CI\n // https://github.com/playwright-community/eslint-plugin-playwright/blob/main/docs/rules/no-focused-test.md\n \"playwright/no-focused-test\": \"error\",\n\n // Warn on { force: true } — bypasses visibility/actionability checks\n // https://github.com/playwright-community/eslint-plugin-playwright/blob/main/docs/rules/no-force-option.md\n \"playwright/no-force-option\": \"warn\",\n\n // No waitUntil: \"networkidle\" — unreliable, use specific waits\n // https://github.com/playwright-community/eslint-plugin-playwright/blob/main/docs/rules/no-networkidle.md\n \"playwright/no-networkidle\": \"error\",\n\n // No page.pause() — debugging artifact, breaks CI\n // https://github.com/playwright-community/eslint-plugin-playwright/blob/main/docs/rules/no-page-pause.md\n \"playwright/no-page-pause\": \"error\",\n\n // Warn on test.skip — track disabled tests\n // https://github.com/playwright-community/eslint-plugin-playwright/blob/main/docs/rules/no-skipped-test.md\n \"playwright/no-skipped-test\": \"warn\",\n\n // No unnecessary await on non-promise values\n // https://github.com/playwright-community/eslint-plugin-playwright/blob/main/docs/rules/no-useless-await.md\n \"playwright/no-useless-await\": \"error\",\n\n // No double-negative assertions: expect(x).not.not...\n // https://github.com/playwright-community/eslint-plugin-playwright/blob/main/docs/rules/no-useless-not.md\n \"playwright/no-useless-not\": \"error\",\n\n // Warn on waitForSelector — prefer locators with auto-wait\n // https://github.com/playwright-community/eslint-plugin-playwright/blob/main/docs/rules/no-wait-for-selector.md\n \"playwright/no-wait-for-selector\": \"warn\",\n\n // No hardcoded timeouts — use Playwright's built-in waiting\n // https://github.com/playwright-community/eslint-plugin-playwright/blob/main/docs/rules/no-wait-for-timeout.md\n \"playwright/no-wait-for-timeout\": \"error\",\n\n // Prefer web-first assertions (toBeVisible, toHaveText) — auto-retry\n // https://github.com/playwright-community/eslint-plugin-playwright/blob/main/docs/rules/prefer-web-first-assertions.md\n \"playwright/prefer-web-first-assertions\": \"error\",\n\n // Validate expect() usage — proper matcher and argument count\n // https://github.com/playwright-community/eslint-plugin-playwright/blob/main/docs/rules/valid-expect.md\n \"playwright/valid-expect\": \"error\",\n\n // ── Relaxed rules for E2E tests ───────────────────────────────\n // E2E tests are long procedural scripts with many page interactions\n\n \"max-lines\": \"off\",\n \"max-lines-per-function\": \"off\",\n \"max-statements\": \"off\",\n },\n },\n ]\n}\n","import type { FlatConfigArray } from \"../types\"\n\n/**\n * Script file overrides — relaxed rules for build/dev scripts.\n * Scripts are CLI tools that legitimately use console.log and process.exit.\n *\n * File pattern: scripts dir (*.ts, *.mts, *.js, *.mjs)\n */\nexport function scriptsOverride(): FlatConfigArray {\n return [\n {\n name: \"eslint-config-setup/scripts\",\n files: [\"**/scripts/**/*.{ts,mts,js,mjs}\"],\n rules: {\n // Scripts use console for user-facing output\n \"no-console\": \"off\",\n\n // Scripts use process.exit for clean termination\n // https://github.com/eslint-community/eslint-plugin-n/blob/master/docs/rules/no-process-exit.md\n \"node/no-process-exit\": \"off\",\n\n // Scripts can be long (build pipelines, code generators)\n \"max-lines\": \"off\",\n \"max-lines-per-function\": \"off\",\n\n // Scripts are often procedural without explicit return types\n \"@typescript-eslint/explicit-function-return-type\": \"off\",\n\n // Scripts legitimately call process.exit()\n // https://github.com/sindresorhus/eslint-plugin-unicorn/blob/main/docs/rules/no-process-exit.md\n \"unicorn/no-process-exit\": \"off\",\n },\n },\n ]\n}\n","import storybookPlugin from \"eslint-plugin-storybook\"\n\nimport type { FlatConfigArray } from \"../types\"\n\n/**\n * Storybook overrides — Storybook best-practice rules for story files.\n *\n * File pattern: *.stories.{ts,tsx}\n *\n * @see https://github.com/storybookjs/eslint-plugin-storybook#supported-rules\n */\nexport function storiesOverride(): FlatConfigArray {\n return [\n {\n name: \"eslint-config-setup/stories\",\n files: [\"**/*.stories.{ts,tsx}\"],\n plugins: {\n storybook: storybookPlugin as Record<string, unknown>,\n },\n rules: {\n // ── Storybook rules ───────────────────────────────────────────\n\n // Await play function interactions — prevents race conditions\n // https://github.com/storybookjs/eslint-plugin-storybook/blob/main/docs/rules/await-interactions.md\n \"storybook/await-interactions\": \"error\",\n\n // Stories must have a default export (meta) — Storybook requirement\n // https://github.com/storybookjs/eslint-plugin-storybook/blob/main/docs/rules/default-exports.md\n \"storybook/default-exports\": \"error\",\n\n // Use / for hierarchy separators, not | or . — Storybook 7+ convention\n // https://github.com/storybookjs/eslint-plugin-storybook/blob/main/docs/rules/hierarchy-separator.md\n \"storybook/hierarchy-separator\": \"error\",\n\n // No redundant story names that match export name — DRY\n // https://github.com/storybookjs/eslint-plugin-storybook/blob/main/docs/rules/no-redundant-story-name.md\n \"storybook/no-redundant-story-name\": \"error\",\n\n // No deprecated storiesOf() API — use CSF (Component Story Format)\n // https://github.com/storybookjs/eslint-plugin-storybook/blob/main/docs/rules/no-stories-of.md\n \"storybook/no-stories-of\": \"error\",\n\n // Warn if title is in meta — auto-title is preferred in CSF 3\n // https://github.com/storybookjs/eslint-plugin-storybook/blob/main/docs/rules/no-title-property-in-meta.md\n \"storybook/no-title-property-in-meta\": \"warn\",\n\n // Story exports should be PascalCase — component naming convention\n // https://github.com/storybookjs/eslint-plugin-storybook/blob/main/docs/rules/prefer-pascal-case.md\n \"storybook/prefer-pascal-case\": \"error\",\n\n // File must export at least one story — prevents empty story files\n // https://github.com/storybookjs/eslint-plugin-storybook/blob/main/docs/rules/story-exports.md\n \"storybook/story-exports\": \"error\",\n\n // Use Storybook's expect() instead of Jest/Vitest in play functions\n // https://github.com/storybookjs/eslint-plugin-storybook/blob/main/docs/rules/use-storybook-expect.md\n \"storybook/use-storybook-expect\": \"error\",\n\n // Use Storybook's Testing Library, not direct import\n // https://github.com/storybookjs/eslint-plugin-storybook/blob/main/docs/rules/use-storybook-testing-library.md\n \"storybook/use-storybook-testing-library\": \"error\",\n\n // Enforce `satisfies Meta<typeof Component>` on default export — type-safe meta\n // https://github.com/storybookjs/eslint-plugin-storybook/blob/main/docs/rules/meta-satisfies-type.md\n \"storybook/meta-satisfies-type\": \"error\",\n\n // ── Relaxed rules for stories ─────────────────────────────────\n\n // Stories require default exports (meta object)\n \"import/no-default-export\": \"off\",\n\n // Stories can be long (many variants of a component)\n \"max-lines\": \"off\",\n \"max-lines-per-function\": \"off\",\n },\n },\n ]\n}\n","import type { Linter } from \"eslint\"\n\nimport vitestPlugin from \"@vitest/eslint-plugin\"\nimport testingLibraryPlugin from \"eslint-plugin-testing-library\"\n\nimport type { FlatConfigArray } from \"../types\"\n\nconst TEST_FILES = [\"**/*.test.{ts,tsx}\", \"**/__tests__/**/*.{ts,tsx}\"]\n\nconst VITEST_RULES: Linter.RulesRecord = {\n // ── Vitest rules ──────────────────────────────────────────────\n\n // Every test must contain at least one assertion\n // https://github.com/vitest-dev/eslint-plugin-vitest/blob/main/docs/rules/expect-expect.md\n \"vitest/expect-expect\": \"error\",\n\n // Prevent duplicate test titles within a describe block\n // https://github.com/vitest-dev/eslint-plugin-vitest/blob/main/docs/rules/no-identical-title.md\n \"vitest/no-identical-title\": \"error\",\n\n // No it.only / describe.only — prevents accidentally skipping tests in CI\n // https://github.com/vitest-dev/eslint-plugin-vitest/blob/main/docs/rules/no-focused-tests.md\n \"vitest/no-focused-tests\": \"error\",\n\n // Warn on it.skip / describe.skip — track disabled tests\n // https://github.com/vitest-dev/eslint-plugin-vitest/blob/main/docs/rules/no-disabled-tests.md\n \"vitest/no-disabled-tests\": \"warn\",\n\n // No duplicate beforeEach/afterEach hooks — merge them\n // https://github.com/vitest-dev/eslint-plugin-vitest/blob/main/docs/rules/no-duplicate-hooks.md\n \"vitest/no-duplicate-hooks\": \"error\",\n\n // Prefer .toBe() over .toEqual() for primitives — clearer intent\n // https://github.com/vitest-dev/eslint-plugin-vitest/blob/main/docs/rules/prefer-to-be.md\n \"vitest/prefer-to-be\": \"error\",\n\n // Prefer .toHaveLength() over .toBe(arr.length) — better errors\n // https://github.com/vitest-dev/eslint-plugin-vitest/blob/main/docs/rules/prefer-to-have-length.md\n \"vitest/prefer-to-have-length\": \"error\",\n\n // Validate expect() usage — no dangling expect without assertion\n // https://github.com/vitest-dev/eslint-plugin-vitest/blob/main/docs/rules/valid-expect.md\n \"vitest/valid-expect\": \"error\",\n\n // Validate test/describe title format — no empty or invalid titles\n // https://github.com/vitest-dev/eslint-plugin-vitest/blob/main/docs/rules/valid-title.md\n \"vitest/valid-title\": \"error\",\n\n // No conditional logic (if/else) inside tests — split into separate tests\n // https://github.com/vitest-dev/eslint-plugin-vitest/blob/main/docs/rules/no-conditional-in-test.md\n \"vitest/no-conditional-in-test\": \"error\",\n\n // No expect() inside conditional blocks — always assert unconditionally\n // https://github.com/vitest-dev/eslint-plugin-vitest/blob/main/docs/rules/no-conditional-expect.md\n \"vitest/no-conditional-expect\": \"error\",\n\n // No standalone expect() outside test blocks — always wrap in it/test\n // https://github.com/vitest-dev/eslint-plugin-vitest/blob/main/docs/rules/no-standalone-expect.md\n \"vitest/no-standalone-expect\": \"error\",\n\n // Prefer .toStrictEqual() over .toEqual() — catches undefined vs missing\n // https://github.com/vitest-dev/eslint-plugin-vitest/blob/main/docs/rules/prefer-strict-equal.md\n \"vitest/prefer-strict-equal\": \"error\",\n\n // Prefer vi.spyOn() over vi.fn() for method mocks — preserves original\n // https://github.com/vitest-dev/eslint-plugin-vitest/blob/main/docs/rules/prefer-spy-on.md\n \"vitest/prefer-spy-on\": \"error\",\n\n // Require message argument in toThrow/toThrowError — verify correct error\n // https://github.com/vitest-dev/eslint-plugin-vitest/blob/main/docs/rules/require-to-throw-message.md\n \"vitest/require-to-throw-message\": \"error\",\n\n // ── Relaxed rules for tests ───────────────────────────────────\n // Tests are naturally verbose and use patterns banned in prod code\n\n // Tests can be long (setup + many assertions)\n \"max-lines\": \"off\",\n \"max-lines-per-function\": \"off\",\n \"max-statements\": \"off\",\n\n // Tests often need `any` for mocking and type assertions\n \"@typescript-eslint/no-explicit-any\": \"off\",\n \"@typescript-eslint/no-non-null-assertion\": \"off\",\n \"@typescript-eslint/no-unsafe-assignment\": \"off\",\n \"@typescript-eslint/no-unsafe-member-access\": \"off\",\n}\n\nconst TESTING_LIBRARY_RULES: Linter.RulesRecord = {\n // ── Testing Library rules ───────────────────────────────────\n\n // Await async events (userEvent.click, etc.) — prevents race conditions\n // https://github.com/testing-library/eslint-plugin-testing-library/blob/main/docs/rules/await-async-events.md\n \"testing-library/await-async-events\": \"error\",\n\n // Await async queries (findBy*) — they return promises\n // https://github.com/testing-library/eslint-plugin-testing-library/blob/main/docs/rules/await-async-queries.md\n \"testing-library/await-async-queries\": \"error\",\n\n // Await async utilities (waitFor, waitForElementToBeRemoved)\n // https://github.com/testing-library/eslint-plugin-testing-library/blob/main/docs/rules/await-async-utils.md\n \"testing-library/await-async-utils\": \"error\",\n\n // Don't await synchronous events — misleading\n // https://github.com/testing-library/eslint-plugin-testing-library/blob/main/docs/rules/no-await-sync-events.md\n \"testing-library/no-await-sync-events\": \"error\",\n\n // Don't await synchronous queries (getBy*, queryBy*) — not promises\n // https://github.com/testing-library/eslint-plugin-testing-library/blob/main/docs/rules/no-await-sync-queries.md\n \"testing-library/no-await-sync-queries\": \"error\",\n\n // Don't use container.querySelector — use queries instead\n // https://github.com/testing-library/eslint-plugin-testing-library/blob/main/docs/rules/no-container.md\n \"testing-library/no-container\": \"error\",\n\n // Warn on debug()/prettyDOM() left in tests — debugging artifacts\n // https://github.com/testing-library/eslint-plugin-testing-library/blob/main/docs/rules/no-debugging-utils.md\n \"testing-library/no-debugging-utils\": \"warn\",\n\n // Don't access DOM nodes directly — use queries\n // https://github.com/testing-library/eslint-plugin-testing-library/blob/main/docs/rules/no-node-access.md\n \"testing-library/no-node-access\": \"error\",\n\n // Don't call render in beforeEach — call in each test\n // https://github.com/testing-library/eslint-plugin-testing-library/blob/main/docs/rules/no-render-in-lifecycle.md\n \"testing-library/no-render-in-lifecycle\": \"error\",\n\n // No unnecessary act() wrappers — TL handles this internally\n // https://github.com/testing-library/eslint-plugin-testing-library/blob/main/docs/rules/no-unnecessary-act.md\n \"testing-library/no-unnecessary-act\": \"error\",\n\n // One assertion per waitFor — multiple can mask failures\n // https://github.com/testing-library/eslint-plugin-testing-library/blob/main/docs/rules/no-wait-for-multiple-assertions.md\n \"testing-library/no-wait-for-multiple-assertions\": \"error\",\n\n // No side effects in waitFor — only assertions\n // https://github.com/testing-library/eslint-plugin-testing-library/blob/main/docs/rules/no-wait-for-side-effects.md\n \"testing-library/no-wait-for-side-effects\": \"error\",\n\n // Prefer findBy* over waitFor + getBy* — built-in combination\n // https://github.com/testing-library/eslint-plugin-testing-library/blob/main/docs/rules/prefer-find-by.md\n \"testing-library/prefer-find-by\": \"error\",\n\n // Use getBy* (throws) for present elements, queryBy* for absent\n // https://github.com/testing-library/eslint-plugin-testing-library/blob/main/docs/rules/prefer-presence-queries.md\n \"testing-library/prefer-presence-queries\": \"error\",\n\n // Use queryBy* for disappearance checks — returns null when gone\n // https://github.com/testing-library/eslint-plugin-testing-library/blob/main/docs/rules/prefer-query-by-disappearance.md\n \"testing-library/prefer-query-by-disappearance\": \"error\",\n\n // Use screen.getBy* over destructured render result — consistent\n // https://github.com/testing-library/eslint-plugin-testing-library/blob/main/docs/rules/prefer-screen-queries.md\n \"testing-library/prefer-screen-queries\": \"error\",\n\n // Name render result consistently (e.g., `const { getByText } = render(...)`)\n // https://github.com/testing-library/eslint-plugin-testing-library/blob/main/docs/rules/render-result-naming-convention.md\n \"testing-library/render-result-naming-convention\": \"error\",\n}\n\n/**\n * Test file overrides — Vitest rules + Testing Library + relaxed strictness.\n *\n * File patterns: *.test.{ts,tsx}, __tests__/*.{ts,tsx}\n *\n * @see https://github.com/vitest-dev/eslint-plugin-vitest#rules\n * @see https://github.com/testing-library/eslint-plugin-testing-library#supported-rules\n */\nexport function testsOverride(): FlatConfigArray {\n return [\n {\n name: \"eslint-config-setup/tests\",\n files: TEST_FILES,\n plugins: {\n vitest: vitestPlugin,\n },\n rules: VITEST_RULES,\n },\n {\n name: \"eslint-config-setup/tests-testing-library\",\n files: TEST_FILES,\n plugins: {\n \"testing-library\": testingLibraryPlugin,\n },\n rules: TESTING_LIBRARY_RULES,\n },\n ]\n}\n","import oxlintPlugin from \"eslint-plugin-oxlint\"\n\nimport type { ConfigOptions, FlatConfig, FlatConfigArray } from \"../types\"\n\n// eslint-disable-next-line @typescript-eslint/no-unsafe-type-assertion -- Typing the oxlint plugin's config shape\nconst typedPlugin = oxlintPlugin as unknown as {\n configs: Record<string, FlatConfig | FlatConfig[]>\n}\n\nfunction addOxlintConfig(\n configs: FlatConfigArray,\n configName: string,\n blockName: string,\n): void {\n const raw = typedPlugin.configs[configName]\n const items = Array.isArray(raw) ? raw : [raw]\n for (const [index, item] of items.entries()) {\n const suffix = items.length > 1 ? `-${index + 1}` : \"\"\n configs.push({ ...item, name: `eslint-config-setup/${blockName}${suffix}` })\n }\n}\n\nfunction addReactOxlintConfigs(\n configs: FlatConfigArray,\n opts: ConfigOptions,\n): void {\n if (!opts.react) {\n return\n }\n\n addOxlintConfig(configs, \"flat/react\", \"oxlint-react\")\n addOxlintConfig(configs, \"flat/jsx-a11y\", \"oxlint-jsx-a11y\")\n addOxlintConfig(configs, \"flat/react-hooks\", \"oxlint-react-hooks\")\n if (opts.ai) {\n addOxlintConfig(configs, \"flat/react-perf\", \"oxlint-react-perf\")\n }\n}\n\n/**\n * Appends eslint-plugin-oxlint configs that disable all ESLint rules\n * already covered by OxLint. Must be the LAST config in the array.\n *\n * This allows running `oxlint && eslint` where OxLint handles the fast\n * checks and ESLint only runs type-aware and specialty rules.\n */\nexport function oxlintIntegration(opts: ConfigOptions): FlatConfigArray {\n const configs: FlatConfigArray = []\n\n addOxlintConfig(configs, \"flat/recommended\", \"oxlint\")\n addReactOxlintConfigs(configs, opts)\n\n if (opts.node) {\n addOxlintConfig(configs, \"flat/node\", \"oxlint-node\")\n }\n\n // TypeScript and unicorn overlaps\n addOxlintConfig(configs, \"flat/typescript\", \"oxlint-typescript\")\n addOxlintConfig(configs, \"flat/unicorn\", \"oxlint-unicorn\")\n addOxlintConfig(configs, \"flat/import\", \"oxlint-import\")\n addOxlintConfig(configs, \"flat/jsdoc\", \"oxlint-jsdoc\")\n\n return configs\n}\n","import type { FlatConfigArray } from \"../types\"\n\n/**\n * Complexity preset — limits for production code that encourage small,\n * focused functions and aggressive extraction of helper functions.\n * @see https://eslint.org/docs/latest/rules/#suggestions (complexity rules)\n */\nexport function standardComplexity(): FlatConfigArray {\n return [\n {\n name: \"eslint-config-setup/complexity\",\n rules: {\n // Max cyclomatic complexity per function — 10 branches\n // https://eslint.org/docs/latest/rules/complexity\n complexity: [\"error\", 10],\n\n // Max nesting depth — 3 levels\n // https://eslint.org/docs/latest/rules/max-depth\n \"max-depth\": [\"error\", 3],\n\n // Max nested callbacks — 2 levels\n // https://eslint.org/docs/latest/rules/max-nested-callbacks\n \"max-nested-callbacks\": [\"error\", 2],\n\n // Max function parameters — 3 before using options object\n // https://eslint.org/docs/latest/rules/max-params\n \"max-params\": [\"error\", 3],\n\n // Max statements per function — 15\n // https://eslint.org/docs/latest/rules/max-statements\n \"max-statements\": [\"error\", 15],\n\n // Max lines per function — 50 (excluding blanks and comments)\n // https://eslint.org/docs/latest/rules/max-lines-per-function\n \"max-lines-per-function\": [\n \"error\",\n { max: 50, skipBlankLines: true, skipComments: true },\n ],\n\n // Max lines per file — 300 (excluding blanks and comments)\n // https://eslint.org/docs/latest/rules/max-lines\n \"max-lines\": [\n \"error\",\n { max: 300, skipBlankLines: true, skipComments: true },\n ],\n\n // Cognitive complexity — measures how hard code is to understand\n // https://sonarsource.github.io/rspec/#/rspec/S3776/javascript\n \"sonarjs/cognitive-complexity\": [\"error\", 10],\n },\n },\n {\n name: \"eslint-config-setup/complexity-tests-relaxed\",\n files: [\"**/*.test.{ts,tsx}\", \"**/__tests__/**/*.{ts,tsx}\", \"**/*.spec.ts\"],\n rules: {\n \"max-nested-callbacks\": \"off\",\n \"max-lines\": \"off\",\n \"max-lines-per-function\": \"off\",\n \"max-statements\": \"off\",\n },\n },\n ]\n}\n","import type { ConfigOptions, FlatConfigArray } from \"../types\"\n\nimport { aiConfig } from \"../configs/ai\"\nimport { baseConfig } from \"../configs/base\"\nimport { compatConfig } from \"../configs/compat\"\nimport { cspellConfig } from \"../configs/cspell\"\nimport { deMorganConfig } from \"../configs/de-morgan\"\nimport { importsConfig } from \"../configs/imports\"\nimport { jsdocConfig } from \"../configs/jsdoc\"\nimport { jsonConfig } from \"../configs/json\"\nimport { markdownConfig } from \"../configs/markdown\"\nimport { nodeConfig } from \"../configs/node\"\nimport { packageJsonAiConfig, packageJsonConfig } from \"../configs/package-json\"\nimport { perfectionistAiConfig, perfectionistConfig } from \"../configs/perfectionist\"\nimport { prettierCompatConfig } from \"../configs/prettier\"\nimport { reactConfig } from \"../configs/react\"\nimport { reactEffectConfig } from \"../configs/react-effect\"\nimport { regexpConfig } from \"../configs/regexp\"\nimport { securityConfig } from \"../configs/security\"\nimport { sonarjsConfig } from \"../configs/sonarjs\"\nimport { typescriptConfig } from \"../configs/typescript\"\nimport { unicornConfig } from \"../configs/unicorn\"\nimport { configFilesOverride } from \"../overrides/config-files\"\nimport { declarationsOverride } from \"../overrides/declarations\"\nimport { e2eOverride } from \"../overrides/e2e\"\nimport { scriptsOverride } from \"../overrides/scripts\"\nimport { storiesOverride } from \"../overrides/stories\"\nimport { testsOverride } from \"../overrides/tests\"\nimport { oxlintIntegration } from \"../oxlint/integration\"\nimport { standardComplexity } from \"../presets/standard\"\n\n/**\n * Composes a full flat config array from the given options.\n * This is the core logic used by the build system to generate configs.\n */\nfunction addCoreConfigs(config: FlatConfigArray, opts: ConfigOptions): void {\n const ai = opts.ai\n\n config.push(\n ...baseConfig({ ai }),\n ...typescriptConfig({ ai, react: opts.react }),\n ...importsConfig(),\n ...perfectionistConfig(),\n ...unicornConfig({ ai }),\n ...regexpConfig({ ai }),\n ...jsdocConfig({ ai }),\n ...cspellConfig(),\n ...sonarjsConfig({ ai }),\n ...securityConfig(),\n ...deMorganConfig(),\n )\n}\n\nfunction addConditionalConfigs(config: FlatConfigArray, opts: ConfigOptions): void {\n if (!opts.node) {\n config.push(...compatConfig())\n }\n\n if (!opts.ai) {\n config.push(...standardComplexity())\n }\n\n if (opts.node) {\n config.push(...nodeConfig({ ai: opts.ai }))\n }\n\n if (opts.react) {\n config.push(...reactConfig({ ai: opts.ai }))\n config.push(...reactEffectConfig())\n }\n\n if (opts.ai) {\n config.push(...aiConfig())\n config.push(...perfectionistAiConfig())\n config.push(...packageJsonAiConfig())\n }\n}\n\nfunction addFileTypeOverrides(config: FlatConfigArray): void {\n config.push(\n ...testsOverride(),\n ...e2eOverride(),\n ...storiesOverride(),\n ...configFilesOverride(),\n ...declarationsOverride(),\n ...scriptsOverride(),\n )\n}\n\nfunction addFinalConfigs(config: FlatConfigArray, opts: ConfigOptions): void {\n config.push(...jsonConfig(), ...packageJsonConfig(), ...markdownConfig(), ...prettierCompatConfig())\n\n if (opts.oxlint) {\n config.push(...oxlintIntegration(opts))\n }\n}\n\nexport function composeConfig(opts: ConfigOptions): FlatConfigArray {\n const config: FlatConfigArray = []\n\n addCoreConfigs(config, opts)\n addConditionalConfigs(config, opts)\n addFileTypeOverrides(config)\n addFinalConfigs(config, opts)\n\n return config\n}\n"],"mappings":"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"}