{
  "$schema": "./node_modules/@biomejs/biome/configuration_schema.json",
  "extends": ["ultracite/core"],
  "plugins": [
    "./lint-rules/no-stdout-write-in-commands.grit",
    "./lint-rules/no-process-stdout-in-commands.grit",
    "./lint-rules/no-raw-metadata-queries.grit",
    "./lint-rules/no-manual-transactions.grit",
    "./lint-rules/no-inline-touch-cache.grit",
    "./lint-rules/no-stderr-write-in-commands.grit",
    "./lint-rules/no-args-join-in-release.grit"
  ],
  "files": {
    // custom-ca.ts excluded: Biome's type analysis hits the 200k type limit
    // on the node:tls module graph — an internal Biome bug that surfaces
    // non-deterministically as error vs warning. See biome issue tracker.
    "includes": [
      "!docs",
      "!test/init-eval/templates",
      "!dist-build",
      "!!src/lib/custom-ca.ts"
    ]
  },
  "javascript": {},
  "linter": {
    "rules": {
      "style": {
        "noRestrictedImports": {
          "level": "error",
          "options": {
            "paths": {
              "@stricli/core": {
                "importNames": ["buildCommand", "buildRouteMap"],
                "message": "Import buildCommand from '../lib/command.js' and buildRouteMap from '../lib/route-map.js' instead. The wrappers inject telemetry and standard subcommand aliases."
              }
            }
          }
        }
      }
    }
  },
  "overrides": [
    {
      // The React-hook lint rules infer "this is a hook" from the
      // `use*` naming convention. We have a couple of test helpers
      // (`useTestConfigDir`, `useEnvSandbox`) that share the prefix
      // by coincidence — they register `beforeEach`/`afterEach` and
      // have nothing to do with React. Without these overrides every
      // call site lights up `useHookAtTopLevel` since making the
      // tsconfig JSX-aware (for `OpenTuiUI`) flipped the rule on.
      // The actual React tree lives in `src/lib/init/ui/opentui-app.tsx`
      // and keeps the rule active.
      "includes": ["test/**/*.ts", "src/**/*.ts", "!src/**/*.tsx"],
      "linter": {
        "rules": {
          "correctness": {
            "useHookAtTopLevel": "off",
            "useExhaustiveDependencies": "off"
          }
        }
      }
    },
    {
      "includes": ["test/**/*.ts"],
      "linter": {
        "rules": {
          "performance": {
            "useTopLevelRegex": "off",
            "noDelete": "off"
          },
          "style": {
            "useBlockStatements": "off",
            "noNonNullAssertion": "off"
          },
          "suspicious": {
            "useAwait": "off"
          }
        }
      }
    },
    {
      // A few DB modules still have genuinely async functions (stat() for mtime validation,
      // clearResponseCache for auth cleanup). The useAwait rule is off for these specific files.
      "includes": [
        "src/lib/db/dsn-cache.ts",
        "src/lib/db/project-root-cache.ts",
        "src/lib/db/auth.ts"
      ],
      "linter": {
        "rules": {
          "suspicious": {
            "useAwait": "off"
          }
        }
      }
    },
    {
      // src/index.ts is the library entry point — re-exports SentryError, SentryOptions, SentrySDK
      // db/index.ts exports db connection utilities - not a barrel file but triggers the rule
      // api-client.ts is a barrel that re-exports from src/lib/api/ domain modules
      // to preserve the existing import path for all consumers
      // markdown.ts re-exports isPlainOutput from plain-detect.ts for backward compat
      // script/debug-id.ts re-exports from src/lib/sourcemap/debug-id.ts for build scripts
      "includes": [
        "src/index.ts",
        "src/lib/db/index.ts",
        "src/lib/api-client.ts",
        "src/lib/formatters/markdown.ts",
        "script/debug-id.ts"
      ],
      "linter": {
        "rules": {
          "performance": {
            "noBarrelFile": "off"
          }
        }
      }
    },
    {
      // command.ts and route-map.ts are the canonical wrappers — they must import from @stricli/core
      "includes": ["src/lib/command.ts", "src/lib/route-map.ts"],
      "linter": {
        "rules": {
          "style": {
            "noRestrictedImports": "off"
          }
        }
      }
    },
    {
      // Commands must use colorTag() from markdown.ts — not raw chalk.
      // Raw chalk bypasses the plain-output pipeline (NO_COLOR, SENTRY_PLAIN_OUTPUT).
      "includes": ["src/commands/**/*.ts"],
      "linter": {
        "rules": {
          "style": {
            "noRestrictedImports": {
              "level": "error",
              "options": {
                "paths": {
                  "@stricli/core": {
                    "importNames": ["buildCommand", "buildRouteMap"],
                    "message": "Import buildCommand from '../lib/command.js' and buildRouteMap from '../lib/route-map.js' instead. The wrappers inject telemetry and standard subcommand aliases."
                  },
                  "chalk": {
                    "message": "Use colorTag() from formatters/markdown.js for colored output. Raw chalk bypasses the plain-output pipeline (NO_COLOR, SENTRY_PLAIN_OUTPUT)."
                  }
                }
              }
            }
          }
        }
      }
    }
  ]
}
