{
  "$schema": "https://biomejs.dev/schemas/2.5.14/schema.json",
  "vcs": {
    "enabled": true,
    "clientKind": "git",
    "useIgnoreFile": true
  },
  "files": {
    "ignoreUnknown": false,
    "includes": [
      "**/*.js",
      "**/*.jsx",
      "**/*.ts",
      "**/*.tsx",
      "**/*.json",
      "**/*.jsonc",
      "**/*.grit",
      "**/*.mjs",
      "**/*.cjs",
      "!!.codex",
      // Unmodified upstream js-yaml distribution bundled for installed agent skills.
      "!!plugins/promptfoo/skills/promptfoo-provider-setup/scripts/vendor",
      "!!drizzle",
      "!!src/app/src/polyfills",
      "!!**/node_modules",
      "!!**/dist",
      "!!**/build",
      "!!**/public",
      "!!examples/config-multi-turn/prompt.json",
      "!!examples/openai-chat-history/prompt.json",
      "!!test/fixtures/rubric-json-template/**/*.json",
      // Excluded due to stack overflow crash in biome - see https://github.com/biomejs/biome/issues/8783
      "!!src/redteam/shared/runtimeTransform.ts",
      "!!plugins/promptfoo/skills/promptfoo-provider-setup/scripts/openapi-operation-to-config.mjs",
      "!!plugins/promptfoo/skills/promptfoo-redteam-setup/scripts/openapi-operation-to-redteam-config.mjs"
    ]
  },
  "formatter": {
    "enabled": true,
    "formatWithErrors": false,
    "indentStyle": "space",
    "indentWidth": 2,
    "lineWidth": 100,
    "lineEnding": "lf"
  },
  "assist": {
    "actions": {
      "source": {
        "noDuplicateClasses": "on",
        "organizeImports": {
          "level": "on",
          "options": {
            "groups": [
              {
                "type": false,
                "source": ["react", "react-dom", "react/**", "react-dom/**"]
              },
              ["react", "react-dom", "react/**", "react-dom/**"],
              ":BLANK_LINE:",
              {
                "type": false,
                "source": [":NODE:", ":BUN:"]
              },
              [":NODE:", ":BUN:"],
              ":BLANK_LINE:",
              {
                "type": false,
                "source": ["**"]
              },
              [
                "**",
                "!./**",
                "!../**",
                "!src/**",
                "!test/**",
                "!examples/**",
                "!react",
                "!react-dom",
                "!react/**",
                "!react-dom/**"
              ],
              ":BLANK_LINE:",
              {
                "type": false,
                "source": ["src/**", "test/**", "examples/**"]
              },
              ["src/**", "test/**", "examples/**"],
              ":BLANK_LINE:",
              {
                "type": false,
                "source": ["./**", "../**"]
              },
              ["./**", "../**"]
            ]
          }
        }
      }
    }
  },
  "linter": {
    "enabled": true,
    "rules": {
      "preset": "none",
      "complexity": {
        "noUselessConstructor": "error",
        "noUselessRename": "error",
        "noUselessTernary": "error",
        "noUselessFragments": "error",
        "useOptionalChain": "off",
        "noExcessiveCognitiveComplexity": {
          "level": "warn",
          "options": {
            "maxAllowedComplexity": 30
          }
        }
      },
      "correctness": {
        "noUnusedVariables": "error",
        "noUnusedImports": "error",
        "useExhaustiveDependencies": "error",
        "noUnusedFunctionParameters": "error",
        "useJsxKeyInIterable": "error",
        "useIsNan": "error"
      },
      "style": {
        "noEnum": "error",
        "noNegationElse": "error",
        "useConst": "error",
        "useBlockStatements": "error",
        "useShorthandAssign": "off",
        "useShorthandFunctionType": "off",
        "useTemplate": "off",
        "useNumberNamespace": "off",
        "useSingleVarDeclarator": "off",
        "useImportType": "off",
        "useNodejsImportProtocol": "off",
        "noNonNullAssertion": "off",
        "noRestrictedGlobals": {
          "level": "error",
          "options": {
            "deniedGlobals": {
              "fetch": "Use fetchWithProxy() instead of global fetch()."
            }
          }
        },
        "noRestrictedImports": {
          "level": "error",
          "options": {
            "paths": {
              "node-fetch": "Use fetchWithProxy() (do not import node-fetch directly).",
              "undici": {
                "importNames": ["fetch", "default"],
                "message": "Use fetchWithProxy() instead of undici.fetch."
              },
              "cross-fetch": "Use fetchWithProxy() instead."
            },
            "patterns": [{ "group": ["whatwg-fetch", "isomorphic-fetch"] }]
          }
        }
      },
      "suspicious": {
        "noAsyncPromiseExecutor": "error",
        "noDebugger": "error",
        "noExplicitAny": "error",
        "noArrayIndexKey": "off",
        "noCommentText": "off",
        "noConfusingVoidType": "error",
        "noDuplicateCase": "error",
        "noDuplicateClassMembers": "error",
        "noDuplicateElseIf": "error",
        "noDuplicateJsxProps": "error",
        "noDuplicateObjectKeys": "error",
        "noDuplicateParameters": "error",
        "noDuplicateTestHooks": "error",
        "noFocusedTests": "error",
        "noSkippedTests": "error",
        "noRedundantUseStrict": "error",
        "noThenProperty": "error",
        "useErrorMessage": "warn",
        "useIterableCallbackReturn": "off",
        "noSelfCompare": "error"
      },
      "performance": {
        "noDelete": "off",
        "noBarrelFile": "off",
        "noReExportAll": "off"
      },
      "a11y": {
        "preset": "none",
        "useButtonType": "off"
      },
      "nursery": {
        "noFloatingPromises": "error",
        // Disabled on the 2.5.5 upgrade. It cost 36s of a 45s `biome ci .` run on
        // this repo (45.5s -> 9.5s with it off), which pushed the Style Check job
        // past its timeout, and 4 of the 5 things it flagged were false positives:
        // 2.5.5 does not unwrap `await` over `Promise<T> | null`, so it reports a
        // resolved `string | null` as a promise in a conditional. Re-enable when
        // upstream makes it cheaper and fixes the await-unwrapping.
        "noMisusedPromises": "off",
        "noUselessTypeConversion": "error",
        "noIdenticalTestTitle": "error",
        "useReduceTypeParameter": "warn"
      }
    }
  },
  "javascript": {
    "formatter": {
      "enabled": true,
      "quoteStyle": "single",
      "jsxQuoteStyle": "double",
      "trailingCommas": "all",
      "semicolons": "always",
      "arrowParentheses": "always",
      "bracketSpacing": true,
      "bracketSameLine": false,
      "quoteProperties": "asNeeded",
      "attributePosition": "auto"
    },
    "parser": {
      "unsafeParameterDecoratorsEnabled": true
    },
    "globals": [
      "process",
      "Buffer",
      "__dirname",
      "__filename",
      "console",
      "global",
      "require",
      "module",
      "exports"
    ]
  },
  "css": {
    "formatter": {
      "enabled": false
    }
  },
  "overrides": [
    {
      "includes": [
        "examples/config-multi-turn/prompt.json",
        "examples/openai-chat-history/prompt.json"
      ],
      "linter": {
        "enabled": false
      },
      "formatter": {
        "enabled": false
      }
    },
    {
      "includes": ["examples/provider-custom/basic/vercelAiSdkExample.js"],
      "linter": {
        "enabled": false
      },
      "formatter": {
        "enabled": false
      }
    },
    {
      "includes": [".jest/**/*.js"],
      "linter": {
        "enabled": false
      },
      "formatter": {
        "enabled": false
      }
    },
    {
      "includes": ["*.mdc"],
      "formatter": {
        "enabled": false
      }
    },
    {
      "includes": ["*.j2"],
      "formatter": {
        "enabled": false
      }
    },
    {
      "includes": ["test/**/*", "**/*.test.ts", "**/*.test.tsx", "**/*.spec.ts", "**/*.spec.tsx"],
      "linter": {
        "rules": {
          "correctness": {
            "noUnusedVariables": "error"
          },
          "style": {
            "noRestrictedGlobals": "off"
          },
          "suspicious": {
            "noExplicitAny": "off"
          },
          "nursery": {
            "noFloatingPromises": "off"
          }
        }
      }
    },
    {
      "includes": [
        "*.js",
        "*.jsx",
        "*.ts",
        "*.tsx",
        "*.mjs",
        "*.cjs",
        "**/*.js",
        "**/*.jsx",
        "**/*.ts",
        "**/*.tsx",
        "**/*.mjs",
        "**/*.cjs"
      ],
      "plugins": ["./tools/biome/no-direct-process-env-mutation.grit"]
    },
    {
      "includes": ["src/app/**/*"],
      "linter": {
        "rules": {
          "style": {
            "noRestrictedGlobals": "off"
          },
          "performance": {
            "noBarrelFile": "off",
            "noReExportAll": "off"
          },
          "nursery": {
            "noFloatingPromises": "off"
          }
        }
      }
    },
    {
      "includes": [
        "src/providers/**/*",
        "src/redteam/**/*",
        "src/util/**/*",
        "src/commands/**/*",
        "src/node/doEval.ts",
        "src/contracts/**/*",
        "src/types/**/*",
        "src/tracing/**/*"
      ],
      "linter": {
        "rules": {
          "suspicious": {
            "noExplicitAny": "off"
          }
        }
      }
    },
    {
      "includes": ["examples/**/*", "site/**/*"],
      "linter": {
        "rules": {
          "preset": "none",
          "correctness": {
            "noUnusedImports": "off",
            "noUnusedVariables": "off",
            "noUnusedFunctionParameters": "off"
          },
          "style": {
            "noRestrictedGlobals": "off",
            "useBlockStatements": "off"
          },
          "suspicious": {
            "noExplicitAny": "off"
          },
          "performance": {
            "noBarrelFile": "off",
            "noReExportAll": "off"
          },
          "nursery": {
            "noFloatingPromises": "off"
          }
        }
      }
    }
  ]
}
