@gaia-harness/lint 3.0.4 → 3.1.0

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.
package/dist/index.js.map CHANGED
@@ -1 +1 @@
1
- {"version":3,"sources":["../src/configs/base.ts","../src/configs/restricted-imports.ts","../src/configs/better-tailwind.ts","../src/configs/guardrails.ts","../src/plugins/cn-conditional.ts","../src/plugins/no-enum.ts","../src/plugins/no-jsx-iife.ts","../src/plugins/no-null-render.ts","../src/plugins/no-switch.ts","../src/plugins/no-zod-enum.ts","../src/configs/i18n.ts","../src/configs/ignores.ts","../src/configs/playwright.ts","../src/configs/prettier.ts","../src/configs/react.ts","../src/plugins/no-imperative-query-fetch.ts","../src/configs/react-router.ts","../src/configs/shadcn.ts","../src/configs/storybook.ts","../src/configs/style-hygiene.ts","../src/configs/testing.ts","../src/configs/zod.ts","../src/index.ts"],"sourcesContent":["import eslintComments from '@eslint-community/eslint-plugin-eslint-comments/configs';\nimport js from '@eslint/js';\nimport {configs, plugins, rules} from 'eslint-config-airbnb-extended';\nimport preferArrowFunctions from 'eslint-plugin-prefer-arrow-functions';\nimport lodashUnderscore from 'eslint-plugin-you-dont-need-lodash-underscore';\nimport {RESTRICTED_IMPORT_PATHS} from './restricted-imports.js';\nimport type {ESLint, Linter} from 'eslint';\n\nconst jsConfig: Linter.Config[] = [\n // ESLint recommended config\n {\n name: 'js/config',\n ...js.configs.recommended,\n },\n // Stylistic plugin\n plugins.stylistic,\n // Import X plugin\n plugins.importX,\n // Airbnb base recommended config\n ...configs.base.recommended,\n // Strict import rules\n rules.base.importsStrict,\n];\n\nconst jsCustomConfig: Linter.Config[] = [\n {\n name: 'js-custom',\n rules: {\n 'consistent-return': 'off',\n curly: ['error', 'all'],\n 'max-params': 'error',\n 'no-param-reassign': 'off', // handled by sonarjs\n 'no-undef': 'off',\n 'no-unused-vars': 'off', // handled by sonarjs\n },\n },\n {\n files: ['**/*.test.ts?(x)', '**/*.stories.ts?(x)'],\n name: 'test-files/all',\n rules: {\n 'guard-for-in': 'off',\n 'max-params': 'off',\n 'no-await-in-loop': 'off',\n 'no-plusplus': 'off',\n 'no-restricted-syntax': 'off',\n },\n },\n {\n files: ['.playwright/**/*.ts?(x)'],\n name: 'playwright/all',\n rules: {\n 'no-await-in-loop': 'off',\n 'no-restricted-syntax': 'off',\n },\n },\n];\n\nconst typescriptConfig: Linter.Config[] = [\n // TypeScript ESLint plugin\n plugins.typescriptEslint,\n // Airbnb base TypeScript config\n ...configs.base.typescript,\n // Strict TypeScript rules\n rules.typescript.typescriptEslintStrict,\n rules.typescript.stylistic,\n // Airbnb React TypeScript config\n ...configs.react.typescript,\n {\n files: ['./*.ts'],\n name: 'root-ts-files',\n rules: {\n 'global-require': 'off',\n 'no-void': 'off',\n },\n },\n {\n files: ['**/*.ts?(x)'],\n name: 'no-void',\n rules: {\n 'no-void': ['error', {allowAsStatement: true}],\n },\n },\n];\n\nconst buildTsEslintConfig = (sourceDir: string): Linter.Config[] => [\n {\n files: ['**/*.ts?(x)'],\n name: 'typescript/config',\n rules: {\n '@typescript-eslint/array-type': ['error', {default: 'array'}],\n '@typescript-eslint/ban-ts-comment': [\n 'error',\n {\n minimumDescriptionLength: 10,\n 'ts-check': false,\n 'ts-expect-error': 'allow-with-description',\n 'ts-ignore': true,\n 'ts-nocheck': true,\n },\n ],\n '@typescript-eslint/consistent-type-definitions': ['error', 'type'],\n '@typescript-eslint/consistent-type-imports': 'error',\n '@typescript-eslint/explicit-module-boundary-types': 'off',\n '@typescript-eslint/method-signature-style': 'error',\n '@typescript-eslint/no-confusing-void-expression': [\n 'error',\n {ignoreArrowShorthand: true},\n ],\n '@typescript-eslint/no-deprecated': 'error',\n '@typescript-eslint/no-floating-promises': [\n 'error',\n {ignoreIIFE: true, ignoreVoid: true},\n ],\n '@typescript-eslint/no-misused-promises': [\n 'error',\n {checksVoidReturn: false},\n ],\n '@typescript-eslint/no-non-null-assertion': 'off',\n '@typescript-eslint/no-throw-literal': 'off',\n '@typescript-eslint/no-unnecessary-boolean-literal-compare': 'error',\n '@typescript-eslint/no-unnecessary-condition': 'error',\n '@typescript-eslint/no-unnecessary-type-conversion': 'error',\n '@typescript-eslint/no-unnecessary-type-parameters': 'off',\n '@typescript-eslint/no-unsafe-argument': 'error',\n '@typescript-eslint/no-unsafe-assignment': 'error',\n '@typescript-eslint/no-unsafe-call': 'error',\n '@typescript-eslint/no-unsafe-member-access': 'error',\n '@typescript-eslint/no-unsafe-return': 'error',\n '@typescript-eslint/only-throw-error': 'off',\n '@typescript-eslint/prefer-nullish-coalescing': 'error',\n '@typescript-eslint/prefer-promise-reject-errors': 'off',\n '@typescript-eslint/restrict-template-expressions': [\n 'error',\n {allowBoolean: true, allowNumber: true},\n ],\n '@typescript-eslint/return-await': 'off',\n '@typescript-eslint/unbound-method': 'off',\n },\n },\n {\n files: [\n `${sourceDir}/utils/**`,\n `${sourceDir}/services/**`,\n `${sourceDir}/hooks/**`,\n ],\n name: 'typescript/explicit-return-types',\n rules: {\n '@typescript-eslint/explicit-module-boundary-types': 'error',\n },\n },\n {\n files: ['**/*.test.ts?(x)', '**/*.stories.ts?(x)'],\n name: 'typescript/test-files',\n rules: {\n '@typescript-eslint/no-explicit-any': 'off',\n '@typescript-eslint/no-unsafe-argument': 'off',\n '@typescript-eslint/no-unsafe-assignment': 'off',\n '@typescript-eslint/no-unsafe-call': 'off',\n '@typescript-eslint/no-unsafe-member-access': 'off',\n },\n },\n {\n files: ['test/**/*.ts?(x)'],\n name: 'typescript/test-config',\n rules: {\n '@typescript-eslint/no-var-requires': 'off',\n 'no-plusplus': 'off',\n },\n },\n {\n files: ['**/*.d.ts'],\n name: 'typescript/type-definitions',\n rules: {\n '@typescript-eslint/consistent-type-definitions': 'off',\n '@typescript-eslint/method-signature-style': 'error',\n '@typescript-eslint/no-unused-vars': 'off',\n },\n },\n];\n\n// `^virtual:` covers Vite plugin virtual modules (`virtual:msw` and the like),\n// which no resolver can find on disk.\nconst NO_UNRESOLVED: Linter.RuleEntry = [\n 'error',\n {caseSensitive: true, commonjs: true, ignore: ['^virtual:']},\n];\n\nconst buildImportXConfig = (sourceDir: string): Linter.Config[] => [\n {\n name: 'import-x-all-files',\n rules: {\n 'import-x/consistent-type-specifier-style': ['error', 'prefer-top-level'],\n 'import-x/extensions': 'off',\n 'import-x/no-anonymous-default-export': [\n 'error',\n {\n allowArray: true,\n allowLiteral: true,\n allowObject: true,\n },\n ],\n 'import-x/no-namespace': 'off',\n 'import-x/no-rename-default': 'off',\n 'import-x/no-useless-path-segments': 'off',\n 'import-x/order': 'off',\n 'import-x/prefer-default-export': 'off',\n },\n },\n {\n files: ['./*.ts'],\n name: 'import-x/root-ts-files',\n rules: {\n 'import-x/no-extraneous-dependencies': 'off',\n 'import-x/no-unresolved': NO_UNRESOLVED,\n 'import-x/prefer-default-export': 'off',\n },\n },\n {\n files: ['**/*.test.ts?(x)', '**/*.stories.ts?(x)'],\n name: 'import-x/test-files',\n rules: {\n 'import-x/extensions': 'off',\n 'import-x/no-extraneous-dependencies': 'off',\n },\n },\n {\n files: [`${sourceDir}/**/*.ts?(x)`],\n name: 'import-x/app-test-files',\n rules: {\n 'import-x/no-unresolved': NO_UNRESOLVED,\n },\n },\n {\n files: [`${sourceDir}/**/hooks/*.ts?(x)`],\n name: 'import-x/hooks',\n rules: {\n 'import-x/no-default-export': 'error',\n },\n },\n {\n files: ['test/**/*.ts?(x)'],\n name: 'import-x/test-config-files',\n rules: {\n 'import-x/no-extraneous-dependencies': 'off',\n 'import-x/prefer-default-export': 'off',\n },\n },\n {\n files: ['.storybook/**/*.ts?(x)', '.playwright/**/*.ts?(x)'],\n name: 'import-x/storybook-playwright',\n rules: {\n 'import-x/no-extraneous-dependencies': 'off',\n 'import-x/no-unresolved': 'off',\n },\n },\n];\n\n// ESLint's built-in directive check, at error so an unused disable fails a\n// plain `eslint` run, not only one with `--max-warnings=0`. The eslint-comments\n// plugin's `no-unused-disable` cannot stand in for it: it looks its severity up\n// under the `@eslint-community/eslint-comments/` prefix, so registered under any\n// other plugin name it never reports.\nconst unusedDisableDirectivesConfig: Linter.Config[] = [\n {\n linterOptions: {reportUnusedDisableDirectives: 'error'},\n name: 'gaia/unused-disable-directives',\n },\n];\n\n/**\n * Disable-directive hygiene. Every `eslint-disable` must say why after a `--`\n * separator, so each bypass of a rule is reviewable where it sits. The\n * recommended set also bans a bare blanket `eslint-disable` and keeps block\n * disables paired with their enable. A whole-file disable at the top of a file\n * is allowed unpaired. An `eslint-enable` needs no reason.\n */\nconst eslintCommentsConfig: Linter.Config[] = [\n {\n ...eslintComments.recommended,\n name: 'gaia/eslint-comments',\n rules: {\n ...eslintComments.recommended.rules,\n '@eslint-community/eslint-comments/disable-enable-pair': [\n 'error',\n {allowWholeFile: true},\n ],\n '@eslint-community/eslint-comments/require-description': [\n 'error',\n {ignore: ['eslint-enable']},\n ],\n },\n },\n];\n\nconst preferArrowFunctionsConfig: Linter.Config[] = [\n {\n name: 'prefer-arrow',\n plugins: {\n 'prefer-arrow-functions': preferArrowFunctions as unknown as ESLint.Plugin,\n },\n rules: {\n 'prefer-arrow-functions/prefer-arrow-functions': 'error',\n },\n },\n {\n files: ['**/*.d.ts'],\n name: 'ts-definition-files/prefer-arrow-off',\n rules: {\n 'prefer-arrow-functions/prefer-arrow-functions': 'off',\n },\n },\n];\n\n/**\n * All `no-restricted-syntax` selectors live in one config object. ESLint flat\n * config merges this rule key by replacement (last match wins), not\n * concatenation, so a second block matching the same files would silently\n * clobber these selectors. Each selector carries its own message.\n *\n * `.d.ts` is ignored: ambient `export default function …(): T;` declarations\n * have no body to convert, and type-definition files contain no render code.\n */\nconst restrictedSyntaxConfig: Linter.Config[] = [\n {\n ignores: ['**/*.d.ts'],\n name: 'gaia/no-restricted-syntax',\n rules: {\n 'no-restricted-syntax': [\n 'error',\n {\n // `prefer-arrow-functions` has a hardcoded exemption for named\n // default-exported declarations\n // (`guard.js:hasNameAndIsExportedAsDefaultExport`), so\n // `export default function Foo() {}` slips through. This selector\n // closes that gap.\n message:\n 'Use `const Name = () => {}; export default Name;` instead. The prefer-arrow-functions plugin exempts named default-exported declarations upstream.',\n selector: 'ExportDefaultDeclaration > FunctionDeclaration',\n },\n {\n // GAIA never renders `null`. `cond ? <JSX/> : null` is the\n // numeric-0-safe `&&` guard written the long way. Both JSX-null\n // ternary selectors only match a JSXElement/JSXFragment branch, so\n // they are inert outside `.tsx`/`.jsx`.\n message:\n 'Do not render `null` from a ternary. Use a boolean-guarded `&&`: `cond && <JSX/>` (coerce a numeric/falsy guard with `!!cond`).',\n selector:\n \"ConditionalExpression[alternate.raw='null']:matches([consequent.type='JSXElement'], [consequent.type='JSXFragment'])\",\n },\n {\n message:\n 'Do not render `null` from a ternary. Invert the condition and use `&&`: `!cond && <JSX/>`.',\n selector:\n \"ConditionalExpression[consequent.raw='null']:matches([alternate.type='JSXElement'], [alternate.type='JSXFragment'])\",\n },\n {\n // A `.length` left operand is always numeric, so `&&` returns the\n // literal `0` (a renderable value) when the list is empty, leaking\n // \"0\" into the DOM. `.length` is the single most common numeric-0\n // leak and flagging it has zero false positives. The general\n // `count && <JSX/>` case is caught by `sonarjs/jsx-no-leaked-render`\n // in `guardrails`, which needs type information; this selector\n // needs none, so it still holds where types are unavailable.\n // Report-only: a blind rewrite is unsafe in general.\n message:\n 'A numeric `.length` left operand leaks \"0\" into the DOM when empty. Force a real boolean: `items.length > 0 && <JSX/>`.',\n selector:\n \"LogicalExpression[operator='&&'][left.property.name='length']:matches([right.type='JSXElement'],[right.type='JSXFragment'])\",\n },\n ],\n },\n },\n];\n\n/**\n * Global `no-restricted-imports` bans, applied to every `.ts`/`.tsx` file.\n *\n * The shared `RESTRICTED_IMPORT_PATHS` const is also spread into testing.ts's\n * own `no-restricted-imports` block. Flat config replaces a rule's options\n * wholesale, so without that second reference this global ban would be dropped\n * on test/story files (which testing.ts re-scopes the rule for).\n */\nconst restrictedImportsConfig: Linter.Config[] = [\n {\n files: ['**/*.ts?(x)'],\n name: 'gaia/no-restricted-imports',\n rules: {\n 'no-restricted-imports': ['error', {paths: RESTRICTED_IMPORT_PATHS}],\n },\n },\n];\n\nconst lodashUnderscoreConfig: Linter.Config[] = [\n {\n name: 'you-dont-need-lodash-underscore',\n plugins: {\n 'you-dont-need-lodash-underscore':\n lodashUnderscore as unknown as ESLint.Plugin,\n },\n rules: {\n ...(lodashUnderscore.configs.compatible.rules as Linter.RulesRecord),\n },\n },\n];\n\nexport const buildBase = (sourceDir: string): Linter.Config[] => [\n ...jsConfig,\n ...jsCustomConfig,\n ...typescriptConfig,\n ...buildTsEslintConfig(sourceDir),\n ...buildImportXConfig(sourceDir),\n ...unusedDisableDirectivesConfig,\n ...eslintCommentsConfig,\n ...preferArrowFunctionsConfig,\n ...restrictedSyntaxConfig,\n ...restrictedImportsConfig,\n ...lodashUnderscoreConfig,\n];\n","/**\n * Shared `no-restricted-imports` path bans.\n *\n * Referenced by BOTH the global base config and the testing config. ESLint\n * flat config replaces a rule's options WHOLESALE across config objects (it\n * does not merge them), so a later block that re-declares\n * `no-restricted-imports` — testing.ts scopes one to test/story files — would\n * otherwise DROP these bans on the files it matches. Both call sites spread\n * this same const so the ban holds everywhere and stays DRY.\n *\n * Uses `paths` (exact specifier match), not `patterns` (glob match): only the\n * bare `@conform-to/zod` specifier is banned, while the distinct\n * `@conform-to/zod/v4` specifier stays allowed. A `patterns` entry keyed on\n * `@conform-to/zod` would wrongly also catch the `/v4` subpath.\n *\n * The `react` entry bans only the `FC` and `FunctionComponent` names\n * (`importNames`); every other `react` import stays allowed. The core rule\n * reports type-only specifiers, so `import type {FC}` is caught too.\n */\nexport const RESTRICTED_IMPORT_PATHS = [\n {\n importNames: ['FC', 'FunctionComponent'],\n message:\n \"Do not import FC or FunctionComponent from 'react'. Type the props inline: `type ButtonProps = {...}; const Button = ({...}: ButtonProps) => ...`.\",\n name: 'react',\n },\n {\n message:\n \"Import from '@conform-to/zod/v4'. The bare '@conform-to/zod' specifier targets Zod v3 and throws at runtime, uncaught by typecheck, lint, and build.\",\n name: '@conform-to/zod',\n },\n];\n","import betterTailwindPlugin from 'eslint-plugin-better-tailwindcss';\nimport type {Linter} from 'eslint';\n\nexport type GaiaLintBetterTailwindOptions = {\n /** Path to the Tailwind entry CSS file (e.g. './app/styles/tailwind.css'). */\n entryPoint: string;\n /** Class names to ignore in `better-tailwindcss/no-unknown-classes`. */\n ignore?: string[];\n};\n\n/**\n * Better-Tailwind flat-config factory.\n *\n * Ports `betterTailwindConfig` from GAIA's `eslint.config.mjs`. The\n * `entryPoint` (consumer's Tailwind CSS entry) and `ignore` list are\n * project-specific, so this is shipped as a factory rather than a static\n * array.\n */\nexport const betterTailwind = (\n opts: GaiaLintBetterTailwindOptions,\n): Linter.Config[] => [\n {\n name: 'better-tailwindcss',\n plugins: {\n 'better-tailwindcss': betterTailwindPlugin,\n },\n rules: {\n // rootFontSize lets a px arbitrary value canonicalize to its scale step\n // (`w-[16px]` to `w-4`).\n 'better-tailwindcss/enforce-canonical-classes': [\n 'error',\n {rootFontSize: 16},\n ],\n 'better-tailwindcss/enforce-consistent-important-position': 'error',\n 'better-tailwindcss/enforce-consistent-variable-syntax': 'error',\n 'better-tailwindcss/enforce-shorthand-classes': 'error',\n 'better-tailwindcss/no-conflicting-classes': 'error',\n 'better-tailwindcss/no-deprecated-classes': 'error',\n 'better-tailwindcss/no-unknown-classes': [\n 'error',\n {ignore: opts.ignore ?? []},\n ],\n },\n settings: {\n 'better-tailwindcss': {\n detectComponentClasses: true,\n entryPoint: opts.entryPoint,\n },\n },\n },\n];\n","import path from 'node:path';\nimport type {Linter} from 'eslint';\nimport noRelativeImportPaths from 'eslint-plugin-no-relative-import-paths';\nimport * as regexp from 'eslint-plugin-regexp';\nimport sonarjs from 'eslint-plugin-sonarjs';\nimport cnConditionalPlugin from '../plugins/cn-conditional.js';\nimport noEnumPlugin from '../plugins/no-enum.js';\nimport noJsxIifePlugin from '../plugins/no-jsx-iife.js';\nimport noNullRenderPlugin from '../plugins/no-null-render.js';\nimport noSwitchPlugin from '../plugins/no-switch.js';\nimport noZodEnumPlugin from '../plugins/no-zod-enum.js';\n\nconst buildSonarConfig = (sourceDir: string): Linter.Config[] => [\n sonarjs.configs!.recommended as Linter.Config,\n {\n name: 'sonarjs',\n rules: {\n 'sonarjs/cognitive-complexity': 'error',\n 'sonarjs/fixme-tag': 'off',\n 'sonarjs/no-commented-code': 'off',\n 'sonarjs/no-nested-conditional': 'off',\n 'sonarjs/no-nested-functions': 'off',\n 'sonarjs/no-selector-parameter': 'off',\n 'sonarjs/regex-complexity': 'off',\n 'sonarjs/todo-tag': 'off',\n },\n },\n {\n files: ['**/*.tsx', '**/hooks/*.ts?(x)'],\n name: 'sonarjs/react-files',\n rules: {\n 'sonarjs/cognitive-complexity': 'off',\n 'sonarjs/function-return-type': 'off',\n },\n },\n {\n files: ['**/*.test.ts?(x)', '**/*.stories.ts?(x)'],\n name: 'sonarjs/test-files',\n rules: {\n 'sonarjs/no-duplicate-string': 'off',\n 'sonarjs/no-identical-functions': 'off',\n },\n },\n {\n files: [`${sourceDir}/languages/**/*.ts`, 'eslint.config.mjs'],\n name: 'sonarjs/credential-checks',\n rules: {\n 'sonarjs/no-hardcoded-credentials': 'off',\n 'sonarjs/no-hardcoded-passwords': 'off',\n },\n },\n];\n\n/**\n * Regex correctness. The recommended set catches patterns that can backtrack\n * catastrophically on hostile input (ReDoS), alternatives and character\n * classes that can never match, misleading capture groups, and needless\n * escapes or quantifiers. sonarjs covers only a few of these.\n */\nconst regexpConfig: Linter.Config[] = [\n {...regexp.configs['flat/recommended'], name: 'regexp'},\n];\n\nconst cnConditionalConfig: Linter.Config[] = [\n {\n files: ['**/*.ts?(x)', '**/*.js?(x)'],\n name: 'cn-conditional',\n plugins: {'cn-conditional': cnConditionalPlugin},\n rules: {'cn-conditional/cn-conditional': 'error'},\n },\n];\n\nconst noEnumConfig: Linter.Config[] = [\n {\n files: ['**/*.ts?(x)'],\n name: 'no-enum',\n plugins: {'no-enum': noEnumPlugin},\n rules: {\n 'no-enum/no-enum': 'error',\n },\n },\n];\n\nconst noJsxIifeConfig: Linter.Config[] = [\n {\n files: ['**/*.tsx', '**/*.jsx'],\n name: 'no-jsx-iife',\n plugins: {'no-jsx-iife': noJsxIifePlugin},\n rules: {'no-jsx-iife/no-jsx-iife': 'error'},\n },\n];\n\nconst noNullRenderConfig: Linter.Config[] = [\n {\n files: ['**/*.tsx', '**/*.jsx'],\n name: 'no-null-render',\n plugins: {'no-null-render': noNullRenderPlugin},\n rules: {'no-null-render/no-null-render': 'error'},\n },\n];\n\nconst noSwitchConfig: Linter.Config[] = [\n {\n files: ['**/*.ts?(x)', '**/*.js?(x)'],\n name: 'no-switch',\n plugins: {'no-switch': noSwitchPlugin},\n rules: {'no-switch/no-switch': 'error'},\n },\n];\n\nconst noZodEnumConfig: Linter.Config[] = [\n {\n files: ['**/*.ts?(x)'],\n name: 'no-zod-enum',\n plugins: {'no-zod-enum': noZodEnumPlugin},\n rules: {'no-zod-enum/no-zod-enum': 'error'},\n },\n];\n\n/**\n * Architecture-boundary enforcement for GAIA's canonical `app/` layout.\n *\n * Imports may only flow from a higher layer to a lower one:\n *\n * routes -> pages -> components -> { hooks, state } -> services -> utils -> types\n *\n * `types/` is a pure leaf importable by everyone. Each zone names a lower\n * layer as `target` and the higher layers it must not import as `from`, so a\n * lower-importing-higher edge (the wrong direction) is reported. `routes`\n * appears in every `from` set, which encodes \"nothing may import a route\".\n *\n * Zone `target`/`from` paths resolve against `process.cwd()` (the consuming\n * project's root where eslint runs), not this package's location in\n * node_modules, so `./${sourceDir}/...` correctly points at the consumer's\n * source tree. `import-x@4.16.2` accepts `from`/`target` as string arrays,\n * which collapses the higher->lower pairs into one zone per target layer.\n *\n * `app/middleware`, `app/sessions.server`, `app/assets`, `app/languages`, and\n * `app/styles` are intentionally left unconstrained (server/asset dirs).\n *\n * The UI layers (pages, components, hooks/state) are exempted from the boundary\n * when importing a typed data-endpoint route (`routes/actions.*`,\n * `routes/resources.*`, or the older `routes/actions+`/`routes/resources+`\n * group folders, still accepted on the 2.x line). These are no-UI, typed data\n * endpoints the UI is explicitly meant to consume (e.g.\n * `useFetcher<typeof action>`). `import-x/no-restricted-paths` cannot\n * distinguish a type-only import, so without this carve-out it flags a\n * component's `import type {action}` from a typed endpoint.\n *\n * These three zones use glob-mode `from` (every entry is a `**` glob), because\n * import-x resolves a plain-mode `except` as a descendant path of `from`, which\n * cannot match a sibling flat route file. In glob mode `except` entries are\n * matched as absolute-path globs against the resolved import path, so they are\n * built from `process.cwd()` (the same default basePath import-x resolves\n * `from` against) rather than written as `**`-relative patterns: a leading `**`\n * does not cross a dot-prefixed path segment, so a `**`-relative pattern goes\n * silently dark under a dot-directory checkout (e.g. a `.claude/worktrees/`\n * worktree). Matching is by basename prefix, not a list of GAIA's endpoint\n * files. The services, utils, and types zones get no exemption, so the\n * carve-out stays within the UI layer.\n */\nconst buildNoRestrictedPathsConfig = (\n sourceDir: string,\n): Linter.Config[] => {\n const dir = (layer: string): string => `./${sourceDir}/${layer}`;\n const globDir = (layer: string): string => `./${sourceDir}/${layer}/**`;\n // Absolute, forward-slash, anchored where import-x resolves `from`\n // (its basePath defaults to process.cwd()).\n const routesDir = path\n .resolve(process.cwd(), sourceDir, 'routes')\n .split(path.sep)\n .join('/');\n const dataEndpoints = [\n `${routesDir}/actions.*`,\n `${routesDir}/resources.*`,\n // Older `+` group folders stay exempt through the 2.x line.\n `${routesDir}/actions+/**`,\n `${routesDir}/resources+/**`,\n ];\n\n return [\n {\n files: [`${sourceDir}/**/!(*.test|*.stories).ts?(x)`],\n name: 'import-x/architecture-boundaries',\n rules: {\n 'import-x/no-restricted-paths': [\n 'error',\n {\n zones: [\n {\n except: dataEndpoints,\n from: [globDir('routes')],\n message:\n 'Pages may only be imported by routes; a page must not import a route (import direction is routes -> pages -> components). Typed `actions.*`/`resources.*` data-endpoint routes are exempt (the older `actions+`/`resources+` folders are still accepted).',\n target: dir('pages'),\n },\n {\n except: dataEndpoints,\n from: [globDir('routes'), globDir('pages')],\n message:\n 'Reusable components must not depend on page- or route-level code (import direction is routes -> pages -> components). Typed `actions.*`/`resources.*` data-endpoint routes are exempt (the older `actions+`/`resources+` folders are still accepted).',\n target: dir('components'),\n },\n {\n except: dataEndpoints,\n from: [globDir('routes'), globDir('pages'), globDir('components')],\n message:\n 'Hooks and state sit below the UI tree; they must not import components, pages, or routes. Typed `actions.*`/`resources.*` data-endpoint routes are exempt (the older `actions+`/`resources+` folders are still accepted).',\n target: [dir('hooks'), dir('state')],\n },\n {\n from: [\n dir('routes'),\n dir('pages'),\n dir('components'),\n dir('hooks'),\n dir('state'),\n ],\n message:\n 'The service/data layer sits below the UI and orchestration layers; it must not import components, pages, routes, hooks, or state.',\n target: dir('services'),\n },\n {\n from: [\n dir('routes'),\n dir('pages'),\n dir('components'),\n dir('hooks'),\n dir('state'),\n dir('services'),\n ],\n message:\n 'Utils are near-leaves; they may import only types and other utils.',\n target: dir('utils'),\n },\n {\n from: [\n dir('routes'),\n dir('pages'),\n dir('components'),\n dir('hooks'),\n dir('state'),\n dir('services'),\n dir('utils'),\n ],\n message:\n 'Types are a pure leaf; they must not import any other app layer.',\n target: dir('types'),\n },\n ],\n },\n ],\n },\n },\n ];\n};\n\nconst buildNoRelativeImportPathsConfig = (\n sourceDir: string,\n): Linter.Config[] => [\n {\n name: 'no-relative-import-paths',\n plugins: {\n 'no-relative-import-paths': noRelativeImportPaths,\n },\n rules: {\n 'no-relative-import-paths/no-relative-import-paths': [\n 'error',\n {\n allowedDepth: 2,\n allowSameFolder: true,\n prefix: '~',\n rootDir: sourceDir,\n },\n ],\n },\n },\n];\n\nexport const buildGuardrails = (sourceDir: string): Linter.Config[] => [\n ...buildSonarConfig(sourceDir),\n ...regexpConfig,\n ...cnConditionalConfig,\n ...noEnumConfig,\n ...noJsxIifeConfig,\n ...noNullRenderConfig,\n ...noSwitchConfig,\n ...noZodEnumConfig,\n ...buildNoRestrictedPathsConfig(sourceDir),\n ...buildNoRelativeImportPathsConfig(sourceDir),\n];\n","import type {ESLint, Rule, Scope} from 'eslint';\n\n/**\n * Holds one form for a conditional class passed to `cn` from the `cn` package:\n * `cond && 'class'`. Object arguments and ternaries with an empty branch\n * (`undefined`, `null`, `false`, `''`, or an empty template) are reported. A\n * ternary with two non-empty branches (`c ? 'a' : 'b'`) is allowed.\n *\n * Only a callee that resolves to the named import `cn` from `'cn'` is checked\n * (aliases count; a local `cn` or a `cn` from another module is ignored).\n * Namespace imports (`import * as c from 'cn'; c.cn(...)`) are a deliberate\n * miss.\n */\n\ntype CallNode = Parameters<NonNullable<Rule.NodeListener['CallExpression']>>[0];\ntype Argument = CallNode['arguments'][number];\ntype Visited = Argument | null | undefined;\n\nconst findVariable = (\n scope: Scope.Scope | null,\n name: string\n): Scope.Variable | undefined => {\n let current = scope;\n while (current) {\n const variable = current.set.get(name);\n if (variable) return variable;\n current = current.upper;\n }\n return undefined;\n};\n\nconst isCnImport = (variable: Scope.Variable | undefined): boolean =>\n variable !== undefined &&\n variable.defs.length === 1 &&\n variable.defs.every((definition) => {\n if (definition.type !== 'ImportBinding') return false;\n const specifier = definition.node;\n return (\n specifier.type === 'ImportSpecifier' &&\n specifier.imported.type === 'Identifier' &&\n specifier.imported.name === 'cn' &&\n definition.parent?.type === 'ImportDeclaration' &&\n definition.parent.source.value === 'cn'\n );\n });\n\nconst isEmptyBranch = (node: Visited): boolean => {\n if (!node) return false;\n switch (node.type) {\n case 'Identifier':\n return node.name === 'undefined';\n case 'Literal':\n return (\n node.value === null || node.value === false || node.value === ''\n );\n case 'TemplateLiteral':\n return (\n node.expressions.length === 0 &&\n node.quasis.every((quasi) => quasi.value.cooked === '')\n );\n default:\n return false;\n }\n};\n\nconst cnConditionalRule: Rule.RuleModule = {\n create: (context) => {\n const visit = (node: Visited): void => {\n if (!node) return;\n switch (node.type) {\n case 'ArrayExpression':\n node.elements.forEach((element) => visit(element));\n break;\n case 'ConditionalExpression':\n if (isEmptyBranch(node.consequent) || isEmptyBranch(node.alternate)) {\n context.report({messageId: 'useLogical', node});\n } else {\n visit(node.consequent);\n visit(node.alternate);\n }\n break;\n case 'LogicalExpression':\n if (node.operator === '&&') {\n visit(node.right);\n } else {\n visit(node.left);\n visit(node.right);\n }\n break;\n case 'ObjectExpression':\n context.report({messageId: 'useLogical', node});\n break;\n default:\n break;\n }\n };\n\n return {\n CallExpression: (node: CallNode) => {\n if (node.callee.type !== 'Identifier') return;\n const variable = findVariable(\n context.sourceCode.getScope(node),\n node.callee.name\n );\n if (!isCnImport(variable)) return;\n node.arguments.forEach((argument) => visit(argument));\n },\n };\n },\n meta: {\n docs: {\n description:\n \"Require conditional classes passed to cn to be written as `cond && 'class'`\",\n },\n messages: {\n useLogical:\n \"Write a conditional class as `cond && 'class'` (or `!cond && 'class'`). `cn` does not accept object conditionals or a ternary with an empty branch in GAIA.\",\n },\n schema: [],\n type: 'problem',\n },\n};\n\nconst plugin: ESLint.Plugin = {\n meta: {\n name: 'cn-conditional',\n version: '0.1.0',\n },\n rules: {\n 'cn-conditional': cnConditionalRule,\n },\n};\n\nexport default plugin;\n","import type {ESLint, Rule} from 'eslint';\n\nconst noEnumRule: Rule.RuleModule = {\n create: (context) => ({\n TSEnumDeclaration: (node: Rule.Node) => {\n context.report({messageId: 'noEnum', node});\n },\n }),\n meta: {\n docs: {description: 'Disallow TypeScript enums'},\n messages: {\n noEnum:\n 'Do not use TypeScript enums. Use an object with `as const` instead.',\n },\n schema: [],\n type: 'problem',\n },\n};\n\nconst plugin: ESLint.Plugin = {\n meta: {\n name: 'no-enum',\n version: '0.1.0',\n },\n rules: {\n 'no-enum': noEnumRule,\n },\n};\n\nexport default plugin;\n","import type {ESLint, Rule} from 'eslint';\n\nconst noJsxIifeRule: Rule.RuleModule = {\n create: (context) => ({\n 'JSXExpressionContainer > CallExpression > ArrowFunctionExpression.callee':\n (node: Rule.Node) => {\n context.report({messageId: 'noJsxIife', node});\n },\n 'JSXExpressionContainer > CallExpression > FunctionExpression.callee': (\n node: Rule.Node,\n ) => {\n context.report({messageId: 'noJsxIife', node});\n },\n }),\n meta: {\n docs: {description: 'Disallow IIFEs in JSX expressions'},\n messages: {\n noJsxIife:\n 'Do not use IIFEs in JSX. Use a computed variable before the return or extract a component instead.',\n },\n schema: [],\n type: 'problem',\n },\n};\n\nconst plugin: ESLint.Plugin = {\n meta: {\n name: 'no-jsx-iife',\n version: '0.1.0',\n },\n rules: {\n 'no-jsx-iife': noJsxIifeRule,\n },\n};\n\nexport default plugin;\n","import type {ESLint, Rule} from 'eslint';\n\n/**\n * Render nothing with `undefined`, not `null`, in render functions.\n *\n * Consistency convention only: `null` and `undefined` are behaviorally\n * identical to React's reconciler (both, plus `false`/`true`, are the same\n * empty slot) and equally cheap in V8. This standardizes on the newer of two\n * equivalent forms; it does NOT imply `null` is wrong or slow.\n *\n * Safety model: this rule autofixes under unsupervised `eslint --fix`. A\n * `return null` in a React Router loader/action/util MUST stay `null` (rewriting\n * it would change runtime behavior). So a `return null` is fixed ONLY when its\n * lexically-enclosing function is PROVABLY a render function (renders JSX in its\n * own scope). When render context is not provable, the rule does nothing: a\n * deliberate safe miss.\n */\n\ntype ReturnNode = Parameters<NonNullable<Rule.NodeListener['ReturnStatement']>>[0];\n\ntype RenderFrame = {candidates: ReturnNode[]; rendersJsx: boolean};\n\n// JSX nodes are not part of @types/estree, so widen to `{type}` to compare.\nconst isJsxNode = (node: {type: string}): boolean =>\n node.type === 'JSXElement' || node.type === 'JSXFragment';\n\nconst noNullRenderRule: Rule.RuleModule = {\n create: (context) => {\n // Function-frame stack. One frame per function entered during traversal.\n const stack: RenderFrame[] = [];\n\n const enterFunction = (node: Rule.Node) => {\n const frame: RenderFrame = {candidates: [], rendersJsx: false};\n // An arrow with a JSX expression body renders JSX in its OWN frame.\n if (node.type === 'ArrowFunctionExpression' && isJsxNode(node.body)) {\n frame.rendersJsx = true;\n }\n stack.push(frame);\n };\n\n const exitFunction = () => {\n const frame = stack.pop();\n if (!frame || !frame.rendersJsx) {\n return; // Not a provable render frame: leave every candidate alone.\n }\n for (const candidate of frame.candidates) {\n const {argument} = candidate;\n if (!argument) {\n continue;\n }\n context.report({\n fix: (fixer) => fixer.replaceText(argument, 'undefined'),\n messageId: 'nullRender',\n node: candidate,\n });\n }\n };\n\n return {\n ArrowFunctionExpression: enterFunction,\n 'ArrowFunctionExpression:exit': exitFunction,\n FunctionDeclaration: enterFunction,\n 'FunctionDeclaration:exit': exitFunction,\n FunctionExpression: enterFunction,\n 'FunctionExpression:exit': exitFunction,\n ReturnStatement: (node) => {\n const frame = stack[stack.length - 1];\n if (!frame) {\n return; // `return` outside any function: not our concern.\n }\n const {argument} = node;\n if (!argument) {\n return; // bare `return;`\n }\n if (isJsxNode(argument)) {\n // A `return <JSX>` proves THIS frame is a render function.\n frame.rendersJsx = true;\n return;\n }\n if (\n argument.type === 'Literal' &&\n argument.value === null &&\n argument.raw === 'null'\n ) {\n // A literal `return null;`: attribute to the current (top) frame.\n // (raw === 'null' excludes regex literals, whose `value` can be null.)\n frame.candidates.push(node);\n }\n },\n };\n },\n meta: {\n docs: {\n description:\n 'Render nothing with `undefined`, not `null`, in render functions',\n },\n fixable: 'code',\n messages: {\n nullRender:\n 'Render nothing with `undefined`, not `null`. GAIA standardizes on `undefined` for the empty render (both are identical to React; this is a consistency convention).',\n },\n schema: [],\n type: 'suggestion',\n },\n};\n\nconst plugin: ESLint.Plugin = {\n meta: {\n name: 'no-null-render',\n version: '0.1.0',\n },\n rules: {\n 'no-null-render': noNullRenderRule,\n },\n};\n\nexport default plugin;\n","import type {ESLint, Rule} from 'eslint';\n\nconst noSwitchRule: Rule.RuleModule = {\n create: (context) => ({\n SwitchStatement: (node: Rule.Node) => {\n context.report({messageId: 'noSwitch', node});\n },\n }),\n meta: {\n docs: {description: 'Disallow switch statements'},\n messages: {\n noSwitch:\n 'Do not use switch statements. Use an object map or if/else instead.',\n },\n schema: [],\n type: 'problem',\n },\n};\n\nconst plugin: ESLint.Plugin = {\n meta: {\n name: 'no-switch',\n version: '0.1.0',\n },\n rules: {\n 'no-switch': noSwitchRule,\n },\n};\n\nexport default plugin;\n","import type {ESLint, Rule} from 'eslint';\n\nconst noZodEnumRule: Rule.RuleModule = {\n create: (context) => ({\n 'CallExpression > MemberExpression.callee[object.name=\"z\"][property.name=\"enum\"]':\n (node: Rule.Node) => {\n context.report({messageId: 'noZodEnum', node});\n },\n }),\n meta: {\n docs: {description: 'Disallow z.enum(); use z.literal([...]) instead'},\n messages: {\n noZodEnum:\n 'Do not use z.enum(). Use z.literal([...]) for string unions (sort values alphanumerically).',\n },\n schema: [],\n type: 'problem',\n },\n};\n\nconst plugin: ESLint.Plugin = {\n meta: {\n name: 'no-zod-enum',\n version: '0.1.0',\n },\n rules: {\n 'no-zod-enum': noZodEnumRule,\n },\n};\n\nexport default plugin;\n","import i18next from 'eslint-plugin-i18next';\nimport type {Linter} from 'eslint';\n\n/**\n * i18n flat-config block (opt-in), for projects that translate their UI.\n *\n * `i18next/no-literal-string` in `jsx-text-only` mode reports raw text between\n * JSX tags (`<p>Hello</p>`), which should come from `t()`. Attributes and\n * plain string literals are not checked: `jsx-only` mode flags `data-slot`,\n * `htmlFor`, `value` and the like, which are not UI copy.\n *\n * Stories, tests, `tests/` helpers and the vendored shadcn ui files are\n * exempt. Text that must stay untranslated (an error boundary that renders\n * without i18n) takes an inline disable with a reason.\n *\n * A project that drops i18n removes `...lint.i18n` from its config.\n */\nexport const buildI18n = (sourceDir: string): Linter.Config[] => [\n {\n files: [`${sourceDir}/**/*.tsx`, `${sourceDir}/**/*.jsx`],\n ignores: [\n '**/*.test.tsx',\n '**/*.stories.tsx',\n '**/tests/**',\n `${sourceDir}/components/ui/*.tsx`,\n ],\n name: 'i18n/no-literal-string',\n plugins: {i18next},\n rules: {\n 'i18next/no-literal-string': ['error', {mode: 'jsx-text-only'}],\n },\n },\n];\n","import {includeIgnoreFile} from '@eslint/config-helpers';\nimport type {Linter} from 'eslint';\nimport fs from 'node:fs';\nimport path from 'node:path';\n\nexport type GaiaLintIgnoresOptions = {\n /**\n * Path to a `.gitignore` file to merge in. Resolved from `process.cwd()`\n * if relative. Pass `false` to skip the gitignore merge entirely.\n *\n * If the resolved path does not exist, the merge is silently skipped —\n * projects without a `.gitignore` don't need to opt out explicitly.\n *\n * @default '.gitignore'\n */\n gitignore?: string | false;\n /** Extra ignore globs to merge with GAIA defaults. */\n extra?: string[];\n};\n\n/**\n * GAIA's default ignore globs — matches the static `ignored-files` block in\n * GAIA's `eslint.config.mjs`. Consumer's `extra` ignores get concatenated\n * onto this list.\n *\n * Every entry names generated output, a non-source asset, or a tool-owned\n * script directory. Authored source stays out: a bare directory entry here is\n * a GLOBAL ignore, which beats any later block's `files`, so ignoring a\n * directory that another block scopes itself to silently kills that block.\n * `.playwright` and `.storybook` hold hand-written source that the\n * `playwright` and `storybook` blocks exist to lint.\n */\nconst defaultIgnores = [\n '/.react-router/**',\n '.claude/**/*.js',\n '.claude/**/*.cjs',\n 'scripts',\n 'public/**',\n '**/*.css',\n '**/*.svg',\n '**/*.md',\n];\n\n/**\n * Ignores flat-config factory.\n *\n * Ports the `includeIgnoreFile(gitignorePath)` + static `ignored-files`\n * block from GAIA's `eslint.config.mjs`. The `gitignore` path must be\n * resolved at the consumer's cwd (config-load time), not at gaia-lint's\n * install location, so this is shipped as a factory.\n */\nexport const ignores = (opts?: GaiaLintIgnoresOptions): Linter.Config[] => {\n const out: Linter.Config[] = [];\n\n const gitignore = opts?.gitignore ?? '.gitignore';\n if (gitignore !== false) {\n const resolved = path.isAbsolute(gitignore)\n ? gitignore\n : path.resolve(process.cwd(), gitignore);\n if (fs.existsSync(resolved)) {\n out.push(includeIgnoreFile(resolved) as Linter.Config);\n }\n }\n\n out.push({\n ignores: [...defaultIgnores, ...(opts?.extra ?? [])],\n name: 'ignored-files',\n });\n\n return out;\n};\n","import playwrightPlugin from 'eslint-plugin-playwright';\nimport type {Linter} from 'eslint';\n\n/**\n * Playwright flat-config block.\n *\n * Ports `playwrightConfig` from GAIA's `eslint.config.mjs` — scopes\n * `eslint-plugin-playwright`'s `flat/recommended` config to `.playwright/`\n * test files (GAIA's e2e directory convention).\n */\nexport const playwright: Linter.Config[] = [\n {\n name: 'playwright',\n ...(playwrightPlugin.configs['flat/recommended'] as Linter.Config),\n files: ['.playwright/**/*.ts?(x)'],\n rules: {\n ...playwrightPlugin.configs['flat/recommended'].rules,\n // Every test must assert something. `assertFunctionPatterns` lets custom\n // `expect*()` helpers count as the assertion. Error, never warn: a test\n // that asserts nothing is a false green.\n 'playwright/expect-expect': [\n 'error',\n {assertFunctionPatterns: ['^expect[A-Z]']},\n ],\n // A bare `test.skip()` is a test switched off at author time and stays\n // flagged at the recommended set's severity. `test.skip(condition, reason)`\n // is a different thing: Playwright's own API for a test that does not\n // apply to the environment it just found (a feature the project did not\n // enable, a browser without the capability). Allow the conditional form.\n 'playwright/no-skipped-test': ['warn', {allowConditional: true}],\n },\n },\n];\n","import {rules as prettierConfigRules} from 'eslint-config-prettier';\nimport prettierPlugin from 'eslint-plugin-prettier';\nimport type {Linter} from 'eslint';\n\n/**\n * Prettier flat-config block.\n *\n * Ports `prettierConfig` from GAIA's `eslint.config.mjs`. Layers\n * `eslint-config-prettier`'s rule disablers, then re-enables a few\n * `@stylistic/*` rules GAIA wants to keep (padding lines, single quotes),\n * and finally turns on the `prettier/prettier` rule itself.\n */\nexport const prettier: Linter.Config[] = [\n {\n name: 'prettier/plugin/config',\n plugins: {prettier: prettierPlugin},\n },\n {\n name: 'prettier/config',\n rules: {\n ...prettierConfigRules,\n '@stylistic/padding-line-between-statements': [\n 'error',\n {\n blankLine: 'always',\n next: ['block-like', 'export', 'return', 'throw'],\n prev: '*',\n },\n ],\n '@stylistic/quotes': [\n 'error',\n 'single',\n {\n allowTemplateLiterals: 'avoidEscape',\n avoidEscape: true,\n },\n ],\n '@stylistic/spaced-comment': 'off',\n 'prettier/prettier': ['error', {endOfLine: 'auto'}],\n },\n },\n];\n","import eslintReact from '@eslint-react/eslint-plugin';\nimport {configs, plugins} from 'eslint-config-airbnb-extended';\nimport reactRefresh from 'eslint-plugin-react-refresh';\nimport youMightNotNeedAnEffect from 'eslint-plugin-react-you-might-not-need-an-effect';\nimport type {ESLint, Linter} from 'eslint';\n\n/**\n * React flat-config block.\n *\n * Ports `reactConfig` + `reactCustomConfig` from GAIA's `eslint.config.mjs`.\n * Pulls React, React Hooks, and JSX A11y plugins plus Airbnb's recommended\n * React config, then layers GAIA's project-wide React rule overrides.\n *\n * Router-specific relaxations live in the optional `reactRouter` block, not\n * here, so a project on a different file-based router keeps its full rule set.\n */\n/**\n * Options for `react-refresh/only-export-components`, shared with the route\n * block in `reactRouter`, which repeats them because flat config replaces a\n * rule's options wholesale. Vite's React plugin keeps state across a hot\n * update for constant and compound-component exports, so both are allowed.\n */\nexport const ONLY_EXPORT_COMPONENTS_OPTIONS = {\n allowCompoundComponents: true,\n allowConstantExport: true,\n} as const;\n\nexport const react: Linter.Config[] = [\n // React plugin\n plugins.react,\n // React hooks plugin\n plugins.reactHooks,\n // React JSX A11y plugin\n plugins.reactA11y,\n // Airbnb React recommended config\n ...configs.react.recommended,\n {\n name: 'react-custom',\n rules: {\n 'jsx-a11y/control-has-associated-label': 'off',\n 'jsx-a11y/no-autofocus': 'off',\n 'react/boolean-prop-naming': [\n 'error',\n {\n propTypeNames: ['bool', 'mutuallyExclusiveTrueProps'],\n rule: '^((can|has|hide|is|show)[A-Z]([A-Za-z0-9]?)+|(checked|disabled|hide|required|show))',\n },\n ],\n 'react/function-component-definition': 'off',\n 'react/jsx-boolean-value': ['error', 'always'],\n 'react/jsx-curly-brace-presence': 'error',\n 'react/jsx-filename-extension': 'off',\n 'react/jsx-fragments': 'error',\n // off by default because it doesn't handle props onXyz function names correctly\n // turn this on from time to time to check for misnamed handlers elsewhere\n 'react/jsx-handler-names': ['off', {checkLocalVariables: true}],\n 'react/jsx-newline': ['error', {prevent: true}],\n 'react/jsx-no-useless-fragment': ['error', {allowExpressions: true}],\n 'react/no-children-prop': 'off',\n 'react/no-danger': 'off',\n 'react/prop-types': 'off',\n 'react/react-in-jsx-scope': 'off',\n 'react/require-default-props': 'off',\n },\n },\n // A module that exports anything besides components cannot be hot-swapped:\n // Fast Refresh falls back to a full reload and drops component state. Test\n // and story files, and the helpers beside them in `tests/` folders, are never\n // hot-swapped as components, so they are exempt.\n {\n files: ['**/*.tsx', '**/*.jsx'],\n ignores: ['**/*.test.ts?(x)', '**/*.stories.ts?(x)', '**/tests/**'],\n name: 'react-refresh',\n plugins: {'react-refresh': reactRefresh},\n rules: {\n 'react-refresh/only-export-components': [\n 'error',\n ONLY_EXPORT_COMPONENTS_OPTIONS,\n ],\n },\n },\n // Effects that should not be Effects: state derived from other state or\n // props, user-event logic, chained updates, notifying a parent, resetting\n // state on a prop change (use `key`), and hand-rolled store subscriptions\n // (use `useSyncExternalStore`). Complements `react-hooks/set-state-in-effect`.\n {\n files: ['**/*.ts?(x)', '**/*.js?(x)'],\n name: 'react-you-might-not-need-an-effect',\n plugins: {\n 'react-you-might-not-need-an-effect':\n youMightNotNeedAnEffect as unknown as ESLint.Plugin,\n },\n rules: {\n 'react-you-might-not-need-an-effect/no-adjust-state-on-prop-change':\n 'error',\n 'react-you-might-not-need-an-effect/no-chain-state-updates': 'error',\n 'react-you-might-not-need-an-effect/no-derived-state': 'error',\n 'react-you-might-not-need-an-effect/no-event-handler': 'error',\n 'react-you-might-not-need-an-effect/no-external-store-subscription':\n 'error',\n 'react-you-might-not-need-an-effect/no-initialize-state': 'error',\n 'react-you-might-not-need-an-effect/no-pass-data-to-parent': 'error',\n 'react-you-might-not-need-an-effect/no-pass-live-state-to-parent':\n 'error',\n 'react-you-might-not-need-an-effect/no-reset-all-state-on-prop-change':\n 'error',\n },\n },\n // Nine rules from @eslint-react, not its preset: the preset re-enables hook\n // rules `react-hooks` already owns. An Effect that adds a listener, timer,\n // interval, observer or fetch must tear it down in its cleanup (a fetch\n // through an AbortController). React 19 forms only: `ref` as a prop instead\n // of `forwardRef`, `use(Context)` instead of `useContext`, and `<Context>`\n // instead of `<Context.Provider>`. `no-context-provider` matches by name, so\n // it reports `ThemeContext.Provider` but not `Ctx.Provider`.\n {\n files: ['**/*.ts?(x)', '**/*.js?(x)'],\n name: 'eslint-react',\n plugins: {'@eslint-react': eslintReact as unknown as ESLint.Plugin},\n rules: {\n '@eslint-react/no-context-provider': 'error',\n '@eslint-react/no-forward-ref': 'error',\n '@eslint-react/no-use-context': 'error',\n '@eslint-react/web-api-no-leaked-event-listener': 'error',\n '@eslint-react/web-api-no-leaked-fetch': 'error',\n '@eslint-react/web-api-no-leaked-intersection-observer': 'error',\n '@eslint-react/web-api-no-leaked-interval': 'error',\n '@eslint-react/web-api-no-leaked-resize-observer': 'error',\n '@eslint-react/web-api-no-leaked-timeout': 'error',\n },\n },\n {\n files: ['**/*.test.ts?(x)', '**/*.stories.ts?(x)'],\n name: 'react/test-files',\n rules: {\n 'react/jsx-props-no-spreading': 'off',\n },\n },\n];\n","import type {ESLint, Rule} from 'eslint';\n\n// Each banned TanStack Query method, mapped to the `queryClient` method a\n// clientLoader awaits in its place.\nconst BANNED_METHODS = new Map([\n ['ensureInfiniteQueryData', 'infiniteQuery'],\n ['ensureQueryData', 'query'],\n ['fetchInfiniteQuery', 'infiniteQuery'],\n ['fetchQuery', 'query'],\n ['prefetchInfiniteQuery', 'infiniteQuery'],\n ['prefetchQuery', 'query'],\n]);\n\nconst getPropertyName = (callee: Rule.Node): string | undefined => {\n if (callee.type !== 'MemberExpression') {\n return undefined;\n }\n\n const {computed, property} = callee;\n\n if (!computed && property.type === 'Identifier') {\n return property.name;\n }\n\n if (\n computed &&\n property.type === 'Literal' &&\n typeof property.value === 'string'\n ) {\n return property.value;\n }\n\n return undefined;\n};\n\nconst noImperativeQueryFetchRule: Rule.RuleModule = {\n create: (context) => ({\n CallExpression: (node) => {\n const method = getPropertyName(node.callee as Rule.Node);\n const replacement = method && BANNED_METHODS.get(method);\n\n if (method && replacement) {\n context.report({\n data: {method, replacement},\n messageId: 'banned',\n node,\n });\n }\n },\n }),\n meta: {\n docs: {\n description:\n 'Disallow imperative TanStack Query fetches; await queryClient.query in a clientLoader and read with useSuspenseQuery',\n },\n messages: {\n banned:\n '`{{method}}` is banned. Await `queryClient.{{replacement}}(options)` in a clientLoader and read the data with `useSuspenseQuery(options)` in the component.',\n },\n schema: [],\n type: 'problem',\n },\n};\n\nconst plugin: ESLint.Plugin = {\n meta: {\n name: 'no-imperative-query-fetch',\n version: '0.1.0',\n },\n rules: {\n 'no-imperative-query-fetch': noImperativeQueryFetchRule,\n },\n};\n\nexport default plugin;\n","import type {Linter} from 'eslint';\nimport noImperativeQueryFetchPlugin from '../plugins/no-imperative-query-fetch.js';\nimport {ONLY_EXPORT_COMPONENTS_OPTIONS} from './react.js';\n\n/**\n * The named exports React Router reads from a route module. Its Vite plugin\n * hot-updates these alongside the component, so they do not cost a full\n * reload.\n */\nconst ROUTE_MODULE_EXPORTS = [\n 'action',\n 'clientAction',\n 'clientLoader',\n 'clientMiddleware',\n 'ErrorBoundary',\n 'handle',\n 'headers',\n 'HydrateFallback',\n 'Layout',\n 'links',\n 'loader',\n 'meta',\n 'middleware',\n 'shouldRevalidate',\n];\n\n/**\n * React Router flat-config block. Optional, and required only for projects\n * running React Router in framework mode.\n *\n * Its route block is SUBTRACTIVE: it relaxes a rule the rest of the bundle\n * turns on, rather than adding rules the way `storybook` and `playwright` do. That\n * is why it ships separately instead of living inside `react`. Its glob,\n * `**\\/routes/**\\/*.tsx`, is not unique to React Router (TanStack Router uses\n * a `routes/` directory too), so folding it into `react` would silently\n * weaken lint for every file-based router that isn't React Router.\n *\n * Spread it after `react`:\n *\n * ...lint.react,\n * ...lint.reactRouter,\n *\n * `no-empty-pattern` is off because a React Router route module destructures\n * nothing from its typed props (`({}: Route.ComponentProps)`), which the rule\n * reads as an empty pattern. TanStack Router names its component\n * (`createFileRoute(...)({component: Named})`) and never produces that shape,\n * so a TanStack project wants the rule left on.\n *\n * It also carries one ADDITIVE rule, `no-imperative-query-fetch`, on every\n * TypeScript file under the source dir. It bans `ensureQueryData`,\n * `fetchQuery`, `prefetchQuery` and their infinite variants, so a route has\n * one fetch idiom: `queryClient.query` awaited in a clientLoader, read with\n * `useSuspenseQuery`. That idiom is React Router's, which is why the rule\n * lives here. It reports on any member call by name, so it needs no TanStack\n * Query install to fire.\n *\n * Route modules, and `root.tsx` (the root route), may also export React\n * Router's route-module names (`loader`, `action`, `meta`, ...) beside their\n * component without tripping `react-refresh/only-export-components`.\n */\nexport const buildReactRouter = (sourceDir: string): Linter.Config[] => [\n {\n files: ['**/routes/**/*.tsx'],\n name: 'react-router/routes',\n rules: {\n 'no-empty-pattern': 'off',\n },\n },\n {\n files: ['**/routes/**/*.tsx', `${sourceDir}/root.tsx`],\n ignores: ['**/*.test.tsx', '**/*.stories.tsx', '**/tests/**'],\n name: 'react-router/route-module-exports',\n rules: {\n 'react-refresh/only-export-components': [\n 'error',\n {...ONLY_EXPORT_COMPONENTS_OPTIONS, allowExportNames: ROUTE_MODULE_EXPORTS},\n ],\n },\n },\n {\n files: [`${sourceDir}/**/*.ts?(x)`],\n name: 'react-router/no-imperative-query-fetch',\n plugins: {'no-imperative-query-fetch': noImperativeQueryFetchPlugin},\n rules: {\n 'no-imperative-query-fetch/no-imperative-query-fetch': 'error',\n },\n },\n];\n","import {plugin as shadcnPlugin} from '@shadcn/lint';\nimport type {ESLint, Linter} from 'eslint';\nimport {RESTRICTED_IMPORT_PATHS} from './restricted-imports.js';\n\nexport type GaiaLintShadcnOptions = {\n /**\n * Fallback: globs where `shadcn/no-restyle` is off outside the vendored ui\n * folder (GAIA-owned components that restyle on purpose). The fallback block\n * always ignores `${sourceDir}/components/ui/**`, so it can never reach the\n * GAIA-authored `ui/tests/**` files.\n *\n * @default []\n */\n restyleOffFiles?: string[];\n /**\n * Import alias of the vendored ui folder. Written to the root-level\n * `settings.shadcn.ui`, never to a rule option, so a later Oxlint config\n * reads it unchanged.\n *\n * @default '~/components/ui'\n */\n ui?: string;\n /**\n * Globs of the vendored files (shadcn registry output kept byte-identical\n * to `shadcn add`). Never matches `ui/tests/**`.\n *\n * @default [`${sourceDir}/components/ui/*.tsx`, ...the registry helpers\n * shadcn writes outside the ui folder (`VENDORED_HELPER_FILES`)]\n */\n uiFiles?: string[];\n};\n\nconst SOURCE_EXTENSIONS = '{js,jsx,ts,tsx}';\n\n/**\n * A class whose arbitrary value is a color literal: hex, a CSS color function,\n * or a `color:` type hint.\n */\nconst ARBITRARY_COLOR_PATTERN = String.raw`^.*\\[(#|rgba?\\(|hsla?\\(|oklch\\(|oklab\\(|lab\\(|lch\\(|color:).*\\]$`;\n\n/**\n * Registry helpers `shadcn add` writes outside the ui folder, relative to the\n * source directory: `use-mobile` (sidebar), and `use-highlighted-code` and\n * `highlighter` (code-block). Exact paths, so a GAIA-authored hook or util\n * beside them keeps every rule.\n */\nconst VENDORED_HELPER_FILES = [\n 'hooks/use-highlighted-code.ts',\n 'hooks/use-mobile.ts',\n 'utils/highlighter.tsx',\n];\n\n/**\n * Rules turned off for vendored files because shadcn's registry output trips\n * them. The list covers the full registry: every rule that fired on unedited\n * `shadcn add --all` output (shadcn 4.22.0, swept 2026-10-22). Style rules\n * come first, then the correctness-class rules the maintainer sanctioned off\n * for vendored output, each with the stock file it covers.\n *\n * Correctness rules not listed here (`react-hooks/rules-of-hooks`,\n * `react-hooks/exhaustive-deps`, `shadcn/no-raw-colors`, and every other rule)\n * stay on.\n */\nconst VENDORED_UI_RULES_OFF: Linter.RulesRecord = {\n // shadcn renders `<Context.Provider>` and calls `useContext` (carousel,\n // chart, drawer, input-otp, sidebar, toggle-group).\n '@eslint-react/no-context-provider': 'off',\n '@eslint-react/no-use-context': 'off',\n '@stylistic/padding-line-between-statements': 'off',\n // shadcn emits double-quoted strings.\n '@stylistic/quotes': 'off',\n // shadcn writes `Array<T>`.\n '@typescript-eslint/array-type': 'off',\n // Helper exports carry inferred return types (use-mobile, highlighter).\n '@typescript-eslint/explicit-module-boundary-types': 'off',\n // toggle-group.tsx: `import { type VariantProps } from ...`.\n '@typescript-eslint/no-import-type-side-effects': 'off',\n // chart.tsx: `payload[key as keyof typeof payload] as string`.\n '@typescript-eslint/no-unnecessary-type-assertion': 'off',\n // shadcn function declarations use a variable before its declaration\n // (hoisted, no runtime effect), e.g. select.tsx.\n '@typescript-eslint/naming-convention': 'off',\n '@typescript-eslint/no-use-before-define': 'off',\n // toggle-group.tsx falls back from context to props with `||`.\n '@typescript-eslint/prefer-nullish-coalescing': 'off',\n // toast.tsx re-exports namespace members as `const a = Namespace.a`.\n '@typescript-eslint/prefer-destructuring': 'off',\n // The useMemo callback in field.tsx is flagged; a stylistic async annotation.\n '@typescript-eslint/promise-function-async': 'off',\n // calendar.tsx and sidebar.tsx arrow bodies are blocks.\n 'arrow-body-style': 'off',\n // Tailwind class rewrites would change vendored class strings.\n 'better-tailwindcss/enforce-canonical-classes': 'off',\n 'better-tailwindcss/enforce-shorthand-classes': 'off',\n 'better-tailwindcss/no-deprecated-classes': 'off',\n // shadcn writes `export { A, B }` on one line.\n 'canonical/export-specifier-newline': 'off',\n // chart.tsx passes an object to `cn`.\n 'cn-conditional/cn-conditional': 'off',\n // shadcn uses inline `type` specifiers (`import {cva, type VariantProps}`).\n 'import-x/consistent-type-specifier-style': 'off',\n // shadcn renders null from field.tsx.\n 'no-null-render/no-null-render': 'off',\n // `_values` in slider.tsx.\n 'no-underscore-dangle': 'off',\n // carousel.tsx: `{ api: api, ... }`.\n 'object-shorthand': 'off',\n 'perfectionist/sort-imports': 'off',\n 'perfectionist/sort-intersection-types': 'off',\n 'perfectionist/sort-jsx-props': 'off',\n 'perfectionist/sort-modules': 'off',\n 'perfectionist/sort-named-exports': 'off',\n 'perfectionist/sort-named-imports': 'off',\n 'perfectionist/sort-object-types': 'off',\n 'perfectionist/sort-objects': 'off',\n 'perfectionist/sort-union-types': 'off',\n // shadcn components are `function` declarations.\n 'prefer-arrow-functions/prefer-arrow-functions': 'off',\n // Vendored output is never reformatted; it stays byte-identical to\n // `shadcn add`.\n 'prettier/prettier': 'off',\n // Prop names such as `inset` (dropdown-menu).\n 'react/boolean-prop-naming': 'off',\n // pagination.tsx: a bare `aria-hidden`.\n 'react/jsx-boolean-value': 'off',\n // button.tsx exports `buttonVariants` and toast.tsx exports its toast\n // manager beside their components. A hot update of either falls back to a\n // full reload, which costs dev time only.\n 'react-refresh/only-export-components': 'off',\n // `prop?: T | undefined` (calendar, carousel).\n 'sonarjs/no-redundant-optional': 'off',\n 'sonarjs/prefer-read-only-props': 'off',\n // chart.tsx: `!payload?.length`, `.replace(/.../g)`, negated ternaries.\n 'unicorn/explicit-length-check': 'off',\n 'unicorn/no-negated-condition': 'off',\n 'unicorn/prefer-string-replace-all': 'off',\n // The `e` handler parameter in input-group.tsx.\n 'unicorn/prevent-abbreviations': 'off',\n // Sanctioned correctness-class exemptions for vendored output. Each one\n // trips a pattern in the shadcn source that GAIA does not edit.\n // sidebar.tsx: `toggleSidebar` returns the setter's void result.\n '@typescript-eslint/no-confusing-void-expression': 'off',\n // calendar.tsx, carousel.tsx, chart.tsx, sidebar.tsx reuse an outer name\n // (`props`, `className`, `api`, `config`, `open`) in a nested callback.\n '@typescript-eslint/no-shadow': 'off',\n // field.tsx FieldError: `uniqueErrors?.length` optional chain on a non-nullish array.\n '@typescript-eslint/no-unnecessary-condition': 'off',\n // chart.tsx reads recharts payload items, typed `any` upstream.\n '@typescript-eslint/no-unsafe-argument': 'off',\n '@typescript-eslint/no-unsafe-assignment': 'off',\n '@typescript-eslint/no-unsafe-member-access': 'off',\n '@typescript-eslint/restrict-template-expressions': 'off',\n // field.tsx FieldError: `uniqueErrors?.length == 1`.\n eqeqeq: 'off',\n // pagination.tsx: PaginationLink's anchor gets its content through spread\n // `children`, which the rule cannot see.\n 'jsx-a11y/anchor-has-content': 'off',\n // input-group.tsx: InputGroupAddon div with an onClick that focuses the input.\n 'jsx-a11y/click-events-have-key-events': 'off',\n // label.tsx: the generic Label primitive renders a <label> with no static control.\n 'jsx-a11y/label-has-associated-control': 'off',\n // input-group.tsx: the role=\"group\" div with an onClick.\n 'jsx-a11y/no-noninteractive-element-interactions': 'off',\n // code-block.tsx: a scrollable <pre> takes `tabIndex={0}` so the keyboard\n // can scroll it.\n 'jsx-a11y/no-noninteractive-tabindex': 'off',\n // carousel.tsx syncs Embla's selection into state from an effect;\n // use-mobile.ts reads `matchMedia` into state on mount.\n 'react-hooks/set-state-in-effect': 'off',\n // calendar.tsx and carousel.tsx call a prop callback from an effect;\n // use-mobile.ts subscribes to `matchMedia` and initializes state from it.\n 'react-you-might-not-need-an-effect/no-event-handler': 'off',\n 'react-you-might-not-need-an-effect/no-external-store-subscription': 'off',\n 'react-you-might-not-need-an-effect/no-initialize-state': 'off',\n 'react-you-might-not-need-an-effect/no-pass-data-to-parent': 'off',\n // sidebar.tsx: SidebarRail's <button> carries no `type`.\n 'react/button-has-type': 'off',\n // carousel.tsx, chart.tsx, toggle-group.tsx pass an inline object to a\n // context provider.\n 'react/jsx-no-constructed-context-values': 'off',\n // field.tsx FieldError: `<li key={index}>` over a static deduped error list.\n 'react/no-array-index-key': 'off',\n // calendar.tsx defines DayPicker's `components` slots inline.\n 'react/no-unstable-nested-components': 'off',\n // sidebar.tsx: SidebarMenuSkeleton picks a random skeleton width.\n 'sonarjs/pseudo-random': 'off',\n // sidebar.tsx persists the open state in a cookie.\n 'unicorn/no-document-cookie': 'off',\n // input-group.tsx: a `<Button>` className built dynamically. `no-raw-colors`\n // still reads those files.\n 'shadcn/require-static-classes': 'off',\n // shadcn writes `import * as React from 'react'`, which the core rule\n // reports against the `FC` ban because a namespace import could reach those\n // names. The block re-declares the shared bans minus the `react` entry\n // (options replace wholesale across blocks), so the other bans hold.\n 'no-restricted-imports': [\n 'error',\n {paths: RESTRICTED_IMPORT_PATHS.filter((entry) => entry.name !== 'react')},\n ],\n // Registry items may carry an arbitrary color the token contract bans.\n 'better-tailwindcss/no-restricted-classes': 'off',\n // input-otp.tsx and navigation-menu.tsx carry registry classes GAIA's theme\n // does not define (`cn-input-otp`, `xs:`, `easing-[ease]`).\n 'better-tailwindcss/no-unknown-classes': 'off',\n // sonner.tsx sets CSS variables through a `style` object.\n 'shadcn/no-inline-styles': 'off',\n // The vendored files compose each other with `className`.\n 'shadcn/no-restyle': 'off',\n};\n\n/**\n * `@shadcn/lint` flat-config factory (opt-in).\n *\n * Makes role tokens the only color vocabulary for GAIA components and exempts\n * the vendored shadcn ui files from house style. Returns these blocks:\n *\n * - `shadcn/settings`: no `files`; registers the plugin and sets\n * `settings.shadcn.ui` at root level.\n * - `shadcn/rules`: source files; `no-raw-colors`, `require-static-classes`,\n * `no-inline-styles` error, `no-restyle` error with `{allow: ['layout']}`,\n * `no-arbitrary-values` and `no-unknown-classes` off (better-tailwindcss's\n * `no-unknown-classes` stays the only unknown-class rule), and\n * `better-tailwindcss/no-restricted-classes` banning arbitrary colors.\n * - `shadcn/vendored-ui`: `uiFiles` only; `prettier/prettier` and the house\n * style rules (plus the maintainer-sanctioned correctness-class rules the\n * shadcn source trips) off. `shadcn/no-raw-colors`,\n * `react-hooks/rules-of-hooks`, `react-hooks/exhaustive-deps` and every\n * other correctness rule stay on.\n * - `shadcn/restyle-fallback`: only when `restyleOffFiles` is non-empty.\n *\n * ORDERING: the vendored-ui block names rules from plugins the other GAIA\n * blocks register (prettier, prefer-arrow-functions, perfectionist, unicorn,\n * better-tailwindcss, ...), so spread the full GAIA composition before it, and\n * spread `shadcn()` LAST, after `...lint.prettier`, so its `prettier/prettier:\n * off` wins on vendored files.\n *\n * @example\n * ...lint.shadcn({ui: '~/components/ui'})\n */\nexport const buildShadcn = (\n sourceDir: string,\n opts?: GaiaLintShadcnOptions,\n): Linter.Config[] => {\n const ui = opts?.ui ?? '~/components/ui';\n const uiFiles = opts?.uiFiles ?? [\n `${sourceDir}/components/ui/*.tsx`,\n ...VENDORED_HELPER_FILES.map((file) => `${sourceDir}/${file}`),\n ];\n const restyleOffFiles = opts?.restyleOffFiles ?? [];\n\n const configs: Linter.Config[] = [\n {\n name: 'shadcn/settings',\n plugins: {shadcn: shadcnPlugin as unknown as ESLint.Plugin},\n settings: {shadcn: {ui}},\n },\n {\n files: [`${sourceDir}/**/*.${SOURCE_EXTENSIONS}`],\n name: 'shadcn/rules',\n rules: {\n // An arbitrary value is allowed where no scale step or token fits;\n // `enforce-canonical-classes` still rewrites one that has a scale\n // equivalent. An arbitrary color is banned: colors are role tokens.\n 'better-tailwindcss/no-restricted-classes': [\n 'error',\n {\n restrict: [\n {\n message:\n 'Arbitrary colors are not allowed; use a theme role token.',\n pattern: ARBITRARY_COLOR_PATTERN,\n },\n ],\n },\n ],\n 'shadcn/no-arbitrary-values': 'off',\n 'shadcn/no-inline-styles': 'error',\n 'shadcn/no-raw-colors': 'error',\n 'shadcn/no-restyle': ['error', {allow: ['layout']}],\n // better-tailwindcss/no-unknown-classes stays the only unknown-class rule.\n 'shadcn/no-unknown-classes': 'off',\n 'shadcn/require-static-classes': 'error',\n },\n },\n {\n files: uiFiles,\n name: 'shadcn/vendored-ui',\n rules: VENDORED_UI_RULES_OFF,\n },\n ];\n\n if (restyleOffFiles.length > 0) {\n configs.push({\n files: restyleOffFiles,\n // The vendored ui folder (and with it `ui/tests/**`) is never reached.\n ignores: [`${sourceDir}/components/ui/**`],\n name: 'shadcn/restyle-fallback',\n rules: {'shadcn/no-restyle': 'off'},\n });\n }\n\n return configs;\n};\n","import storybookPlugin from 'eslint-plugin-storybook';\nimport type {Linter} from 'eslint';\n\n/**\n * Storybook flat-config block.\n *\n * Ports `storybookConfig` from GAIA's `eslint.config.mjs` — applies the\n * official `flat/recommended` config from `eslint-plugin-storybook`.\n */\nexport const storybook: Linter.Config[] = [\n ...(storybookPlugin.configs['flat/recommended'] as Linter.Config[]),\n];\n","import type {Linter} from 'eslint';\nimport canonical from 'eslint-plugin-canonical';\nimport checkFile from 'eslint-plugin-check-file';\nimport perfectionist from 'eslint-plugin-perfectionist';\nimport unicorn from 'eslint-plugin-unicorn';\nimport unusedImports from 'eslint-plugin-unused-imports';\n\nconst buildCanonicalConfig = (sourceDir: string): Linter.Config[] => [\n canonical.configs['flat/recommended'] as Linter.Config,\n {\n name: 'canonical',\n rules: {\n 'canonical/destructuring-property-newline': 'off',\n 'canonical/filename-match-exported': 'error',\n 'canonical/id-match': 'off',\n 'canonical/import-specifier-newline': 'off',\n },\n },\n {\n // Component and page folders are kebab-case while their default export is\n // PascalCase, so `theme-switch/index.tsx` exports `ThemeSwitch`. Scoped to\n // these folders only: a global kebab transform would reject `i18n.ts`\n // exporting `i18n` (lodash kebabs it to `i-18-n`).\n files: [`${sourceDir}/components/**/*.tsx`, `${sourceDir}/pages/**/*.tsx`],\n name: 'canonical/filename-match-exported-kebab',\n rules: {\n 'canonical/filename-match-exported': ['error', {transforms: ['kebab']}],\n },\n },\n {\n files: ['**/*.tsx', '**/hooks/*.ts?(x)'],\n name: 'canonical/sort-react-dependencies',\n rules: {\n 'canonical/sort-react-dependencies': 'error',\n },\n },\n {\n files: [\n `${sourceDir}/root.tsx`,\n `${sourceDir}/entry.server.tsx`,\n // A route page exports `<Name>Page` from `page.tsx`\n `${sourceDir}/pages/**/page.tsx`,\n `${sourceDir}/**/tests/*`,\n 'test/**/*.ts?(x)',\n '**/*.stories.tsx',\n '**/routes/**/*.tsx',\n '**/hooks/*.ts?(x)',\n '.storybook/**/*.ts?(x)',\n '.playwright/**/*.ts?(x)',\n ],\n name: 'canonical/filename-match-exported-disabled',\n rules: {\n 'canonical/filename-match-exported': 'off',\n },\n },\n];\n\nconst perfectionistConfig: Linter.Config[] = [\n perfectionist.configs['recommended-natural'] as Linter.Config,\n {\n name: 'perfectionist',\n rules: {\n 'perfectionist/sort-imports': [\n 'error',\n {\n customGroups: [\n {\n elementNamePattern: '^react$',\n groupName: 'react-type',\n selector: 'type',\n },\n {\n elementNamePattern: '^react$',\n groupName: 'react',\n },\n {\n elementNamePattern: '^react-.+',\n groupName: 'react-other-type',\n selector: 'type',\n },\n {\n elementNamePattern: '^react-.+',\n groupName: 'react-other',\n },\n ],\n groups: [\n 'react-type',\n 'react',\n 'react-other-type',\n 'react-other',\n ['type-external', 'external'],\n ['type-builtin', 'builtin'],\n ['type-internal', 'internal'],\n ['type-parent', 'parent'],\n ['type-sibling', 'sibling'],\n ['type-index', 'index'],\n 'unknown',\n 'style',\n 'side-effect',\n 'side-effect-style',\n ],\n newlinesBetween: 0,\n type: 'natural',\n },\n ],\n 'perfectionist/sort-jsx-props': [\n 'error',\n {\n customGroups: [\n {\n elementNamePattern: ['^key$', '^ref$'],\n groupName: 'reserved',\n },\n ],\n groups: ['reserved'],\n type: 'natural',\n },\n ],\n },\n },\n];\n\nconst unicornConfig: Linter.Config[] = [\n unicorn.configs.recommended as Linter.Config,\n {\n name: 'unicorn',\n rules: {\n 'unicorn/consistent-destructuring': 'error',\n 'unicorn/consistent-template-literal-escape': 'off',\n 'unicorn/filename-case': 'off',\n 'unicorn/new-for-builtins': 'off',\n 'unicorn/no-array-callback-reference': 'off',\n 'unicorn/no-array-for-each': 'off',\n 'unicorn/no-array-reduce': 'off',\n 'unicorn/no-nested-ternary': 'off',\n 'unicorn/no-null': 'off',\n 'unicorn/no-useless-undefined': 'off',\n 'unicorn/prefer-export-from': 'off',\n 'unicorn/prefer-global-this': 'off',\n // `Array#includes` returns a plain boolean, not a type predicate, so it\n // cannot narrow a union the way an `===` comparison chain does. In a typed\n // codebase the chain is the type-safe idiom; forcing `.includes()` discards\n // the narrowing and the value's refined type along with it.\n 'unicorn/prefer-includes-over-repeated-comparisons': 'off',\n 'unicorn/prefer-set-has': 'off',\n // Both gate on `definition.kind === 'const'`, which\n // @typescript-eslint/scope-manager never sets (the `const` lives on\n // `definition.parent.kind`), so under the TypeScript parser they cannot\n // report. Off states that instead of implying coverage.\n 'unicorn/no-blob-to-file': 'off',\n 'unicorn/prefer-set-size': 'off',\n 'unicorn/prefer-switch': 'off',\n 'unicorn/prefer-ternary': 'off',\n 'unicorn/prevent-abbreviations': [\n 'error',\n {\n ignore: [\n 'acc',\n 'ctx',\n 'e2e',\n 'env',\n 'obj',\n 'prev',\n 'req',\n 'res',\n /args/i,\n /fn/i,\n /param/i,\n /params/i,\n /props/i,\n /ref/i,\n /src/i,\n /utils/i,\n ],\n },\n ],\n 'unicorn/text-encoding-identifier-case': 'off',\n },\n },\n {\n files: ['./*.ts'],\n name: 'unicorn/root-ts-files',\n rules: {\n 'unicorn/prefer-module': 'off',\n 'unicorn/prevent-abbreviations': 'off',\n },\n },\n];\n\nconst unusedImportsConfig: Linter.Config[] = [\n {\n name: 'unused-imports',\n plugins: {\n 'unused-imports': unusedImports,\n },\n rules: {\n '@typescript-eslint/no-unused-vars': 'off',\n 'no-unused-vars': 'off',\n 'sonarjs/no-unused-vars': 'off',\n 'sonarjs/unused-import': 'off',\n 'unused-imports/no-unused-imports': 'error',\n 'unused-imports/no-unused-vars': [\n 'error',\n {\n args: 'after-used',\n argsIgnorePattern: '^_',\n ignoreRestSiblings: true,\n vars: 'all',\n varsIgnorePattern: '^_',\n },\n ],\n },\n },\n {\n files: ['**/*.d.ts'],\n name: 'unused-imports/ts-definition-files',\n rules: {\n 'unused-imports/no-unused-vars': 'off',\n },\n },\n];\n\n// Subfolders a component or page folder may hold besides nested components.\nconst RESERVED_FOLDERS = '(assets|hooks|state|tests|utils)';\n\n// The same, plus ui/, whose flat files are not named index.tsx.\nconst RESERVED_AND_UI_FOLDERS = '(assets|hooks|state|tests|ui|utils)';\n\n// Matches one folder segment that is not exactly one of `names`. micromatch's\n// `!(a|b)` alone excludes every segment that merely starts with `a` or `b`\n// (`statement` for `state`), so names extending a reserved word are added back.\nconst notExactly = (names: string): string => `{!${names},@${names}+([a-z0-9-])}`;\n\nconst buildCheckFileConfig = (sourceDir: string): Linter.Config[] => [\n {\n plugins: {\n 'check-file': checkFile,\n },\n },\n {\n files: [`${sourceDir}/**/*`],\n name: 'check-file',\n rules: {\n 'check-file/filename-naming-convention': [\n 'error',\n {\n // React hook files are kebab-case with a `use-` prefix (use-theme.ts)\n '**/hooks/*.{ts,tsx}': 'use-+([a-z0-9])*(-+([a-z0-9]))',\n [`${sourceDir}/state/*.tsx`]: 'KEBAB_CASE',\n // Components live in folders, never directly in components/\n [`${sourceDir}/components/*.tsx`]: '!(*)',\n // components/ui/ holds flat kebab-case component files (button.tsx)\n [`${sourceDir}/components/ui/*.tsx`]: 'KEBAB_CASE',\n // Every other component file is named index.tsx\n [`${sourceDir}/components/**/${notExactly(RESERVED_AND_UI_FOLDERS)}/*.tsx`]:\n 'index+()',\n // A page folder holds its route page.tsx, or index.tsx for colocated components\n [`${sourceDir}/pages/**/${notExactly(RESERVED_FOLDERS)}/*.tsx`]:\n '@(index|page)',\n // Generally, non-component files must be named kebab-case\n [`${sourceDir}/{components,pages}/**/!(hooks)/*.ts`]: 'KEBAB_CASE',\n // Non-component files inside specific components folders must be kebab-case\n [`${sourceDir}/{components,pages}/**/(assets|state|tests|utils)/*.{ts,tsx}`]:\n 'KEBAB_CASE',\n 'test/**/*.ts?(x)': 'KEBAB_CASE',\n },\n {\n ignoreMiddleExtensions: true,\n },\n ],\n 'check-file/folder-match-with-fex': [\n 'error',\n {\n // require stories and test files to be inside tests folders\n '*.(stories|test).{ts,tsx}': `${sourceDir}/**/tests/`,\n },\n ],\n 'check-file/folder-naming-convention': [\n 'error',\n {\n // enforce kebab-case component and page folders; the reserved\n // assets, hooks, state, tests, and utils subfolders are kebab-case too\n [`${sourceDir}/components/**/`]: 'KEBAB_CASE',\n [`${sourceDir}/pages/**/`]: 'KEBAB_CASE',\n // components/ui/ is flat: tests/ is its only subfolder\n [`${sourceDir}/components/ui/*/`]: '@(tests)',\n },\n ],\n },\n },\n {\n files: ['test/**/*.*'],\n name: 'check-file/test-files',\n rules: {\n 'check-file/filename-naming-convention': [\n 'error',\n {\n 'test/**/*.ts?(x)': 'KEBAB_CASE',\n },\n {\n ignoreMiddleExtensions: true,\n },\n ],\n },\n },\n];\n\nexport const buildStyleHygiene = (sourceDir: string): Linter.Config[] => [\n ...buildCanonicalConfig(sourceDir),\n ...perfectionistConfig,\n ...unicornConfig,\n ...unusedImportsConfig,\n ...buildCheckFileConfig(sourceDir),\n];\n","import vitest from '@vitest/eslint-plugin';\nimport jestDom from 'eslint-plugin-jest-dom';\nimport {RESTRICTED_IMPORT_PATHS} from './restricted-imports.js';\nimport type {Linter} from 'eslint';\n\n/**\n * Testing flat-config block.\n *\n * Ports `testHarnessConfig` + `testingLibraryConfig` from GAIA's\n * `eslint.config.mjs`. Wires up Vitest and jest-dom recommended rules\n * across test/story/test-harness files.\n */\nexport const testing: Linter.Config[] = [\n {\n files: [\n '**/*.test.ts?(x)',\n '**/*.stories.ts?(x)',\n 'test/**/*.ts?(x)',\n ],\n name: 'vitest',\n plugins: {\n 'jest-dom': jestDom,\n vitest,\n },\n rules: {\n ...jestDom.configs['flat/recommended'].rules,\n ...vitest.configs.recommended.rules,\n 'import-x/no-useless-path-segments': [\n 'error',\n {noUselessIndex: true},\n ],\n 'vitest/expect-expect': [\n 'error',\n {assertFunctionNames: ['expect', 'expect*']},\n ],\n // Baseline bump: `recommended` ships no-disabled-tests at `warn`.\n // .skip is the single biggest gaming vector for a RED-verification\n // gate (it makes a failing test stop failing), so GAIA forbids it\n // outright. Park work with test.todo or an inline eslint-disable, not\n // a silent .skip.\n 'vitest/no-disabled-tests': 'error',\n // --- Hardening beyond the `recommended` preset ---------------------\n // Rule names and options verified against @vitest/eslint-plugin\n // v1.6.19. GAIA policy: every lint rule is `error`, never `warn`.\n //\n // Consistency: GAIA uses test() exclusively (120 vs 0 it() across the\n // gaia codebase). In 1.6.19 the `fn` option cascades to the\n // within-describe keyword, so this also governs test()/it() nested in\n // describe blocks. Auto-fixable.\n 'vitest/consistent-test-it': ['error', {fn: 'test'}],\n // Consistency: GAIA uses the `vi` mock API (37 vs 0 `vitest.` across the\n // gaia codebase). Auto-fixable.\n 'vitest/consistent-vitest-vi': ['error', {fn: 'vi'}],\n // RED-gate: a branch in a test body can assert nothing on one path.\n // Enable ONLY this one; `no-conditional-tests` is a byte-identical\n // duplicate in 1.6.19 and would double-report.\n 'vitest/no-conditional-in-test': 'error',\n // RED-gate: fdescribe/fit/xdescribe/xit bypass the active\n // no-focused-tests / no-disabled-tests rules; forbid the prefix\n // spellings so the focus/skip net stays airtight. Auto-fixable.\n 'vitest/no-test-prefixes': 'error',\n // RED-gate: a returned value/promise can resolve after the test\n // \"passes\", swallowing assertions and faking GREEN.\n 'vitest/no-test-return-statement': 'error',\n // RED-gate: empty test('...') stubs pass green and read as coverage;\n // rewrite to test.todo('...') so the gap is explicit. Contradicts\n // `warn-todo`, which stays off. Auto-fixable.\n 'vitest/prefer-todo': 'error',\n // Honesty (D-8 / SPEC-006 Rule 3, the cheap-win stand-in for\n // `gaia-test-honesty/no-call-through-only`). A bare\n // `toHaveBeenCalled()`/`toBeCalled()` proves the function ran but\n // asserts nothing about how (arguments) or how many (count) — a\n // call-through that re-proves the framework, not the behavior.\n //\n // SCOPE NOTE: `prefer-called-with` is BROADER than spec Rule 3. The spec\n // rule fires only when a bare `toHaveBeenCalled()` is the SOLE assertion\n // in a test; `prefer-called-with` fires on EVERY bare\n // `toHaveBeenCalled()`/`toBeCalled()` (it exempts only the `.not` form).\n // So this stands in for Rule 3 rather than matching it exactly.\n 'vitest/prefer-called-with': 'error',\n // A bare .toThrow() passes on ANY throw, masking the wrong error;\n // require an asserted message or matcher.\n 'vitest/require-to-throw-message': 'error',\n },\n },\n {\n // Honesty (D-8 / SPEC-006 Rule 4, the cheap-win stand-in for\n // `gaia-test-honesty/no-server-import-from-consumer`). A consumer test,\n // story, or harness file must not import a server-only (`*.server`) or\n // internal (`/internals/`) module: those are private surface, and\n // reaching into them couples the test to implementation the public\n // interface is meant to hide.\n //\n // Same testing glob as the `vitest` block above. The `*.server.test.*`\n // exemption is the point of Rule 4: a dedicated server-side test IS the\n // right place to import a `.server` module (mirrors the real\n // `app/utils/tests/http.server.test.ts` importing `../http.server`).\n //\n // Implemented with the core `no-restricted-imports` rule (config only, no\n // custom plugin) rather than a dedicated AST rule. Chosen over\n // `import-x/no-restricted-paths` because Rule 4 keys off the import\n // SPECIFIER shape (`*.server`, `/internals/`) plus a per-file filename\n // exemption, not the directory `from`/`target` zones that\n // `no-restricted-paths` models.\n //\n // LIMITATION vs the would-be custom rule: `no-restricted-imports` covers\n // static `import` / `export ... from` only, NOT dynamic\n // `import('./x.server')`. The dynamic case is intentionally out of scope\n // for this cheap-win form; the advisory worthiness audit backstops it.\n //\n // ERROR severity, per spec (Rule 4 is an error rule).\n files: [\n '**/*.test.ts?(x)',\n '**/*.stories.ts?(x)',\n 'test/**/*.ts?(x)',\n ],\n ignores: ['**/*.server.test.*'],\n name: 'gaia-test-honesty/no-server-import-from-consumer',\n rules: {\n 'no-restricted-imports': [\n 'error',\n {\n // `paths` re-declares the global `@conform-to/zod` ban from base.ts.\n // Flat config replaces a rule's options wholesale, so this later\n // block would otherwise drop the conform ban on test/story files.\n // Same shared const as base.ts, to stay DRY.\n paths: RESTRICTED_IMPORT_PATHS,\n patterns: [\n {\n group: ['**/*.server'],\n message:\n \"Do not import a server-only ('*.server') module from a consumer test. Server-only modules are private surface: reach them through the public interface, or from a dedicated *.server.test.* file (which is exempt from this rule).\",\n },\n {\n group: ['**/internals/**', '**/internals'],\n message:\n \"Do not import an internal ('/internals/') module from a consumer test. Internal modules are private surface: importing them couples the test to implementation the public interface is meant to hide. Reach the behavior through the public interface instead.\",\n },\n ],\n },\n ],\n },\n },\n];\n","import zodPlugin from 'eslint-plugin-zod';\nimport type {ESLint, Linter} from 'eslint';\n\n/**\n * Zod flat-config block (opt-in), for Zod 4 projects.\n *\n * `eslint-plugin-zod`'s recommended set: conflicting or duplicate checks,\n * `.optional()` with `.default()`, a `throw` inside `.refine()`, a refine\n * without an error message (users see a generic \"Invalid input\"),\n * `z.nativeEnum`, `z.any()`, and the Zod 3 forms Zod 4 deprecates.\n *\n * `consistent-import` is off: it wants `import * as z from 'zod'` by default,\n * and even in `named` mode it reports a named `ZodError` import. The\n * stylistic set is not included; it pushes toward enums, which `no-zod-enum`\n * in `guardrails` bans.\n */\nexport const zod: Linter.Config[] = [\n {\n files: ['**/*.ts?(x)'],\n name: 'zod',\n plugins: {zod: zodPlugin as unknown as ESLint.Plugin},\n rules: {\n ...(zodPlugin.configs.recommended.rules as Linter.RulesRecord),\n 'zod/consistent-import': 'off',\n },\n },\n];\n","import type {Linter} from 'eslint';\nimport {buildBase} from './configs/base.js';\nimport {\n betterTailwind,\n type GaiaLintBetterTailwindOptions,\n} from './configs/better-tailwind.js';\nimport {buildGuardrails} from './configs/guardrails.js';\nimport {buildI18n} from './configs/i18n.js';\nimport {ignores, type GaiaLintIgnoresOptions} from './configs/ignores.js';\nimport {playwright} from './configs/playwright.js';\nimport {prettier} from './configs/prettier.js';\nimport {react} from './configs/react.js';\nimport {buildReactRouter} from './configs/react-router.js';\nimport {buildShadcn, type GaiaLintShadcnOptions} from './configs/shadcn.js';\nimport {storybook} from './configs/storybook.js';\nimport {buildStyleHygiene} from './configs/style-hygiene.js';\nimport {testing} from './configs/testing.js';\nimport {zod} from './configs/zod.js';\n\nexport type {\n GaiaLintBetterTailwindOptions,\n GaiaLintIgnoresOptions,\n GaiaLintShadcnOptions,\n};\n\nexport type GaiaLintOptions = {\n /**\n * Application source directory (relative to project root). Used to scope\n * file-path-based rules — filename conventions, hook-folder scoping,\n * `no-relative-import-paths` root, etc.\n *\n * @default 'app'\n */\n sourceDir?: string;\n};\n\n/**\n * Dual-shape `ignores` accessor. Spread it directly for the default\n * configuration (`...lint.ignores`) or call it to override\n * (`...lint.ignores({extra: ['coverage/**']})`).\n */\nexport type GaiaLintIgnores = ((\n opts?: GaiaLintIgnoresOptions,\n) => Linter.Config[]) &\n Iterable<Linter.Config>;\n\nexport type GaiaLintBundle = {\n base: Linter.Config[];\n betterTailwind: (opts: GaiaLintBetterTailwindOptions) => Linter.Config[];\n guardrails: Linter.Config[];\n /**\n * Opt-in `i18next/no-literal-string` (JSX text only) for projects that\n * translate their UI. Drop it when the project drops i18n.\n */\n i18n: Linter.Config[];\n ignores: GaiaLintIgnores;\n playwright: Linter.Config[];\n prettier: Linter.Config[];\n react: Linter.Config[];\n reactRouter: Linter.Config[];\n /**\n * Opt-in `@shadcn/lint` token rules plus the vendored-ui exemption. Assumes\n * the full GAIA composition is spread before it and must be the LAST entry,\n * after `...lint.prettier`.\n */\n shadcn: (opts?: GaiaLintShadcnOptions) => Linter.Config[];\n storybook: Linter.Config[];\n styleHygiene: Linter.Config[];\n testing: Linter.Config[];\n /** Opt-in `eslint-plugin-zod` recommended rules, for Zod 4 projects. */\n zod: Linter.Config[];\n};\n\nconst buildIgnoresAccessor = (): GaiaLintIgnores => {\n const defaults = ignores();\n const accessor = ((opts?: GaiaLintIgnoresOptions) => ignores(opts)) as\n | ((opts?: GaiaLintIgnoresOptions) => Linter.Config[]) &\n Iterable<Linter.Config> & {[Symbol.iterator]?: () => Iterator<Linter.Config>};\n accessor[Symbol.iterator] = () => defaults[Symbol.iterator]();\n return accessor as GaiaLintIgnores;\n};\n\n/**\n * GAIA lint configuration factory.\n *\n * Call once at the top of your `eslint.config.mjs` to bind a `sourceDir`,\n * then spread the returned configs into `defineConfig`. Defaults to GAIA's\n * `'app'` layout; pass `{sourceDir: 'src'}` (or any other value) for\n * projects that store source elsewhere.\n *\n * @example\n * const lint = gaiaLint(); // GAIA / app/\n * const lint = gaiaLint({sourceDir: 'src'}); // src/\n */\nconst gaiaLint = (opts?: GaiaLintOptions): GaiaLintBundle => {\n const sourceDir = opts?.sourceDir ?? 'app';\n return {\n base: buildBase(sourceDir),\n betterTailwind,\n guardrails: buildGuardrails(sourceDir),\n i18n: buildI18n(sourceDir),\n ignores: buildIgnoresAccessor(),\n playwright,\n prettier,\n react,\n reactRouter: buildReactRouter(sourceDir),\n shadcn: (shadcnOpts) => buildShadcn(sourceDir, shadcnOpts),\n storybook,\n styleHygiene: buildStyleHygiene(sourceDir),\n testing,\n zod,\n };\n};\n\nexport default gaiaLint;\n"],"mappings":"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","names":["plugin","plugin","plugin","plugin","plugin","path","configs","plugins","plugin","configs"]}
1
+ {"version":3,"sources":["../src/configs/base.ts","../src/configs/restricted-imports.ts","../src/configs/better-tailwind.ts","../src/configs/guardrails.ts","../src/plugins/cn-conditional.ts","../src/plugins/no-enum.ts","../src/plugins/no-jsx-iife.ts","../src/plugins/no-null-render.ts","../src/plugins/no-switch.ts","../src/plugins/no-zod-enum.ts","../src/configs/react-doctor.ts","../src/configs/i18n.ts","../src/configs/ignores.ts","../src/configs/playwright.ts","../src/configs/prettier.ts","../src/configs/react.ts","../src/configs/react-router.ts","../src/plugins/no-imperative-query-fetch.ts","../src/configs/shadcn.ts","../src/configs/storybook.ts","../src/configs/style-hygiene.ts","../src/configs/testing.ts","../src/configs/zod.ts","../src/index.ts"],"sourcesContent":["import eslintComments from '@eslint-community/eslint-plugin-eslint-comments/configs';\nimport js from '@eslint/js';\nimport {configs, plugins, rules} from 'eslint-config-airbnb-extended';\nimport preferArrowFunctions from 'eslint-plugin-prefer-arrow-functions';\nimport lodashUnderscore from 'eslint-plugin-you-dont-need-lodash-underscore';\nimport {RESTRICTED_IMPORT_PATHS} from './restricted-imports.js';\nimport type {ESLint, Linter} from 'eslint';\n\nconst jsConfig: Linter.Config[] = [\n // ESLint recommended config\n {\n name: 'js/config',\n ...js.configs.recommended,\n },\n // Stylistic plugin\n plugins.stylistic,\n // Import X plugin\n plugins.importX,\n // Airbnb base recommended config\n ...configs.base.recommended,\n // Strict import rules\n rules.base.importsStrict,\n];\n\nconst jsCustomConfig: Linter.Config[] = [\n {\n name: 'js-custom',\n rules: {\n 'consistent-return': 'off',\n curly: ['error', 'all'],\n 'max-params': 'error',\n 'no-param-reassign': 'off', // handled by sonarjs\n 'no-undef': 'off',\n 'no-unused-vars': 'off', // handled by sonarjs\n },\n },\n {\n files: ['**/*.test.ts?(x)', '**/*.stories.ts?(x)'],\n name: 'test-files/all',\n rules: {\n 'guard-for-in': 'off',\n 'max-params': 'off',\n 'no-await-in-loop': 'off',\n 'no-plusplus': 'off',\n 'no-restricted-syntax': 'off',\n },\n },\n {\n files: ['.playwright/**/*.ts?(x)'],\n name: 'playwright/all',\n rules: {\n 'no-await-in-loop': 'off',\n 'no-restricted-syntax': 'off',\n },\n },\n];\n\nconst typescriptConfig: Linter.Config[] = [\n // TypeScript ESLint plugin\n plugins.typescriptEslint,\n // Airbnb base TypeScript config\n ...configs.base.typescript,\n // Strict TypeScript rules\n rules.typescript.typescriptEslintStrict,\n rules.typescript.stylistic,\n // Airbnb React TypeScript config\n ...configs.react.typescript,\n {\n files: ['./*.ts'],\n name: 'root-ts-files',\n rules: {\n 'global-require': 'off',\n 'no-void': 'off',\n },\n },\n {\n files: ['**/*.ts?(x)'],\n name: 'no-void',\n rules: {\n 'no-void': ['error', {allowAsStatement: true}],\n },\n },\n];\n\nconst buildTsEslintConfig = (sourceDir: string): Linter.Config[] => [\n {\n files: ['**/*.ts?(x)'],\n name: 'typescript/config',\n rules: {\n '@typescript-eslint/array-type': ['error', {default: 'array'}],\n '@typescript-eslint/ban-ts-comment': [\n 'error',\n {\n minimumDescriptionLength: 10,\n 'ts-check': false,\n 'ts-expect-error': 'allow-with-description',\n 'ts-ignore': true,\n 'ts-nocheck': true,\n },\n ],\n '@typescript-eslint/consistent-type-definitions': ['error', 'type'],\n '@typescript-eslint/consistent-type-imports': 'error',\n '@typescript-eslint/explicit-module-boundary-types': 'off',\n '@typescript-eslint/method-signature-style': 'error',\n '@typescript-eslint/no-confusing-void-expression': [\n 'error',\n {ignoreArrowShorthand: true},\n ],\n '@typescript-eslint/no-deprecated': 'error',\n '@typescript-eslint/no-floating-promises': [\n 'error',\n {ignoreIIFE: true, ignoreVoid: true},\n ],\n '@typescript-eslint/no-misused-promises': [\n 'error',\n {checksVoidReturn: false},\n ],\n '@typescript-eslint/no-non-null-assertion': 'off',\n '@typescript-eslint/no-throw-literal': 'off',\n '@typescript-eslint/no-unnecessary-boolean-literal-compare': 'error',\n '@typescript-eslint/no-unnecessary-condition': 'error',\n '@typescript-eslint/no-unnecessary-type-conversion': 'error',\n '@typescript-eslint/no-unnecessary-type-parameters': 'off',\n '@typescript-eslint/no-unsafe-argument': 'error',\n '@typescript-eslint/no-unsafe-assignment': 'error',\n '@typescript-eslint/no-unsafe-call': 'error',\n '@typescript-eslint/no-unsafe-member-access': 'error',\n '@typescript-eslint/no-unsafe-return': 'error',\n '@typescript-eslint/only-throw-error': 'off',\n '@typescript-eslint/prefer-nullish-coalescing': 'error',\n '@typescript-eslint/prefer-promise-reject-errors': 'off',\n '@typescript-eslint/restrict-template-expressions': [\n 'error',\n {allowBoolean: true, allowNumber: true},\n ],\n '@typescript-eslint/return-await': 'off',\n '@typescript-eslint/unbound-method': 'off',\n },\n },\n {\n files: [\n `${sourceDir}/utils/**`,\n `${sourceDir}/services/**`,\n `${sourceDir}/hooks/**`,\n ],\n name: 'typescript/explicit-return-types',\n rules: {\n '@typescript-eslint/explicit-module-boundary-types': 'error',\n },\n },\n {\n files: ['**/*.test.ts?(x)', '**/*.stories.ts?(x)'],\n name: 'typescript/test-files',\n rules: {\n '@typescript-eslint/no-explicit-any': 'off',\n '@typescript-eslint/no-unsafe-argument': 'off',\n '@typescript-eslint/no-unsafe-assignment': 'off',\n '@typescript-eslint/no-unsafe-call': 'off',\n '@typescript-eslint/no-unsafe-member-access': 'off',\n },\n },\n {\n files: ['test/**/*.ts?(x)'],\n name: 'typescript/test-config',\n rules: {\n '@typescript-eslint/no-var-requires': 'off',\n 'no-plusplus': 'off',\n },\n },\n {\n files: ['**/*.d.ts'],\n name: 'typescript/type-definitions',\n rules: {\n '@typescript-eslint/consistent-type-definitions': 'off',\n '@typescript-eslint/method-signature-style': 'error',\n '@typescript-eslint/no-unused-vars': 'off',\n },\n },\n];\n\n// `^virtual:` covers Vite plugin virtual modules (`virtual:msw` and the like),\n// which no resolver can find on disk.\nconst NO_UNRESOLVED: Linter.RuleEntry = [\n 'error',\n {caseSensitive: true, commonjs: true, ignore: ['^virtual:']},\n];\n\nconst buildImportXConfig = (sourceDir: string): Linter.Config[] => [\n {\n name: 'import-x-all-files',\n rules: {\n 'import-x/consistent-type-specifier-style': ['error', 'prefer-top-level'],\n 'import-x/extensions': 'off',\n 'import-x/no-anonymous-default-export': [\n 'error',\n {\n allowArray: true,\n allowLiteral: true,\n allowObject: true,\n },\n ],\n 'import-x/no-namespace': 'off',\n 'import-x/no-rename-default': 'off',\n 'import-x/no-useless-path-segments': 'off',\n 'import-x/order': 'off',\n 'import-x/prefer-default-export': 'off',\n },\n },\n {\n files: ['./*.ts'],\n name: 'import-x/root-ts-files',\n rules: {\n 'import-x/no-extraneous-dependencies': 'off',\n 'import-x/no-unresolved': NO_UNRESOLVED,\n 'import-x/prefer-default-export': 'off',\n },\n },\n {\n files: ['**/*.test.ts?(x)', '**/*.stories.ts?(x)'],\n name: 'import-x/test-files',\n rules: {\n 'import-x/extensions': 'off',\n 'import-x/no-extraneous-dependencies': 'off',\n },\n },\n {\n files: [`${sourceDir}/**/*.ts?(x)`],\n name: 'import-x/app-test-files',\n rules: {\n 'import-x/no-unresolved': NO_UNRESOLVED,\n },\n },\n {\n files: [`${sourceDir}/**/hooks/*.ts?(x)`],\n name: 'import-x/hooks',\n rules: {\n 'import-x/no-default-export': 'error',\n },\n },\n {\n files: ['test/**/*.ts?(x)'],\n name: 'import-x/test-config-files',\n rules: {\n 'import-x/no-extraneous-dependencies': 'off',\n 'import-x/prefer-default-export': 'off',\n },\n },\n {\n files: ['.storybook/**/*.ts?(x)', '.playwright/**/*.ts?(x)'],\n name: 'import-x/storybook-playwright',\n rules: {\n 'import-x/no-extraneous-dependencies': 'off',\n 'import-x/no-unresolved': 'off',\n },\n },\n];\n\n// ESLint's built-in directive check, at error so an unused disable fails a\n// plain `eslint` run, not only one with `--max-warnings=0`. The eslint-comments\n// plugin's `no-unused-disable` cannot stand in for it: it looks its severity up\n// under the `@eslint-community/eslint-comments/` prefix, so registered under any\n// other plugin name it never reports.\nconst unusedDisableDirectivesConfig: Linter.Config[] = [\n {\n linterOptions: {reportUnusedDisableDirectives: 'error'},\n name: 'gaia/unused-disable-directives',\n },\n];\n\n/**\n * Disable-directive hygiene. Every `eslint-disable` must say why after a `--`\n * separator, so each bypass of a rule is reviewable where it sits. The\n * recommended set also bans a bare blanket `eslint-disable` and keeps block\n * disables paired with their enable. A whole-file disable at the top of a file\n * is allowed unpaired. An `eslint-enable` needs no reason.\n */\nconst eslintCommentsConfig: Linter.Config[] = [\n {\n ...eslintComments.recommended,\n name: 'gaia/eslint-comments',\n rules: {\n ...eslintComments.recommended.rules,\n '@eslint-community/eslint-comments/disable-enable-pair': [\n 'error',\n {allowWholeFile: true},\n ],\n '@eslint-community/eslint-comments/require-description': [\n 'error',\n {ignore: ['eslint-enable']},\n ],\n },\n },\n];\n\nconst preferArrowFunctionsConfig: Linter.Config[] = [\n {\n name: 'prefer-arrow',\n plugins: {\n 'prefer-arrow-functions': preferArrowFunctions as unknown as ESLint.Plugin,\n },\n rules: {\n 'prefer-arrow-functions/prefer-arrow-functions': 'error',\n },\n },\n {\n files: ['**/*.d.ts'],\n name: 'ts-definition-files/prefer-arrow-off',\n rules: {\n 'prefer-arrow-functions/prefer-arrow-functions': 'off',\n },\n },\n];\n\n/**\n * All `no-restricted-syntax` selectors live in one config object. ESLint flat\n * config merges this rule key by replacement (last match wins), not\n * concatenation, so a second block matching the same files would silently\n * clobber these selectors. Each selector carries its own message.\n *\n * `.d.ts` is ignored: ambient `export default function …(): T;` declarations\n * have no body to convert, and type-definition files contain no render code.\n */\nconst restrictedSyntaxConfig: Linter.Config[] = [\n {\n ignores: ['**/*.d.ts'],\n name: 'gaia/no-restricted-syntax',\n rules: {\n 'no-restricted-syntax': [\n 'error',\n {\n // `prefer-arrow-functions` has a hardcoded exemption for named\n // default-exported declarations\n // (`guard.js:hasNameAndIsExportedAsDefaultExport`), so\n // `export default function Foo() {}` slips through. This selector\n // closes that gap.\n message:\n 'Use `const Name = () => {}; export default Name;` instead. The prefer-arrow-functions plugin exempts named default-exported declarations upstream.',\n selector: 'ExportDefaultDeclaration > FunctionDeclaration',\n },\n {\n // GAIA never renders `null`. `cond ? <JSX/> : null` is the\n // numeric-0-safe `&&` guard written the long way. Both JSX-null\n // ternary selectors only match a JSXElement/JSXFragment branch, so\n // they are inert outside `.tsx`/`.jsx`.\n message:\n 'Do not render `null` from a ternary. Use a boolean-guarded `&&`: `cond && <JSX/>` (coerce a numeric/falsy guard with `!!cond`).',\n selector:\n \"ConditionalExpression[alternate.raw='null']:matches([consequent.type='JSXElement'], [consequent.type='JSXFragment'])\",\n },\n {\n message:\n 'Do not render `null` from a ternary. Invert the condition and use `&&`: `!cond && <JSX/>`.',\n selector:\n \"ConditionalExpression[consequent.raw='null']:matches([alternate.type='JSXElement'], [alternate.type='JSXFragment'])\",\n },\n {\n // A `.length` left operand is always numeric, so `&&` returns the\n // literal `0` (a renderable value) when the list is empty, leaking\n // \"0\" into the DOM. `.length` is the single most common numeric-0\n // leak and flagging it has zero false positives. The general\n // `count && <JSX/>` case is caught by `sonarjs/jsx-no-leaked-render`\n // in `guardrails`, which needs type information; this selector\n // needs none, so it still holds where types are unavailable.\n // Report-only: a blind rewrite is unsafe in general.\n message:\n 'A numeric `.length` left operand leaks \"0\" into the DOM when empty. Force a real boolean: `items.length > 0 && <JSX/>`.',\n selector:\n \"LogicalExpression[operator='&&'][left.property.name='length']:matches([right.type='JSXElement'],[right.type='JSXFragment'])\",\n },\n ],\n },\n },\n];\n\n/**\n * Global `no-restricted-imports` bans, applied to every `.ts`/`.tsx` file.\n *\n * The shared `RESTRICTED_IMPORT_PATHS` const is also spread into testing.ts's\n * own `no-restricted-imports` block. Flat config replaces a rule's options\n * wholesale, so without that second reference this global ban would be dropped\n * on test/story files (which testing.ts re-scopes the rule for).\n */\nconst restrictedImportsConfig: Linter.Config[] = [\n {\n files: ['**/*.ts?(x)'],\n name: 'gaia/no-restricted-imports',\n rules: {\n 'no-restricted-imports': ['error', {paths: RESTRICTED_IMPORT_PATHS}],\n },\n },\n];\n\nconst lodashUnderscoreConfig: Linter.Config[] = [\n {\n name: 'you-dont-need-lodash-underscore',\n plugins: {\n 'you-dont-need-lodash-underscore':\n lodashUnderscore as unknown as ESLint.Plugin,\n },\n rules: {\n ...(lodashUnderscore.configs.compatible.rules as Linter.RulesRecord),\n },\n },\n];\n\nexport const buildBase = (sourceDir: string): Linter.Config[] => [\n ...jsConfig,\n ...jsCustomConfig,\n ...typescriptConfig,\n ...buildTsEslintConfig(sourceDir),\n ...buildImportXConfig(sourceDir),\n ...unusedDisableDirectivesConfig,\n ...eslintCommentsConfig,\n ...preferArrowFunctionsConfig,\n ...restrictedSyntaxConfig,\n ...restrictedImportsConfig,\n ...lodashUnderscoreConfig,\n];\n","/**\n * Shared `no-restricted-imports` path bans.\n *\n * Referenced by BOTH the global base config and the testing config. ESLint\n * flat config replaces a rule's options WHOLESALE across config objects (it\n * does not merge them), so a later block that re-declares\n * `no-restricted-imports` — testing.ts scopes one to test/story files — would\n * otherwise DROP these bans on the files it matches. Both call sites spread\n * this same const so the ban holds everywhere and stays DRY.\n *\n * Uses `paths` (exact specifier match), not `patterns` (glob match): only the\n * bare `@conform-to/zod` specifier is banned, while the distinct\n * `@conform-to/zod/v4` specifier stays allowed. A `patterns` entry keyed on\n * `@conform-to/zod` would wrongly also catch the `/v4` subpath.\n *\n * The `react` entry bans only the `FC` and `FunctionComponent` names\n * (`importNames`); every other `react` import stays allowed. The core rule\n * reports type-only specifiers, so `import type {FC}` is caught too.\n */\nexport const RESTRICTED_IMPORT_PATHS = [\n {\n importNames: ['FC', 'FunctionComponent'],\n message:\n \"Do not import FC or FunctionComponent from 'react'. Type the props inline: `type ButtonProps = {...}; const Button = ({...}: ButtonProps) => ...`.\",\n name: 'react',\n },\n {\n message:\n \"Import from '@conform-to/zod/v4'. The bare '@conform-to/zod' specifier targets Zod v3 and throws at runtime, uncaught by typecheck, lint, and build.\",\n name: '@conform-to/zod',\n },\n];\n","import betterTailwindPlugin from 'eslint-plugin-better-tailwindcss';\nimport type {Linter} from 'eslint';\n\nexport type GaiaLintBetterTailwindOptions = {\n /** Path to the Tailwind entry CSS file (e.g. './app/styles/tailwind.css'). */\n entryPoint: string;\n /** Class names to ignore in `better-tailwindcss/no-unknown-classes`. */\n ignore?: string[];\n};\n\n/**\n * Better-Tailwind flat-config factory.\n *\n * Ports `betterTailwindConfig` from GAIA's `eslint.config.mjs`. The\n * `entryPoint` (consumer's Tailwind CSS entry) and `ignore` list are\n * project-specific, so this is shipped as a factory rather than a static\n * array.\n */\nexport const betterTailwind = (\n opts: GaiaLintBetterTailwindOptions,\n): Linter.Config[] => [\n {\n name: 'better-tailwindcss',\n plugins: {\n 'better-tailwindcss': betterTailwindPlugin,\n },\n rules: {\n // rootFontSize lets a px arbitrary value canonicalize to its scale step\n // (`w-[16px]` to `w-4`).\n 'better-tailwindcss/enforce-canonical-classes': [\n 'error',\n {rootFontSize: 16},\n ],\n 'better-tailwindcss/enforce-consistent-important-position': 'error',\n 'better-tailwindcss/enforce-consistent-variable-syntax': 'error',\n 'better-tailwindcss/enforce-shorthand-classes': 'error',\n 'better-tailwindcss/no-conflicting-classes': 'error',\n 'better-tailwindcss/no-deprecated-classes': 'error',\n 'better-tailwindcss/no-unknown-classes': [\n 'error',\n {ignore: opts.ignore ?? []},\n ],\n },\n settings: {\n 'better-tailwindcss': {\n detectComponentClasses: true,\n entryPoint: opts.entryPoint,\n },\n },\n },\n];\n","import path from 'node:path';\nimport type {Linter} from 'eslint';\nimport noRelativeImportPaths from 'eslint-plugin-no-relative-import-paths';\nimport * as regexp from 'eslint-plugin-regexp';\nimport sonarjs from 'eslint-plugin-sonarjs';\nimport cnConditionalPlugin from '../plugins/cn-conditional.js';\nimport noEnumPlugin from '../plugins/no-enum.js';\nimport noJsxIifePlugin from '../plugins/no-jsx-iife.js';\nimport noNullRenderPlugin from '../plugins/no-null-render.js';\nimport noSwitchPlugin from '../plugins/no-switch.js';\nimport noZodEnumPlugin from '../plugins/no-zod-enum.js';\nimport {\n REACT_DOCTOR_GUARDRAIL_RULES,\n REACT_DOCTOR_PLUGINS,\n} from './react-doctor.js';\n\nconst buildSonarConfig = (sourceDir: string): Linter.Config[] => [\n sonarjs.configs!.recommended as Linter.Config,\n {\n name: 'sonarjs',\n rules: {\n 'sonarjs/cognitive-complexity': 'error',\n 'sonarjs/fixme-tag': 'off',\n 'sonarjs/no-commented-code': 'off',\n 'sonarjs/no-nested-conditional': 'off',\n 'sonarjs/no-nested-functions': 'off',\n 'sonarjs/no-selector-parameter': 'off',\n 'sonarjs/regex-complexity': 'off',\n 'sonarjs/todo-tag': 'off',\n },\n },\n {\n files: ['**/*.tsx', '**/hooks/*.ts?(x)'],\n name: 'sonarjs/react-files',\n rules: {\n 'sonarjs/cognitive-complexity': 'off',\n 'sonarjs/function-return-type': 'off',\n },\n },\n {\n files: ['**/*.test.ts?(x)', '**/*.stories.ts?(x)'],\n name: 'sonarjs/test-files',\n rules: {\n 'sonarjs/no-duplicate-string': 'off',\n 'sonarjs/no-identical-functions': 'off',\n },\n },\n {\n files: [`${sourceDir}/languages/**/*.ts`, 'eslint.config.mjs'],\n name: 'sonarjs/credential-checks',\n rules: {\n 'sonarjs/no-hardcoded-credentials': 'off',\n 'sonarjs/no-hardcoded-passwords': 'off',\n },\n },\n];\n\n/**\n * Regex correctness. The recommended set catches patterns that can backtrack\n * catastrophically on hostile input (ReDoS), alternatives and character\n * classes that can never match, misleading capture groups, and needless\n * escapes or quantifiers. sonarjs covers only a few of these.\n */\nconst regexpConfig: Linter.Config[] = [\n {...regexp.configs['flat/recommended'], name: 'regexp'},\n];\n\n/**\n * Curated react-doctor rules (see `react-doctor.ts`) for security and\n * defensive-JS classes the sonarjs and regexp sets miss: auth tokens in web\n * storage, secrets in client code, unescaped dynamic `RegExp` input, path\n * prefix containment, `window.open` without `noopener`, throwing parse calls\n * and NaN-producing input parses, and similar.\n */\nconst reactDoctorGuardrailsConfig: Linter.Config[] = [\n {\n files: ['**/*.ts?(x)', '**/*.js?(x)'],\n name: 'react-doctor/guardrails',\n plugins: REACT_DOCTOR_PLUGINS,\n rules: REACT_DOCTOR_GUARDRAIL_RULES,\n },\n];\n\nconst cnConditionalConfig: Linter.Config[] = [\n {\n files: ['**/*.ts?(x)', '**/*.js?(x)'],\n name: 'cn-conditional',\n plugins: {'cn-conditional': cnConditionalPlugin},\n rules: {'cn-conditional/cn-conditional': 'error'},\n },\n];\n\nconst noEnumConfig: Linter.Config[] = [\n {\n files: ['**/*.ts?(x)'],\n name: 'no-enum',\n plugins: {'no-enum': noEnumPlugin},\n rules: {\n 'no-enum/no-enum': 'error',\n },\n },\n];\n\nconst noJsxIifeConfig: Linter.Config[] = [\n {\n files: ['**/*.tsx', '**/*.jsx'],\n name: 'no-jsx-iife',\n plugins: {'no-jsx-iife': noJsxIifePlugin},\n rules: {'no-jsx-iife/no-jsx-iife': 'error'},\n },\n];\n\nconst noNullRenderConfig: Linter.Config[] = [\n {\n files: ['**/*.tsx', '**/*.jsx'],\n name: 'no-null-render',\n plugins: {'no-null-render': noNullRenderPlugin},\n rules: {'no-null-render/no-null-render': 'error'},\n },\n];\n\nconst noSwitchConfig: Linter.Config[] = [\n {\n files: ['**/*.ts?(x)', '**/*.js?(x)'],\n name: 'no-switch',\n plugins: {'no-switch': noSwitchPlugin},\n rules: {'no-switch/no-switch': 'error'},\n },\n];\n\nconst noZodEnumConfig: Linter.Config[] = [\n {\n files: ['**/*.ts?(x)'],\n name: 'no-zod-enum',\n plugins: {'no-zod-enum': noZodEnumPlugin},\n rules: {'no-zod-enum/no-zod-enum': 'error'},\n },\n];\n\n/**\n * Architecture-boundary enforcement for GAIA's canonical `app/` layout.\n *\n * Imports may only flow from a higher layer to a lower one:\n *\n * routes -> pages -> components -> { hooks, state } -> services -> utils -> types\n *\n * `types/` is a pure leaf importable by everyone. Each zone names a lower\n * layer as `target` and the higher layers it must not import as `from`, so a\n * lower-importing-higher edge (the wrong direction) is reported. `routes`\n * appears in every `from` set, which encodes \"nothing may import a route\".\n *\n * Zone `target`/`from` paths resolve against `process.cwd()` (the consuming\n * project's root where eslint runs), not this package's location in\n * node_modules, so `./${sourceDir}/...` correctly points at the consumer's\n * source tree. `import-x@4.16.2` accepts `from`/`target` as string arrays,\n * which collapses the higher->lower pairs into one zone per target layer.\n *\n * `app/middleware`, `app/sessions.server`, `app/assets`, `app/languages`, and\n * `app/styles` are intentionally left unconstrained (server/asset dirs).\n *\n * The UI layers (pages, components, hooks/state) are exempted from the boundary\n * when importing a typed data-endpoint route (`routes/actions.*`,\n * `routes/resources.*`, or the older `routes/actions+`/`routes/resources+`\n * group folders, still accepted on the 2.x line). These are no-UI, typed data\n * endpoints the UI is explicitly meant to consume (e.g.\n * `useFetcher<typeof action>`). `import-x/no-restricted-paths` cannot\n * distinguish a type-only import, so without this carve-out it flags a\n * component's `import type {action}` from a typed endpoint.\n *\n * These three zones use glob-mode `from` (every entry is a `**` glob), because\n * import-x resolves a plain-mode `except` as a descendant path of `from`, which\n * cannot match a sibling flat route file. In glob mode `except` entries are\n * matched as absolute-path globs against the resolved import path, so they are\n * built from `process.cwd()` (the same default basePath import-x resolves\n * `from` against) rather than written as `**`-relative patterns: a leading `**`\n * does not cross a dot-prefixed path segment, so a `**`-relative pattern goes\n * silently dark under a dot-directory checkout (e.g. a `.claude/worktrees/`\n * worktree). Matching is by basename prefix, not a list of GAIA's endpoint\n * files. The services, utils, and types zones get no exemption, so the\n * carve-out stays within the UI layer.\n */\nconst buildNoRestrictedPathsConfig = (\n sourceDir: string,\n): Linter.Config[] => {\n const dir = (layer: string): string => `./${sourceDir}/${layer}`;\n const globDir = (layer: string): string => `./${sourceDir}/${layer}/**`;\n // Absolute, forward-slash, anchored where import-x resolves `from`\n // (its basePath defaults to process.cwd()).\n const routesDir = path\n .resolve(process.cwd(), sourceDir, 'routes')\n .split(path.sep)\n .join('/');\n const dataEndpoints = [\n `${routesDir}/actions.*`,\n `${routesDir}/resources.*`,\n // Older `+` group folders stay exempt through the 2.x line.\n `${routesDir}/actions+/**`,\n `${routesDir}/resources+/**`,\n ];\n\n return [\n {\n files: [`${sourceDir}/**/!(*.test|*.stories).ts?(x)`],\n name: 'import-x/architecture-boundaries',\n rules: {\n 'import-x/no-restricted-paths': [\n 'error',\n {\n zones: [\n {\n except: dataEndpoints,\n from: [globDir('routes')],\n message:\n 'Pages may only be imported by routes; a page must not import a route (import direction is routes -> pages -> components). Typed `actions.*`/`resources.*` data-endpoint routes are exempt (the older `actions+`/`resources+` folders are still accepted).',\n target: dir('pages'),\n },\n {\n except: dataEndpoints,\n from: [globDir('routes'), globDir('pages')],\n message:\n 'Reusable components must not depend on page- or route-level code (import direction is routes -> pages -> components). Typed `actions.*`/`resources.*` data-endpoint routes are exempt (the older `actions+`/`resources+` folders are still accepted).',\n target: dir('components'),\n },\n {\n except: dataEndpoints,\n from: [globDir('routes'), globDir('pages'), globDir('components')],\n message:\n 'Hooks and state sit below the UI tree; they must not import components, pages, or routes. Typed `actions.*`/`resources.*` data-endpoint routes are exempt (the older `actions+`/`resources+` folders are still accepted).',\n target: [dir('hooks'), dir('state')],\n },\n {\n from: [\n dir('routes'),\n dir('pages'),\n dir('components'),\n dir('hooks'),\n dir('state'),\n ],\n message:\n 'The service/data layer sits below the UI and orchestration layers; it must not import components, pages, routes, hooks, or state.',\n target: dir('services'),\n },\n {\n from: [\n dir('routes'),\n dir('pages'),\n dir('components'),\n dir('hooks'),\n dir('state'),\n dir('services'),\n ],\n message:\n 'Utils are near-leaves; they may import only types and other utils.',\n target: dir('utils'),\n },\n {\n from: [\n dir('routes'),\n dir('pages'),\n dir('components'),\n dir('hooks'),\n dir('state'),\n dir('services'),\n dir('utils'),\n ],\n message:\n 'Types are a pure leaf; they must not import any other app layer.',\n target: dir('types'),\n },\n ],\n },\n ],\n },\n },\n ];\n};\n\nconst buildNoRelativeImportPathsConfig = (\n sourceDir: string,\n): Linter.Config[] => [\n {\n name: 'no-relative-import-paths',\n plugins: {\n 'no-relative-import-paths': noRelativeImportPaths,\n },\n rules: {\n 'no-relative-import-paths/no-relative-import-paths': [\n 'error',\n {\n allowedDepth: 2,\n allowSameFolder: true,\n prefix: '~',\n rootDir: sourceDir,\n },\n ],\n },\n },\n];\n\nexport const buildGuardrails = (sourceDir: string): Linter.Config[] => [\n ...buildSonarConfig(sourceDir),\n ...regexpConfig,\n ...reactDoctorGuardrailsConfig,\n ...cnConditionalConfig,\n ...noEnumConfig,\n ...noJsxIifeConfig,\n ...noNullRenderConfig,\n ...noSwitchConfig,\n ...noZodEnumConfig,\n ...buildNoRestrictedPathsConfig(sourceDir),\n ...buildNoRelativeImportPathsConfig(sourceDir),\n];\n","import type {ESLint, Rule, Scope} from 'eslint';\n\n/**\n * Holds one form for a conditional class passed to `cn` from the `cn` package:\n * `cond && 'class'`. Object arguments and ternaries with an empty branch\n * (`undefined`, `null`, `false`, `''`, or an empty template) are reported. A\n * ternary with two non-empty branches (`c ? 'a' : 'b'`) is allowed.\n *\n * Only a callee that resolves to the named import `cn` from `'cn'` is checked\n * (aliases count; a local `cn` or a `cn` from another module is ignored).\n * Namespace imports (`import * as c from 'cn'; c.cn(...)`) are a deliberate\n * miss.\n */\n\ntype CallNode = Parameters<NonNullable<Rule.NodeListener['CallExpression']>>[0];\ntype Argument = CallNode['arguments'][number];\ntype Visited = Argument | null | undefined;\n\nconst findVariable = (\n scope: Scope.Scope | null,\n name: string\n): Scope.Variable | undefined => {\n let current = scope;\n while (current) {\n const variable = current.set.get(name);\n if (variable) return variable;\n current = current.upper;\n }\n return undefined;\n};\n\nconst isCnImport = (variable: Scope.Variable | undefined): boolean =>\n variable !== undefined &&\n variable.defs.length === 1 &&\n variable.defs.every((definition) => {\n if (definition.type !== 'ImportBinding') return false;\n const specifier = definition.node;\n return (\n specifier.type === 'ImportSpecifier' &&\n specifier.imported.type === 'Identifier' &&\n specifier.imported.name === 'cn' &&\n definition.parent?.type === 'ImportDeclaration' &&\n definition.parent.source.value === 'cn'\n );\n });\n\nconst isEmptyBranch = (node: Visited): boolean => {\n if (!node) return false;\n switch (node.type) {\n case 'Identifier':\n return node.name === 'undefined';\n case 'Literal':\n return (\n node.value === null || node.value === false || node.value === ''\n );\n case 'TemplateLiteral':\n return (\n node.expressions.length === 0 &&\n node.quasis.every((quasi) => quasi.value.cooked === '')\n );\n default:\n return false;\n }\n};\n\nconst cnConditionalRule: Rule.RuleModule = {\n create: (context) => {\n const visit = (node: Visited): void => {\n if (!node) return;\n switch (node.type) {\n case 'ArrayExpression':\n node.elements.forEach((element) => visit(element));\n break;\n case 'ConditionalExpression':\n if (isEmptyBranch(node.consequent) || isEmptyBranch(node.alternate)) {\n context.report({messageId: 'useLogical', node});\n } else {\n visit(node.consequent);\n visit(node.alternate);\n }\n break;\n case 'LogicalExpression':\n if (node.operator === '&&') {\n visit(node.right);\n } else {\n visit(node.left);\n visit(node.right);\n }\n break;\n case 'ObjectExpression':\n context.report({messageId: 'useLogical', node});\n break;\n default:\n break;\n }\n };\n\n return {\n CallExpression: (node: CallNode) => {\n if (node.callee.type !== 'Identifier') return;\n const variable = findVariable(\n context.sourceCode.getScope(node),\n node.callee.name\n );\n if (!isCnImport(variable)) return;\n node.arguments.forEach((argument) => visit(argument));\n },\n };\n },\n meta: {\n docs: {\n description:\n \"Require conditional classes passed to cn to be written as `cond && 'class'`\",\n },\n messages: {\n useLogical:\n \"Write a conditional class as `cond && 'class'` (or `!cond && 'class'`). `cn` does not accept object conditionals or a ternary with an empty branch in GAIA.\",\n },\n schema: [],\n type: 'problem',\n },\n};\n\nconst plugin: ESLint.Plugin = {\n meta: {\n name: 'cn-conditional',\n version: '0.1.0',\n },\n rules: {\n 'cn-conditional': cnConditionalRule,\n },\n};\n\nexport default plugin;\n","import type {ESLint, Rule} from 'eslint';\n\nconst noEnumRule: Rule.RuleModule = {\n create: (context) => ({\n TSEnumDeclaration: (node: Rule.Node) => {\n context.report({messageId: 'noEnum', node});\n },\n }),\n meta: {\n docs: {description: 'Disallow TypeScript enums'},\n messages: {\n noEnum:\n 'Do not use TypeScript enums. Use an object with `as const` instead.',\n },\n schema: [],\n type: 'problem',\n },\n};\n\nconst plugin: ESLint.Plugin = {\n meta: {\n name: 'no-enum',\n version: '0.1.0',\n },\n rules: {\n 'no-enum': noEnumRule,\n },\n};\n\nexport default plugin;\n","import type {ESLint, Rule} from 'eslint';\n\nconst noJsxIifeRule: Rule.RuleModule = {\n create: (context) => ({\n 'JSXExpressionContainer > CallExpression > ArrowFunctionExpression.callee':\n (node: Rule.Node) => {\n context.report({messageId: 'noJsxIife', node});\n },\n 'JSXExpressionContainer > CallExpression > FunctionExpression.callee': (\n node: Rule.Node,\n ) => {\n context.report({messageId: 'noJsxIife', node});\n },\n }),\n meta: {\n docs: {description: 'Disallow IIFEs in JSX expressions'},\n messages: {\n noJsxIife:\n 'Do not use IIFEs in JSX. Use a computed variable before the return or extract a component instead.',\n },\n schema: [],\n type: 'problem',\n },\n};\n\nconst plugin: ESLint.Plugin = {\n meta: {\n name: 'no-jsx-iife',\n version: '0.1.0',\n },\n rules: {\n 'no-jsx-iife': noJsxIifeRule,\n },\n};\n\nexport default plugin;\n","import type {ESLint, Rule} from 'eslint';\n\n/**\n * Render nothing with `undefined`, not `null`, in render functions.\n *\n * Consistency convention only: `null` and `undefined` are behaviorally\n * identical to React's reconciler (both, plus `false`/`true`, are the same\n * empty slot) and equally cheap in V8. This standardizes on the newer of two\n * equivalent forms; it does NOT imply `null` is wrong or slow.\n *\n * Safety model: this rule autofixes under unsupervised `eslint --fix`. A\n * `return null` in a React Router loader/action/util MUST stay `null` (rewriting\n * it would change runtime behavior). So a `return null` is fixed ONLY when its\n * lexically-enclosing function is PROVABLY a render function (renders JSX in its\n * own scope). When render context is not provable, the rule does nothing: a\n * deliberate safe miss.\n */\n\ntype ReturnNode = Parameters<NonNullable<Rule.NodeListener['ReturnStatement']>>[0];\n\ntype RenderFrame = {candidates: ReturnNode[]; rendersJsx: boolean};\n\n// JSX nodes are not part of @types/estree, so widen to `{type}` to compare.\nconst isJsxNode = (node: {type: string}): boolean =>\n node.type === 'JSXElement' || node.type === 'JSXFragment';\n\nconst noNullRenderRule: Rule.RuleModule = {\n create: (context) => {\n // Function-frame stack. One frame per function entered during traversal.\n const stack: RenderFrame[] = [];\n\n const enterFunction = (node: Rule.Node) => {\n const frame: RenderFrame = {candidates: [], rendersJsx: false};\n // An arrow with a JSX expression body renders JSX in its OWN frame.\n if (node.type === 'ArrowFunctionExpression' && isJsxNode(node.body)) {\n frame.rendersJsx = true;\n }\n stack.push(frame);\n };\n\n const exitFunction = () => {\n const frame = stack.pop();\n if (!frame || !frame.rendersJsx) {\n return; // Not a provable render frame: leave every candidate alone.\n }\n for (const candidate of frame.candidates) {\n const {argument} = candidate;\n if (!argument) {\n continue;\n }\n context.report({\n fix: (fixer) => fixer.replaceText(argument, 'undefined'),\n messageId: 'nullRender',\n node: candidate,\n });\n }\n };\n\n return {\n ArrowFunctionExpression: enterFunction,\n 'ArrowFunctionExpression:exit': exitFunction,\n FunctionDeclaration: enterFunction,\n 'FunctionDeclaration:exit': exitFunction,\n FunctionExpression: enterFunction,\n 'FunctionExpression:exit': exitFunction,\n ReturnStatement: (node) => {\n const frame = stack[stack.length - 1];\n if (!frame) {\n return; // `return` outside any function: not our concern.\n }\n const {argument} = node;\n if (!argument) {\n return; // bare `return;`\n }\n if (isJsxNode(argument)) {\n // A `return <JSX>` proves THIS frame is a render function.\n frame.rendersJsx = true;\n return;\n }\n if (\n argument.type === 'Literal' &&\n argument.value === null &&\n argument.raw === 'null'\n ) {\n // A literal `return null;`: attribute to the current (top) frame.\n // (raw === 'null' excludes regex literals, whose `value` can be null.)\n frame.candidates.push(node);\n }\n },\n };\n },\n meta: {\n docs: {\n description:\n 'Render nothing with `undefined`, not `null`, in render functions',\n },\n fixable: 'code',\n messages: {\n nullRender:\n 'Render nothing with `undefined`, not `null`. GAIA standardizes on `undefined` for the empty render (both are identical to React; this is a consistency convention).',\n },\n schema: [],\n type: 'suggestion',\n },\n};\n\nconst plugin: ESLint.Plugin = {\n meta: {\n name: 'no-null-render',\n version: '0.1.0',\n },\n rules: {\n 'no-null-render': noNullRenderRule,\n },\n};\n\nexport default plugin;\n","import type {ESLint, Rule} from 'eslint';\n\nconst noSwitchRule: Rule.RuleModule = {\n create: (context) => ({\n SwitchStatement: (node: Rule.Node) => {\n context.report({messageId: 'noSwitch', node});\n },\n }),\n meta: {\n docs: {description: 'Disallow switch statements'},\n messages: {\n noSwitch:\n 'Do not use switch statements. Use an object map or if/else instead.',\n },\n schema: [],\n type: 'problem',\n },\n};\n\nconst plugin: ESLint.Plugin = {\n meta: {\n name: 'no-switch',\n version: '0.1.0',\n },\n rules: {\n 'no-switch': noSwitchRule,\n },\n};\n\nexport default plugin;\n","import type {ESLint, Rule} from 'eslint';\n\nconst noZodEnumRule: Rule.RuleModule = {\n create: (context) => ({\n 'CallExpression > MemberExpression.callee[object.name=\"z\"][property.name=\"enum\"]':\n (node: Rule.Node) => {\n context.report({messageId: 'noZodEnum', node});\n },\n }),\n meta: {\n docs: {description: 'Disallow z.enum(); use z.literal([...]) instead'},\n messages: {\n noZodEnum:\n 'Do not use z.enum(). Use z.literal([...]) for string unions (sort values alphanumerically).',\n },\n schema: [],\n type: 'problem',\n },\n};\n\nconst plugin: ESLint.Plugin = {\n meta: {\n name: 'no-zod-enum',\n version: '0.1.0',\n },\n rules: {\n 'no-zod-enum': noZodEnumRule,\n },\n};\n\nexport default plugin;\n","import reactDoctor from 'eslint-plugin-react-doctor';\nimport type {ESLint, Linter} from 'eslint';\n\n/**\n * The one `eslint-plugin-react-doctor` registration every block that names a\n * `react-doctor/*` rule spreads into its `plugins`. Flat config accepts the\n * same plugin object in several blocks, so `react`, `reactRouter`, `shadcn()`\n * and `guardrails` each stay self-contained without a redefinition error.\n *\n * Curated rules only, never a preset: the presets re-enable rules GAIA turns\n * off on purpose and carry hundreds of rules for libraries GAIA does not use.\n * The rules take no options, carry no autofix and need no type information,\n * so the same rule ids port unchanged to Oxlint's `oxlint-plugin-react-doctor`.\n *\n * The package is pinned to an exact version. The rule set churns between\n * releases, and ESLint fails a config that names a rule the installed plugin\n * no longer ships, so a bump is a deliberate change with its tests. Every\n * curated rule id lives in this file, grouped by the block that applies it,\n * so a bump is checked against one list.\n */\nexport const REACT_DOCTOR_PLUGINS: Record<string, ESLint.Plugin> = {\n 'react-doctor': reactDoctor as unknown as ESLint.Plugin,\n};\n\n/** `react`: browser globals in render or a state initializer break SSR. */\nconst SSR_RULES: Linter.RulesRecord = {\n 'react-doctor/no-hydration-branch-on-browser-global': 'error',\n 'react-doctor/no-locale-format-in-render': 'warn',\n 'react-doctor/no-match-media-in-state-initializer': 'warn',\n 'react-doctor/no-unguarded-browser-global-in-render-or-hook-init': 'error',\n};\n\n/** `react`: markup the browser repairs or rejects, which breaks hydration. */\nconst HTML_RULES: Linter.RulesRecord = {\n 'react-doctor/form-control-requires-name': 'warn',\n 'react-doctor/html-no-invalid-paragraph-child': 'warn',\n 'react-doctor/html-no-invalid-table-nesting': 'warn',\n 'react-doctor/html-no-nested-form': 'warn',\n 'react-doctor/html-no-nested-interactive': 'warn',\n 'react-doctor/no-inert-sticky-position': 'warn',\n};\n\n/**\n * `react`: accessible names, landmarks, headings, roles, hover-only content\n * and form semantics jsx-a11y misses.\n */\nconst A11Y_RULES: Linter.RulesRecord = {\n 'react-doctor/data-table-requires-accessible-name': 'warn',\n 'react-doctor/details-requires-summary': 'warn',\n 'react-doctor/dialog-has-accessible-name': 'warn',\n 'react-doctor/empty-table-header': 'warn',\n 'react-doctor/fieldset-requires-legend': 'warn',\n 'react-doctor/html-label-has-single-control': 'warn',\n 'react-doctor/no-aria-invalid-without-description': 'warn',\n 'react-doctor/no-assertive-status': 'warn',\n 'react-doctor/no-autoplay-without-muted': 'warn',\n 'react-doctor/no-blocked-paste': 'error',\n 'react-doctor/no-disabled-zoom': 'error',\n 'react-doctor/no-duplicate-static-id-reference': 'error',\n 'react-doctor/no-focusable-content-in-aria-hidden': 'warn',\n 'react-doctor/no-hover-only-reveal': 'warn',\n 'react-doctor/no-invalid-progress-range': 'error',\n 'react-doctor/no-multiple-main-landmarks': 'warn',\n 'react-doctor/no-multiple-unlabeled-navigation-landmarks': 'warn',\n 'react-doctor/no-placeholder-only-field': 'warn',\n 'react-doctor/no-presentation-role-conflict': 'warn',\n 'react-doctor/no-responsive-hidden-accessible-name': 'warn',\n 'react-doctor/no-skipped-heading-level': 'warn',\n 'react-doctor/no-uninformative-aria-label': 'warn',\n 'react-doctor/radio-input-missing-name': 'warn',\n 'react-doctor/role-button-requires-complete-keyboard-activation': 'warn',\n};\n\n/**\n * `react`: side effects and identity bugs in render and state updates that the\n * React Compiler rules in `react-hooks` do not model.\n */\nconst RENDER_STATE_RULES: Linter.RulesRecord = {\n 'react-doctor/no-call-component-as-function': 'warn',\n 'react-doctor/no-controlled-input-value-without-state-update': 'warn',\n 'react-doctor/no-create-context-in-render': 'error',\n 'react-doctor/no-create-ref-in-function-component': 'warn',\n 'react-doctor/no-default-props': 'warn',\n 'react-doctor/no-impure-call-at-module-scope': 'warn',\n 'react-doctor/no-indeterminate-attribute': 'warn',\n 'react-doctor/no-mutate-queried-dom-node-in-component': 'warn',\n 'react-doctor/no-mutating-reducer-state': 'error',\n 'react-doctor/no-nondeterministic-id-value-in-render-body': 'warn',\n 'react-doctor/no-prop-callback-in-render': 'error',\n 'react-doctor/no-side-effect-in-state-updater-function': 'warn',\n 'react-doctor/no-uncontrolled-input': 'warn',\n 'react-doctor/rerender-functional-setstate': 'warn',\n 'react-doctor/waapi-animation-in-render': 'error',\n};\n\n/**\n * `react`: fetch and async work in Effects, and teardown the `@eslint-react`\n * leak rules do not cover (animation frames, object URLs, debounces, pointer\n * capture, stale timer refs, async races).\n */\nconst EFFECT_RULES: Linter.RulesRecord = {\n 'react-doctor/debounce-no-cleanup': 'warn',\n 'react-doctor/effect-raf-loop-needs-cancel': 'warn',\n 'react-doctor/no-create-object-url-without-revoke': 'warn',\n 'react-doctor/no-fetch-in-effect': 'warn',\n 'react-doctor/no-fetch-response-used-without-status-check': 'warn',\n 'react-doctor/no-loading-flag-reset-outside-finally': 'warn',\n 'react-doctor/no-promise-then-side-effect-in-effect-without-catch': 'warn',\n 'react-doctor/no-set-state-after-await-in-effect': 'warn',\n 'react-doctor/no-stale-timer-ref': 'warn',\n 'react-doctor/no-unbounded-animation-frame-loop': 'warn',\n 'react-doctor/no-unowned-async-error-clear': 'warn',\n 'react-doctor/pointer-capture-needs-cancel-handler': 'warn',\n};\n\n/**\n * `react`: sequential independent awaits, work repeated every render or call,\n * and image and script loading.\n */\nconst PERFORMANCE_RULES: Linter.RulesRecord = {\n 'react-doctor/async-parallel': 'warn',\n 'react-doctor/js-hoist-intl': 'warn',\n 'react-doctor/no-eager-new-in-use-state-initializer': 'warn',\n 'react-doctor/no-img-lazy-with-high-fetchpriority': 'warn',\n 'react-doctor/no-img-without-dimensions': 'warn',\n 'react-doctor/no-mixed-srcset-descriptors': 'warn',\n 'react-doctor/no-spread-accumulator-in-reduce': 'warn',\n 'react-doctor/no-srcset-without-sizes': 'warn',\n 'react-doctor/rendering-script-defer-async': 'warn',\n 'react-doctor/rerender-lazy-ref-init': 'warn',\n 'react-doctor/rerender-lazy-state-init': 'warn',\n};\n\n/**\n * `react`: motion that ignores reduced-motion and pixel font sizes that ignore\n * user font scaling. Off in vendored shadcn ui (see `shadcn.ts`).\n */\nexport const MOTION_FONT_RULES: Linter.RulesRecord = {\n 'react-doctor/no-arbitrary-px-font-size': 'warn',\n 'react-doctor/no-smooth-scroll-without-reduced-motion': 'warn',\n 'react-doctor/no-ungated-tailwind-animation': 'warn',\n};\n\n/**\n * `react`: size and complexity measured only on components and `use*` hooks\n * (over 300 lines; cyclomatic or cognitive complexity over 15; both fixed\n * upstream). They stand in for the sonarjs size and complexity rules, which\n * stay off because they do not model components and hooks.\n */\nconst SIZE_RULES: Linter.RulesRecord = {\n 'react-doctor/no-giant-component': 'warn',\n 'react-doctor/no-high-complexity-react-function': 'warn',\n};\n\nexport const REACT_DOCTOR_REACT_RULES: Linter.RulesRecord = {\n ...SSR_RULES,\n ...HTML_RULES,\n ...A11Y_RULES,\n ...RENDER_STATE_RULES,\n ...EFFECT_RULES,\n ...PERFORMANCE_RULES,\n ...MOTION_FONT_RULES,\n ...SIZE_RULES,\n};\n\n/**\n * `reactRouter`: framework-mode mistakes in loaders, actions, middleware,\n * sessions, cookies, search params, navigation and the server entry.\n */\nexport const REACT_DOCTOR_REACT_ROUTER_RULES: Linter.RulesRecord = {\n 'react-doctor/react-router-csp-nonce-consistency': 'error',\n 'react-doctor/react-router-guard-aborted-handle-error': 'warn',\n 'react-doctor/react-router-internal-route-anchor': 'warn',\n 'react-doctor/react-router-loader-fetch-forwards-signal': 'warn',\n 'react-doctor/react-router-loader-parallel-fetch': 'warn',\n 'react-doctor/react-router-no-catch-middleware-next': 'warn',\n 'react-doctor/react-router-no-client-module-in-server-render': 'error',\n 'react-doctor/react-router-no-loader-request-body': 'error',\n 'react-doctor/react-router-no-middleware-response-body-consumption': 'warn',\n 'react-doctor/react-router-no-multiple-blockers': 'error',\n 'react-doctor/react-router-no-multiple-middleware-next': 'error',\n 'react-doctor/react-router-no-multiple-set-search-params-in-tick': 'warn',\n 'react-doctor/react-router-no-navigate-in-render': 'error',\n 'react-doctor/react-router-no-redirect-in-try-catch': 'error',\n 'react-doctor/react-router-no-route-module-environment-suffix': 'error',\n 'react-doctor/react-router-no-session-mutation-in-loader': 'error',\n 'react-doctor/react-router-no-static-cookie-expires': 'error',\n 'react-doctor/react-router-no-unsynchronized-search-params-mutation': 'error',\n 'react-doctor/react-router-no-use-loader-data-in-error-ui': 'error',\n 'react-doctor/react-router-require-root-error-boundary': 'error',\n 'react-doctor/react-router-resource-link-requires-reload': 'error',\n 'react-doctor/react-router-return-navigation-promise-in-transition': 'warn',\n 'react-doctor/react-router-server-middleware-return-response': 'error',\n 'react-doctor/react-router-session-mutation-requires-commit': 'error',\n};\n\n/**\n * `reactRouter`, in the Query block: TanStack Query misuse the official\n * plugin does not check. Its `no-rest-destructuring`, `stable-query-client`\n * and `no-void-query-fn` own those cases, so react-doctor's copies stay off.\n */\nexport const REACT_DOCTOR_QUERY_RULES: Linter.RulesRecord = {\n 'react-doctor/query-destructure-result': 'warn',\n 'react-doctor/query-mutation-missing-invalidation': 'warn',\n 'react-doctor/query-no-mutation-in-effect-as-read': 'warn',\n 'react-doctor/query-no-query-in-effect': 'warn',\n 'react-doctor/query-no-usequery-for-mutation': 'warn',\n};\n\n/** `reactRouter`: source modules only; a module-scope browser global crashes SSR. */\nexport const REACT_DOCTOR_MODULE_SCOPE_RULES: Linter.RulesRecord = {\n 'react-doctor/no-unguarded-browser-global-at-module-scope': 'warn',\n};\n\n/** `guardrails`: security and defensive-JS classes sonarjs and regexp miss. */\nexport const REACT_DOCTOR_GUARDRAIL_RULES: Linter.RulesRecord = {\n 'react-doctor/auth-token-in-web-storage': 'warn',\n 'react-doctor/no-document-write': 'warn',\n 'react-doctor/no-fill-map-element-as-key': 'warn',\n 'react-doctor/no-non-literal-selector-query-without-try-catch': 'warn',\n 'react-doctor/no-non-null-assertion-on-maybe-undefined-result': 'warn',\n 'react-doctor/no-nullish-coalescing-arithmetic-precedence': 'warn',\n 'react-doctor/no-path-prefix-containment': 'warn',\n 'react-doctor/no-secrets-in-client-code': 'warn',\n 'react-doctor/no-sync-xhr': 'warn',\n 'react-doctor/no-unescaped-dynamic-string-in-regexp': 'warn',\n 'react-doctor/no-unguarded-numeric-input-parse': 'warn',\n 'react-doctor/no-unguarded-throwing-parse-call': 'warn',\n 'react-doctor/no-whole-object-default-losing-per-key-defaults': 'warn',\n 'react-doctor/window-open-without-noopener': 'warn',\n};\n\n/**\n * `shadcn()`: composition that breaks a shadcn primitive's accessible name,\n * keyboard model or structure. Off in vendored ui, which defines the\n * primitives these check.\n */\nexport const REACT_DOCTOR_SHADCN_RULES: Linter.RulesRecord = {\n 'react-doctor/shadcn-dialog-content-requires-title': 'warn',\n 'react-doctor/shadcn-icon-button-requires-label': 'warn',\n 'react-doctor/shadcn-input-group-no-raw-controls': 'warn',\n 'react-doctor/shadcn-tabs-trigger-requires-list': 'warn',\n};\n\n/**\n * The capabilities `reactRouter` declares in `settings['react-doctor']`.\n * react-doctor's CLI detects them per project; the standalone plugin reads\n * them from settings. Without `react-router-framework` the react-router rules\n * never recognize a route module's named `loader`, `action` or\n * `ErrorBoundary` exports and report nothing. Once the list is set, a rule\n * runs only when every capability it `requires` appears verbatim (a version\n * entry such as `react-router:7.9` is a floor, not a range), so this names\n * each capability the curated rules require that a React Router\n * framework-mode project on React 19 and Tailwind has. `shadcn` and\n * `tanstack-query` are listed too: their rules match the components and hooks\n * they check by import, so they stay silent in a project without them.\n */\nexport const REACT_DOCTOR_CAPABILITIES = [\n 'react',\n 'react:19',\n 'react-router',\n 'react-router:6.4',\n 'react-router:6.7',\n 'react-router:7',\n 'react-router:7.8',\n 'react-router:7.9',\n 'react-router:7.10',\n 'react-router-framework',\n 'shadcn',\n 'ssr',\n 'tailwind',\n 'tanstack-query',\n];\n","import i18next from 'eslint-plugin-i18next';\nimport type {Linter} from 'eslint';\n\n/**\n * i18n flat-config block (opt-in), for projects that translate their UI.\n *\n * `i18next/no-literal-string` in `jsx-text-only` mode reports raw text between\n * JSX tags (`<p>Hello</p>`), which should come from `t()`. Attributes and\n * plain string literals are not checked: `jsx-only` mode flags `data-slot`,\n * `htmlFor`, `value` and the like, which are not UI copy.\n *\n * Stories, tests, `tests/` helpers and the vendored shadcn ui files are\n * exempt. Text that must stay untranslated (an error boundary that renders\n * without i18n) takes an inline disable with a reason.\n *\n * A project that drops i18n removes `...lint.i18n` from its config.\n */\nexport const buildI18n = (sourceDir: string): Linter.Config[] => [\n {\n files: [`${sourceDir}/**/*.tsx`, `${sourceDir}/**/*.jsx`],\n ignores: [\n '**/*.test.tsx',\n '**/*.stories.tsx',\n '**/tests/**',\n `${sourceDir}/components/ui/*.tsx`,\n ],\n name: 'i18n/no-literal-string',\n plugins: {i18next},\n rules: {\n 'i18next/no-literal-string': ['error', {mode: 'jsx-text-only'}],\n },\n },\n];\n","import {includeIgnoreFile} from '@eslint/config-helpers';\nimport type {Linter} from 'eslint';\nimport fs from 'node:fs';\nimport path from 'node:path';\n\nexport type GaiaLintIgnoresOptions = {\n /**\n * Path to a `.gitignore` file to merge in. Resolved from `process.cwd()`\n * if relative. Pass `false` to skip the gitignore merge entirely.\n *\n * If the resolved path does not exist, the merge is silently skipped —\n * projects without a `.gitignore` don't need to opt out explicitly.\n *\n * @default '.gitignore'\n */\n gitignore?: string | false;\n /** Extra ignore globs to merge with GAIA defaults. */\n extra?: string[];\n};\n\n/**\n * GAIA's default ignore globs — matches the static `ignored-files` block in\n * GAIA's `eslint.config.mjs`. Consumer's `extra` ignores get concatenated\n * onto this list.\n *\n * Every entry names generated output, a non-source asset, or a tool-owned\n * script directory. Authored source stays out: a bare directory entry here is\n * a GLOBAL ignore, which beats any later block's `files`, so ignoring a\n * directory that another block scopes itself to silently kills that block.\n * `.playwright` and `.storybook` hold hand-written source that the\n * `playwright` and `storybook` blocks exist to lint.\n */\nconst defaultIgnores = [\n '/.react-router/**',\n '.claude/**/*.js',\n '.claude/**/*.cjs',\n 'scripts',\n 'public/**',\n '**/*.css',\n '**/*.svg',\n '**/*.md',\n];\n\n/**\n * Ignores flat-config factory.\n *\n * Ports the `includeIgnoreFile(gitignorePath)` + static `ignored-files`\n * block from GAIA's `eslint.config.mjs`. The `gitignore` path must be\n * resolved at the consumer's cwd (config-load time), not at gaia-lint's\n * install location, so this is shipped as a factory.\n */\nexport const ignores = (opts?: GaiaLintIgnoresOptions): Linter.Config[] => {\n const out: Linter.Config[] = [];\n\n const gitignore = opts?.gitignore ?? '.gitignore';\n if (gitignore !== false) {\n const resolved = path.isAbsolute(gitignore)\n ? gitignore\n : path.resolve(process.cwd(), gitignore);\n if (fs.existsSync(resolved)) {\n out.push(includeIgnoreFile(resolved) as Linter.Config);\n }\n }\n\n out.push({\n ignores: [...defaultIgnores, ...(opts?.extra ?? [])],\n name: 'ignored-files',\n });\n\n return out;\n};\n","import playwrightPlugin from 'eslint-plugin-playwright';\nimport type {Linter} from 'eslint';\n\n/**\n * Playwright flat-config block.\n *\n * Ports `playwrightConfig` from GAIA's `eslint.config.mjs` — scopes\n * `eslint-plugin-playwright`'s `flat/recommended` config to `.playwright/`\n * test files (GAIA's e2e directory convention).\n */\nexport const playwright: Linter.Config[] = [\n {\n name: 'playwright',\n ...(playwrightPlugin.configs['flat/recommended'] as Linter.Config),\n files: ['.playwright/**/*.ts?(x)'],\n rules: {\n ...playwrightPlugin.configs['flat/recommended'].rules,\n // Every test must assert something. `assertFunctionPatterns` lets custom\n // `expect*()` helpers count as the assertion. Error, never warn: a test\n // that asserts nothing is a false green.\n 'playwright/expect-expect': [\n 'error',\n {assertFunctionPatterns: ['^expect[A-Z]']},\n ],\n // A bare `test.skip()` is a test switched off at author time and stays\n // flagged at the recommended set's severity. `test.skip(condition, reason)`\n // is a different thing: Playwright's own API for a test that does not\n // apply to the environment it just found (a feature the project did not\n // enable, a browser without the capability). Allow the conditional form.\n 'playwright/no-skipped-test': ['warn', {allowConditional: true}],\n },\n },\n];\n","import {rules as prettierConfigRules} from 'eslint-config-prettier';\nimport prettierPlugin from 'eslint-plugin-prettier';\nimport type {Linter} from 'eslint';\n\n/**\n * Prettier flat-config block.\n *\n * Ports `prettierConfig` from GAIA's `eslint.config.mjs`. Layers\n * `eslint-config-prettier`'s rule disablers, then re-enables a few\n * `@stylistic/*` rules GAIA wants to keep (padding lines, single quotes),\n * and finally turns on the `prettier/prettier` rule itself.\n */\nexport const prettier: Linter.Config[] = [\n {\n name: 'prettier/plugin/config',\n plugins: {prettier: prettierPlugin},\n },\n {\n name: 'prettier/config',\n rules: {\n ...prettierConfigRules,\n '@stylistic/padding-line-between-statements': [\n 'error',\n {\n blankLine: 'always',\n next: ['block-like', 'export', 'return', 'throw'],\n prev: '*',\n },\n ],\n '@stylistic/quotes': [\n 'error',\n 'single',\n {\n allowTemplateLiterals: 'avoidEscape',\n avoidEscape: true,\n },\n ],\n '@stylistic/spaced-comment': 'off',\n 'prettier/prettier': ['error', {endOfLine: 'auto'}],\n },\n },\n];\n","import eslintReact from '@eslint-react/eslint-plugin';\nimport {configs, plugins} from 'eslint-config-airbnb-extended';\nimport reactRefresh from 'eslint-plugin-react-refresh';\nimport youMightNotNeedAnEffect from 'eslint-plugin-react-you-might-not-need-an-effect';\nimport type {ESLint, Linter} from 'eslint';\nimport {\n REACT_DOCTOR_PLUGINS,\n REACT_DOCTOR_REACT_RULES,\n} from './react-doctor.js';\n\n/**\n * React flat-config block.\n *\n * Ports `reactConfig` + `reactCustomConfig` from GAIA's `eslint.config.mjs`.\n * Pulls React, React Hooks, and JSX A11y plugins plus Airbnb's recommended\n * React config, then layers GAIA's project-wide React rule overrides.\n *\n * Router-specific relaxations live in the optional `reactRouter` block, not\n * here, so a project on a different file-based router keeps its full rule set.\n */\n/**\n * Options for `react-refresh/only-export-components`, shared with the route\n * block in `reactRouter`, which repeats them because flat config replaces a\n * rule's options wholesale. Vite's React plugin keeps state across a hot\n * update for constant and compound-component exports, so both are allowed.\n */\nexport const ONLY_EXPORT_COMPONENTS_OPTIONS = {\n allowCompoundComponents: true,\n allowConstantExport: true,\n} as const;\n\nexport const react: Linter.Config[] = [\n // React plugin\n plugins.react,\n // React hooks plugin\n plugins.reactHooks,\n // React JSX A11y plugin\n plugins.reactA11y,\n // Airbnb React recommended config\n ...configs.react.recommended,\n {\n name: 'react-custom',\n rules: {\n 'jsx-a11y/control-has-associated-label': 'off',\n 'jsx-a11y/no-autofocus': 'off',\n 'react/boolean-prop-naming': [\n 'error',\n {\n propTypeNames: ['bool', 'mutuallyExclusiveTrueProps'],\n rule: '^((can|has|hide|is|show)[A-Z]([A-Za-z0-9]?)+|(checked|disabled|hide|required|show))',\n },\n ],\n 'react/function-component-definition': 'off',\n 'react/jsx-boolean-value': ['error', 'always'],\n 'react/jsx-curly-brace-presence': 'error',\n 'react/jsx-filename-extension': 'off',\n 'react/jsx-fragments': 'error',\n // airbnb-extended's non-strict react config turns this off, and nothing\n // else in the bundle catches a list rendered without `key`.\n 'react/jsx-key': [\n 'error',\n {checkFragmentShorthand: true, warnOnDuplicates: true},\n ],\n // off by default because it doesn't handle props onXyz function names correctly\n // turn this on from time to time to check for misnamed handlers elsewhere\n 'react/jsx-handler-names': ['off', {checkLocalVariables: true}],\n 'react/jsx-newline': ['error', {prevent: true}],\n 'react/jsx-no-useless-fragment': ['error', {allowExpressions: true}],\n 'react/no-children-prop': 'off',\n 'react/no-danger': 'off',\n 'react/prop-types': 'off',\n 'react/react-in-jsx-scope': 'off',\n 'react/require-default-props': 'off',\n },\n },\n // A module that exports anything besides components cannot be hot-swapped:\n // Fast Refresh falls back to a full reload and drops component state. Test\n // and story files, and the helpers beside them in `tests/` folders, are never\n // hot-swapped as components, so they are exempt.\n {\n files: ['**/*.tsx', '**/*.jsx'],\n ignores: ['**/*.test.ts?(x)', '**/*.stories.ts?(x)', '**/tests/**'],\n name: 'react-refresh',\n plugins: {'react-refresh': reactRefresh},\n rules: {\n 'react-refresh/only-export-components': [\n 'error',\n ONLY_EXPORT_COMPONENTS_OPTIONS,\n ],\n },\n },\n // Effects that should not be Effects: state derived from other state or\n // props, user-event logic, chained updates, notifying a parent, resetting\n // state on a prop change (use `key`), and hand-rolled store subscriptions\n // (use `useSyncExternalStore`). Complements `react-hooks/set-state-in-effect`.\n {\n files: ['**/*.ts?(x)', '**/*.js?(x)'],\n name: 'react-you-might-not-need-an-effect',\n plugins: {\n 'react-you-might-not-need-an-effect':\n youMightNotNeedAnEffect as unknown as ESLint.Plugin,\n },\n rules: {\n 'react-you-might-not-need-an-effect/no-adjust-state-on-prop-change':\n 'error',\n 'react-you-might-not-need-an-effect/no-chain-state-updates': 'error',\n 'react-you-might-not-need-an-effect/no-derived-state': 'error',\n 'react-you-might-not-need-an-effect/no-event-handler': 'error',\n 'react-you-might-not-need-an-effect/no-external-store-subscription':\n 'error',\n 'react-you-might-not-need-an-effect/no-initialize-state': 'error',\n 'react-you-might-not-need-an-effect/no-pass-data-to-parent': 'error',\n 'react-you-might-not-need-an-effect/no-pass-live-state-to-parent':\n 'error',\n 'react-you-might-not-need-an-effect/no-reset-all-state-on-prop-change':\n 'error',\n },\n },\n // Nine rules from @eslint-react, not its preset: the preset re-enables hook\n // rules `react-hooks` already owns. An Effect that adds a listener, timer,\n // interval, observer or fetch must tear it down in its cleanup (a fetch\n // through an AbortController). React 19 forms only: `ref` as a prop instead\n // of `forwardRef`, `use(Context)` instead of `useContext`, and `<Context>`\n // instead of `<Context.Provider>`. `no-context-provider` matches by name, so\n // it reports `ThemeContext.Provider` but not `Ctx.Provider`.\n {\n files: ['**/*.ts?(x)', '**/*.js?(x)'],\n name: 'eslint-react',\n plugins: {'@eslint-react': eslintReact as unknown as ESLint.Plugin},\n rules: {\n '@eslint-react/no-context-provider': 'error',\n '@eslint-react/no-forward-ref': 'error',\n '@eslint-react/no-use-context': 'error',\n '@eslint-react/web-api-no-leaked-event-listener': 'error',\n '@eslint-react/web-api-no-leaked-fetch': 'error',\n '@eslint-react/web-api-no-leaked-intersection-observer': 'error',\n '@eslint-react/web-api-no-leaked-interval': 'error',\n '@eslint-react/web-api-no-leaked-resize-observer': 'error',\n '@eslint-react/web-api-no-leaked-timeout': 'error',\n },\n },\n // Curated react-doctor rules (see `react-doctor.ts`, which groups them with\n // the reason for each group): SSR and hydration hazards, invalid HTML,\n // accessibility jsx-a11y misses, side effects in render and state updates,\n // Effect lifecycle and teardown, render-path performance, reduced motion\n // and font scaling, and component and hook size and complexity.\n {\n files: ['**/*.ts?(x)', '**/*.js?(x)'],\n name: 'react-doctor/react',\n plugins: REACT_DOCTOR_PLUGINS,\n rules: REACT_DOCTOR_REACT_RULES,\n },\n {\n files: ['**/*.test.ts?(x)', '**/*.stories.ts?(x)'],\n name: 'react/test-files',\n rules: {\n 'react/jsx-props-no-spreading': 'off',\n },\n },\n];\n","import tanstackQuery from '@tanstack/eslint-plugin-query';\nimport type {ESLint, Linter} from 'eslint';\nimport noImperativeQueryFetchPlugin from '../plugins/no-imperative-query-fetch.js';\nimport {ONLY_EXPORT_COMPONENTS_OPTIONS} from './react.js';\nimport {\n REACT_DOCTOR_CAPABILITIES,\n REACT_DOCTOR_MODULE_SCOPE_RULES,\n REACT_DOCTOR_PLUGINS,\n REACT_DOCTOR_QUERY_RULES,\n REACT_DOCTOR_REACT_ROUTER_RULES,\n} from './react-doctor.js';\n\n/**\n * `@tanstack/eslint-plugin-query`'s recommended rules, read from its flat\n * preset so a plugin bump carries upstream's recommended set and severities.\n */\nconst TANSTACK_QUERY_RECOMMENDED_RULES: Linter.RulesRecord = Object.assign(\n {},\n ...tanstackQuery.configs['flat/recommended'].map(\n (config) => config.rules as Linter.RulesRecord,\n ),\n);\n\n/**\n * The named exports React Router reads from a route module. Its Vite plugin\n * hot-updates these alongside the component, so they do not cost a full\n * reload.\n */\nconst ROUTE_MODULE_EXPORTS = [\n 'action',\n 'clientAction',\n 'clientLoader',\n 'clientMiddleware',\n 'ErrorBoundary',\n 'handle',\n 'headers',\n 'HydrateFallback',\n 'Layout',\n 'links',\n 'loader',\n 'meta',\n 'middleware',\n 'shouldRevalidate',\n];\n\n/**\n * React Router flat-config block. Optional, and required only for projects\n * running React Router in framework mode.\n *\n * Its route block is SUBTRACTIVE: it relaxes a rule the rest of the bundle\n * turns on, rather than adding rules the way `storybook` and `playwright` do. That\n * is why it ships separately instead of living inside `react`. Its glob,\n * `**\\/routes/**\\/*.tsx`, is not unique to React Router (TanStack Router uses\n * a `routes/` directory too), so folding it into `react` would silently\n * weaken lint for every file-based router that isn't React Router.\n *\n * Spread it after `react`:\n *\n * ...lint.react,\n * ...lint.reactRouter,\n *\n * `no-empty-pattern` is off because a React Router route module destructures\n * nothing from its typed props (`({}: Route.ComponentProps)`), which the rule\n * reads as an empty pattern. TanStack Router names its component\n * (`createFileRoute(...)({component: Named})`) and never produces that shape,\n * so a TanStack project wants the rule left on.\n *\n * It also carries ADDITIVE rules on every TypeScript file under the source\n * dir: the curated react-doctor React Router and Query rules with the\n * capability settings they need, the `@tanstack/eslint-plugin-query`\n * recommended rules, and `no-imperative-query-fetch`. That last one sits on every\n * TypeScript file under the source dir. It bans `ensureQueryData`,\n * `fetchQuery`, `prefetchQuery` and their infinite variants, so a route has\n * one fetch idiom: `queryClient.query` awaited in a clientLoader, read with\n * `useSuspenseQuery`. That idiom is React Router's, which is why the rule\n * lives here. It reports on any member call by name, so it needs no TanStack\n * Query install to fire.\n *\n * Route modules, and `root.tsx` (the root route), may also export React\n * Router's route-module names (`loader`, `action`, `meta`, ...) beside their\n * component without tripping `react-refresh/only-export-components`.\n */\nexport const buildReactRouter = (sourceDir: string): Linter.Config[] => [\n {\n files: ['**/routes/**/*.tsx'],\n name: 'react-router/routes',\n rules: {\n 'no-empty-pattern': 'off',\n },\n },\n {\n files: ['**/routes/**/*.tsx', `${sourceDir}/root.tsx`],\n ignores: ['**/*.test.tsx', '**/*.stories.tsx', '**/tests/**'],\n name: 'react-router/route-module-exports',\n rules: {\n 'react-refresh/only-export-components': [\n 'error',\n {...ONLY_EXPORT_COMPONENTS_OPTIONS, allowExportNames: ROUTE_MODULE_EXPORTS},\n ],\n },\n },\n // TanStack Query, one block: `no-imperative-query-fetch`, the official\n // `@tanstack/eslint-plugin-query` recommended rules, and the react-doctor\n // Query rules the official plugin does not cover (`react-doctor.ts`). The\n // official and react-doctor rules match hooks and clients imported from\n // TanStack Query, so they stay silent in a project without Query.\n // `no-imperative-query-fetch` matches by method name.\n {\n files: [`${sourceDir}/**/*.ts?(x)`],\n name: 'react-router/no-imperative-query-fetch',\n plugins: {\n '@tanstack/query': tanstackQuery as unknown as ESLint.Plugin,\n 'no-imperative-query-fetch': noImperativeQueryFetchPlugin,\n ...REACT_DOCTOR_PLUGINS,\n },\n rules: {\n ...TANSTACK_QUERY_RECOMMENDED_RULES,\n ...REACT_DOCTOR_QUERY_RULES,\n 'no-imperative-query-fetch/no-imperative-query-fetch': 'error',\n },\n },\n // react-doctor's CLI detects a project's capabilities and hands them to its\n // rules; the standalone plugin reads them from these settings instead (see\n // `REACT_DOCTOR_CAPABILITIES`). Route detection matches `app/routes/`,\n // `app/root.*` and `app/entry.*`.\n {\n files: [`${sourceDir}/**/*.ts?(x)`],\n name: 'react-doctor/react-router-settings',\n settings: {\n 'react-doctor': {capabilities: REACT_DOCTOR_CAPABILITIES},\n },\n },\n // Curated react-doctor rules (see `react-doctor.ts`) for React Router\n // framework-mode mistakes that throw or misbehave at runtime: loaders,\n // actions, middleware, sessions, cookies, search params, navigation, error\n // UI and the server entry.\n {\n files: [`${sourceDir}/**/*.ts?(x)`],\n name: 'react-doctor/react-router',\n plugins: REACT_DOCTOR_PLUGINS,\n rules: REACT_DOCTOR_REACT_ROUTER_RULES,\n },\n // A browser global read at module scope crashes the server render. Source\n // modules only: tests, stories and the helpers in `tests/` folders run in a\n // browser or a DOM environment, never through SSR.\n {\n files: [`${sourceDir}/**/*.ts?(x)`],\n ignores: ['**/*.test.ts?(x)', '**/*.stories.ts?(x)', '**/tests/**'],\n name: 'react-doctor/react-router-module-scope',\n plugins: REACT_DOCTOR_PLUGINS,\n rules: REACT_DOCTOR_MODULE_SCOPE_RULES,\n },\n];\n","import type {ESLint, Rule} from 'eslint';\n\n// Each banned TanStack Query method, mapped to the `queryClient` method a\n// clientLoader awaits in its place.\nconst BANNED_METHODS = new Map([\n ['ensureInfiniteQueryData', 'infiniteQuery'],\n ['ensureQueryData', 'query'],\n ['fetchInfiniteQuery', 'infiniteQuery'],\n ['fetchQuery', 'query'],\n ['prefetchInfiniteQuery', 'infiniteQuery'],\n ['prefetchQuery', 'query'],\n]);\n\nconst getPropertyName = (callee: Rule.Node): string | undefined => {\n if (callee.type !== 'MemberExpression') {\n return undefined;\n }\n\n const {computed, property} = callee;\n\n if (!computed && property.type === 'Identifier') {\n return property.name;\n }\n\n if (\n computed &&\n property.type === 'Literal' &&\n typeof property.value === 'string'\n ) {\n return property.value;\n }\n\n return undefined;\n};\n\nconst noImperativeQueryFetchRule: Rule.RuleModule = {\n create: (context) => ({\n CallExpression: (node) => {\n const method = getPropertyName(node.callee as Rule.Node);\n const replacement = method && BANNED_METHODS.get(method);\n\n if (method && replacement) {\n context.report({\n data: {method, replacement},\n messageId: 'banned',\n node,\n });\n }\n },\n }),\n meta: {\n docs: {\n description:\n 'Disallow imperative TanStack Query fetches; await queryClient.query in a clientLoader and read with useSuspenseQuery',\n },\n messages: {\n banned:\n '`{{method}}` is banned. Await `queryClient.{{replacement}}(options)` in a clientLoader and read the data with `useSuspenseQuery(options)` in the component.',\n },\n schema: [],\n type: 'problem',\n },\n};\n\nconst plugin: ESLint.Plugin = {\n meta: {\n name: 'no-imperative-query-fetch',\n version: '0.1.0',\n },\n rules: {\n 'no-imperative-query-fetch': noImperativeQueryFetchRule,\n },\n};\n\nexport default plugin;\n","import {plugin as shadcnPlugin} from '@shadcn/lint';\nimport type {ESLint, Linter} from 'eslint';\nimport {\n MOTION_FONT_RULES,\n REACT_DOCTOR_PLUGINS,\n REACT_DOCTOR_SHADCN_RULES,\n} from './react-doctor.js';\nimport {RESTRICTED_IMPORT_PATHS} from './restricted-imports.js';\n\nexport type GaiaLintShadcnOptions = {\n /**\n * Fallback: globs where `shadcn/no-restyle` is off outside the vendored ui\n * folder (GAIA-owned components that restyle on purpose). The fallback block\n * always ignores `${sourceDir}/components/ui/**`, so it can never reach the\n * GAIA-authored `ui/tests/**` files.\n *\n * @default []\n */\n restyleOffFiles?: string[];\n /**\n * Import alias of the vendored ui folder. Written to the root-level\n * `settings.shadcn.ui`, never to a rule option, so a later Oxlint config\n * reads it unchanged.\n *\n * @default '~/components/ui'\n */\n ui?: string;\n /**\n * Globs of the vendored files (shadcn registry output kept byte-identical\n * to `shadcn add`). Never matches `ui/tests/**`.\n *\n * @default [`${sourceDir}/components/ui/*.tsx`, ...the registry helpers\n * shadcn writes outside the ui folder (`VENDORED_HELPER_FILES`)]\n */\n uiFiles?: string[];\n};\n\nconst SOURCE_EXTENSIONS = '{js,jsx,ts,tsx}';\n\n/**\n * A class whose arbitrary value is a color literal: hex, a CSS color function,\n * or a `color:` type hint.\n */\nconst ARBITRARY_COLOR_PATTERN = String.raw`^.*\\[(#|rgba?\\(|hsla?\\(|oklch\\(|oklab\\(|lab\\(|lch\\(|color:).*\\]$`;\n\n/**\n * Registry helpers `shadcn add` writes outside the ui folder, relative to the\n * source directory: `use-mobile` (sidebar), and `use-highlighted-code` and\n * `highlighter` (code-block). Exact paths, so a GAIA-authored hook or util\n * beside them keeps every rule.\n */\nconst VENDORED_HELPER_FILES = [\n 'hooks/use-highlighted-code.ts',\n 'hooks/use-mobile.ts',\n 'utils/highlighter.tsx',\n];\n\n/**\n * Rules turned off for vendored files because shadcn's registry output trips\n * them. The list covers the full registry: every rule that fired on unedited\n * `shadcn add --all` output (shadcn 4.22.0, swept 2026-10-22). Style rules\n * come first, then the correctness-class rules the maintainer sanctioned off\n * for vendored output, each with the stock file it covers.\n *\n * Correctness rules not listed here (`react-hooks/rules-of-hooks`,\n * `react-hooks/exhaustive-deps`, `shadcn/no-raw-colors`, and every other rule)\n * stay on.\n */\nconst VENDORED_UI_RULES_OFF: Linter.RulesRecord = {\n // shadcn renders `<Context.Provider>` and calls `useContext` (carousel,\n // chart, drawer, input-otp, sidebar, toggle-group).\n '@eslint-react/no-context-provider': 'off',\n '@eslint-react/no-use-context': 'off',\n '@stylistic/padding-line-between-statements': 'off',\n // shadcn emits double-quoted strings.\n '@stylistic/quotes': 'off',\n // shadcn writes `Array<T>`.\n '@typescript-eslint/array-type': 'off',\n // Helper exports carry inferred return types (use-mobile, highlighter).\n '@typescript-eslint/explicit-module-boundary-types': 'off',\n // toggle-group.tsx: `import { type VariantProps } from ...`.\n '@typescript-eslint/no-import-type-side-effects': 'off',\n // chart.tsx: `payload[key as keyof typeof payload] as string`.\n '@typescript-eslint/no-unnecessary-type-assertion': 'off',\n // shadcn function declarations use a variable before its declaration\n // (hoisted, no runtime effect), e.g. select.tsx.\n '@typescript-eslint/naming-convention': 'off',\n '@typescript-eslint/no-use-before-define': 'off',\n // toggle-group.tsx falls back from context to props with `||`.\n '@typescript-eslint/prefer-nullish-coalescing': 'off',\n // toast.tsx re-exports namespace members as `const a = Namespace.a`.\n '@typescript-eslint/prefer-destructuring': 'off',\n // The useMemo callback in field.tsx is flagged; a stylistic async annotation.\n '@typescript-eslint/promise-function-async': 'off',\n // calendar.tsx and sidebar.tsx arrow bodies are blocks.\n 'arrow-body-style': 'off',\n // Tailwind class rewrites would change vendored class strings.\n 'better-tailwindcss/enforce-canonical-classes': 'off',\n 'better-tailwindcss/enforce-shorthand-classes': 'off',\n 'better-tailwindcss/no-deprecated-classes': 'off',\n // shadcn writes `export { A, B }` on one line.\n 'canonical/export-specifier-newline': 'off',\n // chart.tsx passes an object to `cn`.\n 'cn-conditional/cn-conditional': 'off',\n // shadcn uses inline `type` specifiers (`import {cva, type VariantProps}`).\n 'import-x/consistent-type-specifier-style': 'off',\n // shadcn renders null from field.tsx.\n 'no-null-render/no-null-render': 'off',\n // `_values` in slider.tsx.\n 'no-underscore-dangle': 'off',\n // carousel.tsx: `{ api: api, ... }`.\n 'object-shorthand': 'off',\n 'perfectionist/sort-imports': 'off',\n 'perfectionist/sort-intersection-types': 'off',\n 'perfectionist/sort-jsx-props': 'off',\n 'perfectionist/sort-modules': 'off',\n 'perfectionist/sort-named-exports': 'off',\n 'perfectionist/sort-named-imports': 'off',\n 'perfectionist/sort-object-types': 'off',\n 'perfectionist/sort-objects': 'off',\n 'perfectionist/sort-union-types': 'off',\n // shadcn components are `function` declarations.\n 'prefer-arrow-functions/prefer-arrow-functions': 'off',\n // Vendored output is never reformatted; it stays byte-identical to\n // `shadcn add`.\n 'prettier/prettier': 'off',\n // Prop names such as `inset` (dropdown-menu).\n 'react/boolean-prop-naming': 'off',\n // pagination.tsx: a bare `aria-hidden`.\n 'react/jsx-boolean-value': 'off',\n // button.tsx exports `buttonVariants` and toast.tsx exports its toast\n // manager beside their components. A hot update of either falls back to a\n // full reload, which costs dev time only.\n 'react-refresh/only-export-components': 'off',\n // `prop?: T | undefined` (calendar, carousel).\n 'sonarjs/no-redundant-optional': 'off',\n 'sonarjs/prefer-read-only-props': 'off',\n // chart.tsx: `!payload?.length`, `.replace(/.../g)`, negated ternaries.\n 'unicorn/explicit-length-check': 'off',\n 'unicorn/no-negated-condition': 'off',\n 'unicorn/prefer-string-replace-all': 'off',\n // The `e` handler parameter in input-group.tsx.\n 'unicorn/prevent-abbreviations': 'off',\n // Sanctioned correctness-class exemptions for vendored output. Each one\n // trips a pattern in the shadcn source that GAIA does not edit.\n // sidebar.tsx: `toggleSidebar` returns the setter's void result.\n '@typescript-eslint/no-confusing-void-expression': 'off',\n // calendar.tsx, carousel.tsx, chart.tsx, sidebar.tsx reuse an outer name\n // (`props`, `className`, `api`, `config`, `open`) in a nested callback.\n '@typescript-eslint/no-shadow': 'off',\n // field.tsx FieldError: `uniqueErrors?.length` optional chain on a non-nullish array.\n '@typescript-eslint/no-unnecessary-condition': 'off',\n // chart.tsx reads recharts payload items, typed `any` upstream.\n '@typescript-eslint/no-unsafe-argument': 'off',\n '@typescript-eslint/no-unsafe-assignment': 'off',\n '@typescript-eslint/no-unsafe-member-access': 'off',\n '@typescript-eslint/restrict-template-expressions': 'off',\n // field.tsx FieldError: `uniqueErrors?.length == 1`.\n eqeqeq: 'off',\n // pagination.tsx: PaginationLink's anchor gets its content through spread\n // `children`, which the rule cannot see.\n 'jsx-a11y/anchor-has-content': 'off',\n // input-group.tsx: InputGroupAddon div with an onClick that focuses the input.\n 'jsx-a11y/click-events-have-key-events': 'off',\n // label.tsx: the generic Label primitive renders a <label> with no static control.\n 'jsx-a11y/label-has-associated-control': 'off',\n // input-group.tsx: the role=\"group\" div with an onClick.\n 'jsx-a11y/no-noninteractive-element-interactions': 'off',\n // code-block.tsx: a scrollable <pre> takes `tabIndex={0}` so the keyboard\n // can scroll it.\n 'jsx-a11y/no-noninteractive-tabindex': 'off',\n // carousel.tsx syncs Embla's selection into state from an effect;\n // use-mobile.ts reads `matchMedia` into state on mount.\n 'react-hooks/set-state-in-effect': 'off',\n // calendar.tsx and carousel.tsx call a prop callback from an effect;\n // use-mobile.ts subscribes to `matchMedia` and initializes state from it.\n 'react-you-might-not-need-an-effect/no-event-handler': 'off',\n 'react-you-might-not-need-an-effect/no-external-store-subscription': 'off',\n 'react-you-might-not-need-an-effect/no-initialize-state': 'off',\n 'react-you-might-not-need-an-effect/no-pass-data-to-parent': 'off',\n // The react-doctor shadcn rules check how GAIA code composes the primitives,\n // not the primitives themselves. toast.tsx: ToastClose's default\n // `render={<Button size=\"icon-sm\" />}` reads as an unlabeled icon Button,\n // but the aria-label sits on the ToastPrimitive.Close that renders it.\n ...Object.fromEntries(\n Object.keys(REACT_DOCTOR_SHADCN_RULES).map((rule) => [rule, 'off']),\n ),\n // Registry animation, scroll and font classes are shadcn's (toast.tsx\n // animates without a reduced-motion gate).\n ...Object.fromEntries(\n Object.keys(MOTION_FONT_RULES).map((rule) => [rule, 'off']),\n ),\n // sidebar.tsx: SidebarRail's <button> carries no `type`.\n 'react/button-has-type': 'off',\n // carousel.tsx, chart.tsx, toggle-group.tsx pass an inline object to a\n // context provider.\n 'react/jsx-no-constructed-context-values': 'off',\n // field.tsx FieldError: `<li key={index}>` over a static deduped error list.\n 'react/no-array-index-key': 'off',\n // calendar.tsx defines DayPicker's `components` slots inline.\n 'react/no-unstable-nested-components': 'off',\n // sidebar.tsx: SidebarMenuSkeleton picks a random skeleton width.\n 'sonarjs/pseudo-random': 'off',\n // sidebar.tsx persists the open state in a cookie.\n 'unicorn/no-document-cookie': 'off',\n // input-group.tsx: a `<Button>` className built dynamically. `no-raw-colors`\n // still reads those files.\n 'shadcn/require-static-classes': 'off',\n // shadcn writes `import * as React from 'react'`, which the core rule\n // reports against the `FC` ban because a namespace import could reach those\n // names. The block re-declares the shared bans minus the `react` entry\n // (options replace wholesale across blocks), so the other bans hold.\n 'no-restricted-imports': [\n 'error',\n {paths: RESTRICTED_IMPORT_PATHS.filter((entry) => entry.name !== 'react')},\n ],\n // Registry items may carry an arbitrary color the token contract bans.\n 'better-tailwindcss/no-restricted-classes': 'off',\n // input-otp.tsx and navigation-menu.tsx carry registry classes GAIA's theme\n // does not define (`cn-input-otp`, `xs:`, `easing-[ease]`).\n 'better-tailwindcss/no-unknown-classes': 'off',\n // sonner.tsx sets CSS variables through a `style` object.\n 'shadcn/no-inline-styles': 'off',\n // The vendored files compose each other with `className`.\n 'shadcn/no-restyle': 'off',\n};\n\n/**\n * `@shadcn/lint` flat-config factory (opt-in).\n *\n * Makes role tokens the only color vocabulary for GAIA components and exempts\n * the vendored shadcn ui files from house style. Returns these blocks:\n *\n * - `shadcn/settings`: no `files`; registers the plugin and sets\n * `settings.shadcn.ui` at root level.\n * - `shadcn/rules`: source files; `no-raw-colors`, `require-static-classes`,\n * `no-inline-styles` error, `no-restyle` error with `{allow: ['layout']}`,\n * `no-arbitrary-values` and `no-unknown-classes` off (better-tailwindcss's\n * `no-unknown-classes` stays the only unknown-class rule), and\n * `better-tailwindcss/no-restricted-classes` banning arbitrary colors.\n * - `shadcn/vendored-ui`: `uiFiles` only; `prettier/prettier` and the house\n * style rules (plus the maintainer-sanctioned correctness-class rules the\n * shadcn source trips) off. `shadcn/no-raw-colors`,\n * `react-hooks/rules-of-hooks`, `react-hooks/exhaustive-deps` and every\n * other correctness rule stay on.\n * - `shadcn/restyle-fallback`: only when `restyleOffFiles` is non-empty.\n *\n * ORDERING: the vendored-ui block names rules from plugins the other GAIA\n * blocks register (prettier, prefer-arrow-functions, perfectionist, unicorn,\n * better-tailwindcss, ...), so spread the full GAIA composition before it, and\n * spread `shadcn()` LAST, after `...lint.prettier`, so its `prettier/prettier:\n * off` wins on vendored files.\n *\n * @example\n * ...lint.shadcn({ui: '~/components/ui'})\n */\nexport const buildShadcn = (\n sourceDir: string,\n opts?: GaiaLintShadcnOptions,\n): Linter.Config[] => {\n const ui = opts?.ui ?? '~/components/ui';\n const uiFiles = opts?.uiFiles ?? [\n `${sourceDir}/components/ui/*.tsx`,\n ...VENDORED_HELPER_FILES.map((file) => `${sourceDir}/${file}`),\n ];\n const restyleOffFiles = opts?.restyleOffFiles ?? [];\n\n const configs: Linter.Config[] = [\n {\n name: 'shadcn/settings',\n plugins: {shadcn: shadcnPlugin as unknown as ESLint.Plugin},\n settings: {shadcn: {ui}},\n },\n {\n files: [`${sourceDir}/**/*.${SOURCE_EXTENSIONS}`],\n name: 'shadcn/rules',\n rules: {\n // An arbitrary value is allowed where no scale step or token fits;\n // `enforce-canonical-classes` still rewrites one that has a scale\n // equivalent. An arbitrary color is banned: colors are role tokens.\n 'better-tailwindcss/no-restricted-classes': [\n 'error',\n {\n restrict: [\n {\n message:\n 'Arbitrary colors are not allowed; use a theme role token.',\n pattern: ARBITRARY_COLOR_PATTERN,\n },\n ],\n },\n ],\n 'shadcn/no-arbitrary-values': 'off',\n 'shadcn/no-inline-styles': 'error',\n 'shadcn/no-raw-colors': 'error',\n 'shadcn/no-restyle': ['error', {allow: ['layout']}],\n // better-tailwindcss/no-unknown-classes stays the only unknown-class rule.\n 'shadcn/no-unknown-classes': 'off',\n 'shadcn/require-static-classes': 'error',\n },\n },\n // Curated react-doctor rules (see `react-doctor.ts`) for shadcn\n // composition that breaks a primitive: an icon-only Button with no label,\n // a DialogContent with no title, a raw control in an InputGroup, a\n // TabsTrigger outside TabsList.\n {\n files: [`${sourceDir}/**/*.${SOURCE_EXTENSIONS}`],\n name: 'react-doctor/shadcn',\n plugins: REACT_DOCTOR_PLUGINS,\n rules: REACT_DOCTOR_SHADCN_RULES,\n },\n {\n files: uiFiles,\n name: 'shadcn/vendored-ui',\n rules: VENDORED_UI_RULES_OFF,\n },\n ];\n\n if (restyleOffFiles.length > 0) {\n configs.push({\n files: restyleOffFiles,\n // The vendored ui folder (and with it `ui/tests/**`) is never reached.\n ignores: [`${sourceDir}/components/ui/**`],\n name: 'shadcn/restyle-fallback',\n rules: {'shadcn/no-restyle': 'off'},\n });\n }\n\n return configs;\n};\n","import storybookPlugin from 'eslint-plugin-storybook';\nimport type {Linter} from 'eslint';\n\n/**\n * Storybook flat-config block.\n *\n * Ports `storybookConfig` from GAIA's `eslint.config.mjs` — applies the\n * official `flat/recommended` config from `eslint-plugin-storybook`.\n */\nexport const storybook: Linter.Config[] = [\n ...(storybookPlugin.configs['flat/recommended'] as Linter.Config[]),\n];\n","import type {Linter} from 'eslint';\nimport canonical from 'eslint-plugin-canonical';\nimport checkFile from 'eslint-plugin-check-file';\nimport perfectionist from 'eslint-plugin-perfectionist';\nimport unicorn from 'eslint-plugin-unicorn';\nimport unusedImports from 'eslint-plugin-unused-imports';\n\nconst buildCanonicalConfig = (sourceDir: string): Linter.Config[] => [\n canonical.configs['flat/recommended'] as Linter.Config,\n {\n name: 'canonical',\n rules: {\n 'canonical/destructuring-property-newline': 'off',\n 'canonical/filename-match-exported': 'error',\n 'canonical/id-match': 'off',\n 'canonical/import-specifier-newline': 'off',\n },\n },\n {\n // Component and page folders are kebab-case while their default export is\n // PascalCase, so `theme-switch/index.tsx` exports `ThemeSwitch`. Scoped to\n // these folders only: a global kebab transform would reject `i18n.ts`\n // exporting `i18n` (lodash kebabs it to `i-18-n`).\n files: [`${sourceDir}/components/**/*.tsx`, `${sourceDir}/pages/**/*.tsx`],\n name: 'canonical/filename-match-exported-kebab',\n rules: {\n 'canonical/filename-match-exported': ['error', {transforms: ['kebab']}],\n },\n },\n {\n files: ['**/*.tsx', '**/hooks/*.ts?(x)'],\n name: 'canonical/sort-react-dependencies',\n rules: {\n 'canonical/sort-react-dependencies': 'error',\n },\n },\n {\n files: [\n `${sourceDir}/root.tsx`,\n `${sourceDir}/entry.server.tsx`,\n // A route page exports `<Name>Page` from `page.tsx`\n `${sourceDir}/pages/**/page.tsx`,\n `${sourceDir}/**/tests/*`,\n 'test/**/*.ts?(x)',\n '**/*.stories.tsx',\n '**/routes/**/*.tsx',\n '**/hooks/*.ts?(x)',\n '.storybook/**/*.ts?(x)',\n '.playwright/**/*.ts?(x)',\n ],\n name: 'canonical/filename-match-exported-disabled',\n rules: {\n 'canonical/filename-match-exported': 'off',\n },\n },\n];\n\nconst perfectionistConfig: Linter.Config[] = [\n perfectionist.configs['recommended-natural'] as Linter.Config,\n {\n name: 'perfectionist',\n rules: {\n 'perfectionist/sort-imports': [\n 'error',\n {\n customGroups: [\n {\n elementNamePattern: '^react$',\n groupName: 'react-type',\n selector: 'type',\n },\n {\n elementNamePattern: '^react$',\n groupName: 'react',\n },\n {\n elementNamePattern: '^react-.+',\n groupName: 'react-other-type',\n selector: 'type',\n },\n {\n elementNamePattern: '^react-.+',\n groupName: 'react-other',\n },\n ],\n groups: [\n 'react-type',\n 'react',\n 'react-other-type',\n 'react-other',\n ['type-external', 'external'],\n ['type-builtin', 'builtin'],\n ['type-internal', 'internal'],\n ['type-parent', 'parent'],\n ['type-sibling', 'sibling'],\n ['type-index', 'index'],\n 'unknown',\n 'style',\n 'side-effect',\n 'side-effect-style',\n ],\n newlinesBetween: 0,\n type: 'natural',\n },\n ],\n // TanStack Query reads option order for type inference: the\n // `@tanstack/query/*-property-order` rules need `onMutate` before\n // `onError` and `onSettled`, and `queryFn` before the page-param\n // getters. Plain natural order puts those keys first, so in the object\n // passed straight to the TanStack call they sort into a last group\n // instead, natural order everywhere else in it. Every other object\n // keeps `recommended-natural`'s sort.\n 'perfectionist/sort-objects': [\n 'error',\n {\n customGroups: [\n {\n elementNamePattern: '^(onError|onSettled)$',\n groupName: 'after-on-mutate',\n },\n ],\n groups: ['unknown', 'after-on-mutate'],\n order: 'asc',\n type: 'natural',\n useConfigurationIf: {callingFunctionNamePattern: '^useMutation$'},\n },\n {\n customGroups: [\n {\n elementNamePattern: '^(getNextPageParam|getPreviousPageParam)$',\n groupName: 'after-query-fn',\n },\n ],\n groups: ['unknown', 'after-query-fn'],\n order: 'asc',\n type: 'natural',\n useConfigurationIf: {\n callingFunctionNamePattern:\n '^(infiniteQueryOptions|useInfiniteQuery|useSuspenseInfiniteQuery)$',\n },\n },\n {order: 'asc', type: 'natural'},\n ],\n 'perfectionist/sort-jsx-props': [\n 'error',\n {\n customGroups: [\n {\n elementNamePattern: ['^key$', '^ref$'],\n groupName: 'reserved',\n },\n ],\n groups: ['reserved'],\n type: 'natural',\n },\n ],\n },\n },\n];\n\nconst unicornConfig: Linter.Config[] = [\n unicorn.configs.recommended as Linter.Config,\n {\n name: 'unicorn',\n rules: {\n 'unicorn/consistent-destructuring': 'error',\n 'unicorn/consistent-template-literal-escape': 'off',\n 'unicorn/filename-case': 'off',\n 'unicorn/new-for-builtins': 'off',\n 'unicorn/no-array-callback-reference': 'off',\n 'unicorn/no-array-for-each': 'off',\n 'unicorn/no-array-reduce': 'off',\n 'unicorn/no-nested-ternary': 'off',\n 'unicorn/no-null': 'off',\n 'unicorn/no-useless-undefined': 'off',\n 'unicorn/prefer-export-from': 'off',\n 'unicorn/prefer-global-this': 'off',\n // `Array#includes` returns a plain boolean, not a type predicate, so it\n // cannot narrow a union the way an `===` comparison chain does. In a typed\n // codebase the chain is the type-safe idiom; forcing `.includes()` discards\n // the narrowing and the value's refined type along with it.\n 'unicorn/prefer-includes-over-repeated-comparisons': 'off',\n 'unicorn/prefer-set-has': 'off',\n // Both gate on `definition.kind === 'const'`, which\n // @typescript-eslint/scope-manager never sets (the `const` lives on\n // `definition.parent.kind`), so under the TypeScript parser they cannot\n // report. Off states that instead of implying coverage.\n 'unicorn/no-blob-to-file': 'off',\n 'unicorn/prefer-set-size': 'off',\n 'unicorn/prefer-switch': 'off',\n 'unicorn/prefer-ternary': 'off',\n 'unicorn/prevent-abbreviations': [\n 'error',\n {\n ignore: [\n 'acc',\n 'ctx',\n 'e2e',\n 'env',\n 'obj',\n 'prev',\n 'req',\n 'res',\n /args/i,\n /fn/i,\n /param/i,\n /params/i,\n /props/i,\n /ref/i,\n /src/i,\n /utils/i,\n ],\n },\n ],\n 'unicorn/text-encoding-identifier-case': 'off',\n },\n },\n {\n files: ['./*.ts'],\n name: 'unicorn/root-ts-files',\n rules: {\n 'unicorn/prefer-module': 'off',\n 'unicorn/prevent-abbreviations': 'off',\n },\n },\n];\n\nconst unusedImportsConfig: Linter.Config[] = [\n {\n name: 'unused-imports',\n plugins: {\n 'unused-imports': unusedImports,\n },\n rules: {\n '@typescript-eslint/no-unused-vars': 'off',\n 'no-unused-vars': 'off',\n 'sonarjs/no-unused-vars': 'off',\n 'sonarjs/unused-import': 'off',\n 'unused-imports/no-unused-imports': 'error',\n 'unused-imports/no-unused-vars': [\n 'error',\n {\n args: 'after-used',\n argsIgnorePattern: '^_',\n ignoreRestSiblings: true,\n vars: 'all',\n varsIgnorePattern: '^_',\n },\n ],\n },\n },\n {\n files: ['**/*.d.ts'],\n name: 'unused-imports/ts-definition-files',\n rules: {\n 'unused-imports/no-unused-vars': 'off',\n },\n },\n];\n\n// Subfolders a component or page folder may hold besides nested components.\nconst RESERVED_FOLDERS = '(assets|hooks|state|tests|utils)';\n\n// The same, plus ui/, whose flat files are not named index.tsx.\nconst RESERVED_AND_UI_FOLDERS = '(assets|hooks|state|tests|ui|utils)';\n\n// Matches one folder segment that is not exactly one of `names`. micromatch's\n// `!(a|b)` alone excludes every segment that merely starts with `a` or `b`\n// (`statement` for `state`), so names extending a reserved word are added back.\nconst notExactly = (names: string): string => `{!${names},@${names}+([a-z0-9-])}`;\n\nconst buildCheckFileConfig = (sourceDir: string): Linter.Config[] => [\n {\n plugins: {\n 'check-file': checkFile,\n },\n },\n {\n files: [`${sourceDir}/**/*`],\n name: 'check-file',\n rules: {\n 'check-file/filename-naming-convention': [\n 'error',\n {\n // React hook files are kebab-case with a `use-` prefix (use-theme.ts)\n '**/hooks/*.{ts,tsx}': 'use-+([a-z0-9])*(-+([a-z0-9]))',\n [`${sourceDir}/state/*.tsx`]: 'KEBAB_CASE',\n // Components live in folders, never directly in components/\n [`${sourceDir}/components/*.tsx`]: '!(*)',\n // components/ui/ holds flat kebab-case component files (button.tsx)\n [`${sourceDir}/components/ui/*.tsx`]: 'KEBAB_CASE',\n // Every other component file is named index.tsx\n [`${sourceDir}/components/**/${notExactly(RESERVED_AND_UI_FOLDERS)}/*.tsx`]:\n 'index+()',\n // A page folder holds its route page.tsx, or index.tsx for colocated components\n [`${sourceDir}/pages/**/${notExactly(RESERVED_FOLDERS)}/*.tsx`]:\n '@(index|page)',\n // Generally, non-component files must be named kebab-case\n [`${sourceDir}/{components,pages}/**/!(hooks)/*.ts`]: 'KEBAB_CASE',\n // Non-component files inside specific components folders must be kebab-case\n [`${sourceDir}/{components,pages}/**/(assets|state|tests|utils)/*.{ts,tsx}`]:\n 'KEBAB_CASE',\n 'test/**/*.ts?(x)': 'KEBAB_CASE',\n },\n {\n ignoreMiddleExtensions: true,\n },\n ],\n 'check-file/folder-match-with-fex': [\n 'error',\n {\n // require stories and test files to be inside tests folders\n '*.(stories|test).{ts,tsx}': `${sourceDir}/**/tests/`,\n },\n ],\n 'check-file/folder-naming-convention': [\n 'error',\n {\n // enforce kebab-case component and page folders; the reserved\n // assets, hooks, state, tests, and utils subfolders are kebab-case too\n [`${sourceDir}/components/**/`]: 'KEBAB_CASE',\n [`${sourceDir}/pages/**/`]: 'KEBAB_CASE',\n // components/ui/ is flat: tests/ is its only subfolder\n [`${sourceDir}/components/ui/*/`]: '@(tests)',\n },\n ],\n },\n },\n {\n files: ['test/**/*.*'],\n name: 'check-file/test-files',\n rules: {\n 'check-file/filename-naming-convention': [\n 'error',\n {\n 'test/**/*.ts?(x)': 'KEBAB_CASE',\n },\n {\n ignoreMiddleExtensions: true,\n },\n ],\n },\n },\n];\n\nexport const buildStyleHygiene = (sourceDir: string): Linter.Config[] => [\n ...buildCanonicalConfig(sourceDir),\n ...perfectionistConfig,\n ...unicornConfig,\n ...unusedImportsConfig,\n ...buildCheckFileConfig(sourceDir),\n];\n","import vitest from '@vitest/eslint-plugin';\nimport jestDom from 'eslint-plugin-jest-dom';\nimport {RESTRICTED_IMPORT_PATHS} from './restricted-imports.js';\nimport type {Linter} from 'eslint';\n\n/**\n * Testing flat-config block.\n *\n * Ports `testHarnessConfig` + `testingLibraryConfig` from GAIA's\n * `eslint.config.mjs`. Wires up Vitest and jest-dom recommended rules\n * across test/story/test-harness files.\n */\nexport const testing: Linter.Config[] = [\n {\n files: [\n '**/*.test.ts?(x)',\n '**/*.stories.ts?(x)',\n 'test/**/*.ts?(x)',\n ],\n name: 'vitest',\n plugins: {\n 'jest-dom': jestDom,\n vitest,\n },\n rules: {\n ...jestDom.configs['flat/recommended'].rules,\n ...vitest.configs.recommended.rules,\n 'import-x/no-useless-path-segments': [\n 'error',\n {noUselessIndex: true},\n ],\n 'vitest/expect-expect': [\n 'error',\n {assertFunctionNames: ['expect', 'expect*']},\n ],\n // Baseline bump: `recommended` ships no-disabled-tests at `warn`.\n // .skip is the single biggest gaming vector for a RED-verification\n // gate (it makes a failing test stop failing), so GAIA forbids it\n // outright. Park work with test.todo or an inline eslint-disable, not\n // a silent .skip.\n 'vitest/no-disabled-tests': 'error',\n // --- Hardening beyond the `recommended` preset ---------------------\n // Rule names and options verified against @vitest/eslint-plugin\n // v1.6.19. GAIA policy: every lint rule is `error`, never `warn`.\n //\n // Consistency: GAIA uses test() exclusively (120 vs 0 it() across the\n // gaia codebase). In 1.6.19 the `fn` option cascades to the\n // within-describe keyword, so this also governs test()/it() nested in\n // describe blocks. Auto-fixable.\n 'vitest/consistent-test-it': ['error', {fn: 'test'}],\n // Consistency: GAIA uses the `vi` mock API (37 vs 0 `vitest.` across the\n // gaia codebase). Auto-fixable.\n 'vitest/consistent-vitest-vi': ['error', {fn: 'vi'}],\n // RED-gate: a branch in a test body can assert nothing on one path.\n // Enable ONLY this one; `no-conditional-tests` is a byte-identical\n // duplicate in 1.6.19 and would double-report.\n 'vitest/no-conditional-in-test': 'error',\n // RED-gate: fdescribe/fit/xdescribe/xit bypass the active\n // no-focused-tests / no-disabled-tests rules; forbid the prefix\n // spellings so the focus/skip net stays airtight. Auto-fixable.\n 'vitest/no-test-prefixes': 'error',\n // RED-gate: a returned value/promise can resolve after the test\n // \"passes\", swallowing assertions and faking GREEN.\n 'vitest/no-test-return-statement': 'error',\n // RED-gate: empty test('...') stubs pass green and read as coverage;\n // rewrite to test.todo('...') so the gap is explicit. Contradicts\n // `warn-todo`, which stays off. Auto-fixable.\n 'vitest/prefer-todo': 'error',\n // Honesty (D-8 / SPEC-006 Rule 3, the cheap-win stand-in for\n // `gaia-test-honesty/no-call-through-only`). A bare\n // `toHaveBeenCalled()`/`toBeCalled()` proves the function ran but\n // asserts nothing about how (arguments) or how many (count) — a\n // call-through that re-proves the framework, not the behavior.\n //\n // SCOPE NOTE: `prefer-called-with` is BROADER than spec Rule 3. The spec\n // rule fires only when a bare `toHaveBeenCalled()` is the SOLE assertion\n // in a test; `prefer-called-with` fires on EVERY bare\n // `toHaveBeenCalled()`/`toBeCalled()` (it exempts only the `.not` form).\n // So this stands in for Rule 3 rather than matching it exactly.\n 'vitest/prefer-called-with': 'error',\n // A bare .toThrow() passes on ANY throw, masking the wrong error;\n // require an asserted message or matcher.\n 'vitest/require-to-throw-message': 'error',\n },\n },\n {\n // Honesty (D-8 / SPEC-006 Rule 4, the cheap-win stand-in for\n // `gaia-test-honesty/no-server-import-from-consumer`). A consumer test,\n // story, or harness file must not import a server-only (`*.server`) or\n // internal (`/internals/`) module: those are private surface, and\n // reaching into them couples the test to implementation the public\n // interface is meant to hide.\n //\n // Same testing glob as the `vitest` block above. The `*.server.test.*`\n // exemption is the point of Rule 4: a dedicated server-side test IS the\n // right place to import a `.server` module (mirrors the real\n // `app/utils/tests/http.server.test.ts` importing `../http.server`).\n //\n // Implemented with the core `no-restricted-imports` rule (config only, no\n // custom plugin) rather than a dedicated AST rule. Chosen over\n // `import-x/no-restricted-paths` because Rule 4 keys off the import\n // SPECIFIER shape (`*.server`, `/internals/`) plus a per-file filename\n // exemption, not the directory `from`/`target` zones that\n // `no-restricted-paths` models.\n //\n // LIMITATION vs the would-be custom rule: `no-restricted-imports` covers\n // static `import` / `export ... from` only, NOT dynamic\n // `import('./x.server')`. The dynamic case is intentionally out of scope\n // for this cheap-win form; the advisory worthiness audit backstops it.\n //\n // ERROR severity, per spec (Rule 4 is an error rule).\n files: [\n '**/*.test.ts?(x)',\n '**/*.stories.ts?(x)',\n 'test/**/*.ts?(x)',\n ],\n ignores: ['**/*.server.test.*'],\n name: 'gaia-test-honesty/no-server-import-from-consumer',\n rules: {\n 'no-restricted-imports': [\n 'error',\n {\n // `paths` re-declares the global `@conform-to/zod` ban from base.ts.\n // Flat config replaces a rule's options wholesale, so this later\n // block would otherwise drop the conform ban on test/story files.\n // Same shared const as base.ts, to stay DRY.\n paths: RESTRICTED_IMPORT_PATHS,\n patterns: [\n {\n group: ['**/*.server'],\n message:\n \"Do not import a server-only ('*.server') module from a consumer test. Server-only modules are private surface: reach them through the public interface, or from a dedicated *.server.test.* file (which is exempt from this rule).\",\n },\n {\n group: ['**/internals/**', '**/internals'],\n message:\n \"Do not import an internal ('/internals/') module from a consumer test. Internal modules are private surface: importing them couples the test to implementation the public interface is meant to hide. Reach the behavior through the public interface instead.\",\n },\n ],\n },\n ],\n },\n },\n];\n","import zodPlugin from 'eslint-plugin-zod';\nimport type {ESLint, Linter} from 'eslint';\n\n/**\n * Zod flat-config block (opt-in), for Zod 4 projects.\n *\n * `eslint-plugin-zod`'s recommended set: conflicting or duplicate checks,\n * `.optional()` with `.default()`, a `throw` inside `.refine()`, a refine\n * without an error message (users see a generic \"Invalid input\"),\n * `z.nativeEnum`, `z.any()`, and the Zod 3 forms Zod 4 deprecates.\n *\n * `consistent-import` is off: it wants `import * as z from 'zod'` by default,\n * and even in `named` mode it reports a named `ZodError` import. The\n * stylistic set is not included; it pushes toward enums, which `no-zod-enum`\n * in `guardrails` bans.\n */\nexport const zod: Linter.Config[] = [\n {\n files: ['**/*.ts?(x)'],\n name: 'zod',\n plugins: {zod: zodPlugin as unknown as ESLint.Plugin},\n rules: {\n ...(zodPlugin.configs.recommended.rules as Linter.RulesRecord),\n 'zod/consistent-import': 'off',\n },\n },\n];\n","import type {Linter} from 'eslint';\nimport {buildBase} from './configs/base.js';\nimport {\n betterTailwind,\n type GaiaLintBetterTailwindOptions,\n} from './configs/better-tailwind.js';\nimport {buildGuardrails} from './configs/guardrails.js';\nimport {buildI18n} from './configs/i18n.js';\nimport {ignores, type GaiaLintIgnoresOptions} from './configs/ignores.js';\nimport {playwright} from './configs/playwright.js';\nimport {prettier} from './configs/prettier.js';\nimport {react} from './configs/react.js';\nimport {buildReactRouter} from './configs/react-router.js';\nimport {buildShadcn, type GaiaLintShadcnOptions} from './configs/shadcn.js';\nimport {storybook} from './configs/storybook.js';\nimport {buildStyleHygiene} from './configs/style-hygiene.js';\nimport {testing} from './configs/testing.js';\nimport {zod} from './configs/zod.js';\n\nexport type {\n GaiaLintBetterTailwindOptions,\n GaiaLintIgnoresOptions,\n GaiaLintShadcnOptions,\n};\n\nexport type GaiaLintOptions = {\n /**\n * Application source directory (relative to project root). Used to scope\n * file-path-based rules — filename conventions, hook-folder scoping,\n * `no-relative-import-paths` root, etc.\n *\n * @default 'app'\n */\n sourceDir?: string;\n};\n\n/**\n * Dual-shape `ignores` accessor. Spread it directly for the default\n * configuration (`...lint.ignores`) or call it to override\n * (`...lint.ignores({extra: ['coverage/**']})`).\n */\nexport type GaiaLintIgnores = ((\n opts?: GaiaLintIgnoresOptions,\n) => Linter.Config[]) &\n Iterable<Linter.Config>;\n\nexport type GaiaLintBundle = {\n base: Linter.Config[];\n betterTailwind: (opts: GaiaLintBetterTailwindOptions) => Linter.Config[];\n guardrails: Linter.Config[];\n /**\n * Opt-in `i18next/no-literal-string` (JSX text only) for projects that\n * translate their UI. Drop it when the project drops i18n.\n */\n i18n: Linter.Config[];\n ignores: GaiaLintIgnores;\n playwright: Linter.Config[];\n prettier: Linter.Config[];\n react: Linter.Config[];\n reactRouter: Linter.Config[];\n /**\n * Opt-in `@shadcn/lint` token rules plus the vendored-ui exemption. Assumes\n * the full GAIA composition is spread before it and must be the LAST entry,\n * after `...lint.prettier`.\n */\n shadcn: (opts?: GaiaLintShadcnOptions) => Linter.Config[];\n storybook: Linter.Config[];\n styleHygiene: Linter.Config[];\n testing: Linter.Config[];\n /** Opt-in `eslint-plugin-zod` recommended rules, for Zod 4 projects. */\n zod: Linter.Config[];\n};\n\nconst buildIgnoresAccessor = (): GaiaLintIgnores => {\n const defaults = ignores();\n const accessor = ((opts?: GaiaLintIgnoresOptions) => ignores(opts)) as\n | ((opts?: GaiaLintIgnoresOptions) => Linter.Config[]) &\n Iterable<Linter.Config> & {[Symbol.iterator]?: () => Iterator<Linter.Config>};\n accessor[Symbol.iterator] = () => defaults[Symbol.iterator]();\n return accessor as GaiaLintIgnores;\n};\n\n/**\n * GAIA lint configuration factory.\n *\n * Call once at the top of your `eslint.config.mjs` to bind a `sourceDir`,\n * then spread the returned configs into `defineConfig`. Defaults to GAIA's\n * `'app'` layout; pass `{sourceDir: 'src'}` (or any other value) for\n * projects that store source elsewhere.\n *\n * @example\n * const lint = gaiaLint(); // GAIA / app/\n * const lint = gaiaLint({sourceDir: 'src'}); // src/\n */\nconst gaiaLint = (opts?: GaiaLintOptions): GaiaLintBundle => {\n const sourceDir = opts?.sourceDir ?? 'app';\n return {\n base: buildBase(sourceDir),\n betterTailwind,\n guardrails: buildGuardrails(sourceDir),\n i18n: buildI18n(sourceDir),\n ignores: buildIgnoresAccessor(),\n playwright,\n prettier,\n react,\n reactRouter: buildReactRouter(sourceDir),\n shadcn: (shadcnOpts) => buildShadcn(sourceDir, shadcnOpts),\n storybook,\n styleHygiene: buildStyleHygiene(sourceDir),\n testing,\n zod,\n };\n};\n\nexport default gaiaLint;\n"],"mappings":"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","names":["plugin","plugin","plugin","plugin","plugin","path","configs","plugins","plugins","configs","plugin","configs"]}