import js from "@eslint/js"; import jsdoc from "eslint-plugin-jsdoc"; import importPlugin from "eslint-plugin-import"; import globals from "globals"; import { fileURLToPath } from "url"; import { dirname } from "path"; const __dirname = dirname(fileURLToPath(import.meta.url)); export default [ js.configs.recommended, { plugins: { jsdoc, import: importPlugin, }, languageOptions: { globals: { // Browser built-ins (console, setTimeout, etc.) ...globals.browser, // Node.js globals for scripts ...globals.node, // FoundryVTT globals injected at runtime Hooks: "readonly", game: "readonly", ui: "readonly", canvas: "readonly", foundry: "readonly", CONFIG: "readonly", CONST: "readonly", }, }, settings: { // Support path aliases for import resolution "import/resolver": { node: { extensions: [".js", ".mjs"], }, }, }, rules: { // Require JSDoc on all exported symbols "jsdoc/require-jsdoc": [ "warn", // Changed from error to warn { publicOnly: true, require: { FunctionDeclaration: true, MethodDefinition: true, ClassDeclaration: true, ArrowFunctionExpression: false, FunctionExpression: false, }, contexts: ["ExportNamedDeclaration > FunctionDeclaration"], }, ], "jsdoc/require-param": "warn", "jsdoc/require-returns": "warn", // Import boundary enforcement "import/no-restricted-paths": [ "error", { zones: [ // src/core/ → may import src/contracts/ and src/utils/ ONLY { target: "./src/core", from: "./src/foundry", message: "src/core/ must not import from src/foundry/", }, { target: "./src/core", from: "./src/ui", message: "src/core/ must not import from src/ui/", }, { target: "./src/core", from: "./src/notifications", message: "src/core/ must not import from src/notifications/", }, { target: "./src/core", from: "./src/presets", message: "src/core/ must not import from src/presets/", }, // src/foundry/ → may import src/contracts/ and src/utils/ ONLY { target: "./src/foundry", from: "./src/core", message: "src/foundry/ must not import from src/core/", }, { target: "./src/foundry", from: "./src/ui", message: "src/foundry/ must not import from src/ui/", }, { target: "./src/foundry", from: "./src/notifications", message: "src/foundry/ must not import from src/notifications/", }, { target: "./src/foundry", from: "./src/presets", message: "src/foundry/ must not import from src/presets/", }, // src/contracts/ → no internal imports { target: "./src/contracts", from: "./src", message: "src/contracts/ must not import from other src/ modules", }, // src/utils/ → no internal imports { target: "./src/utils", from: "./src", message: "src/utils/ must not import from other src/ modules", }, ], }, ], // Allow unused variables starting with underscore "no-unused-vars": [ "warn", // Changed from error to warn { argsIgnorePattern: "^_", varsIgnorePattern: "^_", caughtErrorsIgnorePattern: "^_", }, ], // Allow empty catch blocks with underscore "no-empty": [ "error", { allowEmptyCatch: true, }, ], }, }, { files: ["tests/**/*.js"], rules: { // Relax rules for test files "jsdoc/require-jsdoc": "off", "no-unused-vars": "warn", "no-empty": "warn", }, }, { files: ["scripts/**/*.mjs"], languageOptions: { globals: { // Ensure Node.js globals are available in ESM script files ...globals.node, }, }, rules: { // Allow unused imports in scripts "no-unused-vars": "warn", "no-empty": "warn", }, }, { ignores: [ "dist/", "node_modules/", "*.zip", "_bmad-output/", "test-results/", "tests/e2e/_bmad-output/", "tests/e2e/fixtures/", "tests/fixtures/", "tests/helpers/", "**/trace/", "**/assets/codeMirrorModule-*.js", ], }, ];