// ESLint 10 flat config. Scope is deliberately small: this project targets zero // client JavaScript (CLAUDE.md, AGENTS.md ยง7), so the only JS/TS here is build // configuration, site data, and the occasional island. Rules exist to catch // mistakes, not to impose style โ Prettier owns formatting. // // `typescript-eslint` is here because .astro frontmatter IS TypeScript, so the // plugin cannot parse a single component without it. It runs unconfigured for // type-awareness on purpose: `astro check` already does the type checking, and // duplicating it here would be slower and would disagree at the edges. import js from '@eslint/js'; import globals from 'globals'; import tseslint from 'typescript-eslint'; import astro from 'eslint-plugin-astro'; export default [ { ignores: ['dist/**', 'node_modules/**', '.astro/**', 'docs/reference/**'] }, js.configs.recommended, ...tseslint.configs.recommended, ...astro.configs.recommended, ...astro.configs['flat/jsx-a11y-recommended'], // `no-undef` off for TYPESCRIPT ONLY, on typescript-eslint's own advice: it // has no type information, so every ambient global is a false positive โ // Astro declares `ImageMetadata`, `astroHTML.JSX` and friends globally, and // .astro frontmatter IS TypeScript. tsc catches a real undefined reference, // which is what `npm run check` is for. // // NOT applied to .js/.mjs. `tsconfig.json` sets `allowJs` without `checkJs`, // so plain JS is not type-checked by anything โ turning the rule off there // meant a typo like `procss.env.X` in astro.config.mjs passed lint silently. { files: ['**/*.ts', '**/*.astro'], rules: { 'no-undef': 'off' }, }, { files: ['**/*.{js,mjs,ts}', '**/*.astro'], languageOptions: { ecmaVersion: 2023, sourceType: 'module', globals: { ...globals.browser, ...globals.node }, }, rules: { // A stray console.log in a static build is dead weight shipped to nobody. 'no-console': ['warn', { allow: ['warn', 'error'] }], // `role="list"` on a