// ESLint flat config (v0.7 P4, D-048) — ONE config at repo root covers all // TS workspaces; each workspace runs `eslint .` and resolves this file // upward. Deliberately MINIMAL (the milestone goal is a working lint gate, // not maximal strictness): js/recommended + typescript-eslint recommended // (NON type-checked — no project-service, no type-aware rules) + the // react-hooks CORE rules on React surfaces. Type-aware linting stays out: // the 5 tsc projects already own that job (pnpm typecheck). import js from '@eslint/js'; import tseslint from 'typescript-eslint'; import reactHooks from 'eslint-plugin-react-hooks'; import globals from 'globals'; export default tseslint.config( // ---- global ignores: build output + generated files only. Source, // tests, and stories all stay in scope (stories are display-only but // linting them is cheap). { ignores: [ '**/node_modules/', '**/dist/', '**/.next/', '**/out/', '**/.turbo/', '**/coverage/', '**/storybook-static/', '**/.venv/', '**/next-env.d.ts', // generated by `next dev/build` 'apps/web/css.d.ts', // generated by @tailwindcss/postcss ], }, // ---- base: @eslint/js recommended for ALL linted files { ...js.configs.recommended, files: ['**/*.ts', '**/*.tsx', '**/*.mjs', '**/*.cjs'], }, // ---- Node scripts (.mjs/.cjs): build scripts + tooling configs run in // Node — they need process/console. { files: ['**/*.mjs', '**/*.cjs'], languageOptions: { globals: { ...globals.node }, }, }, // ---- TypeScript: recommended, non type-checked (fast — no program needed) { files: ['**/*.ts', '**/*.tsx'], extends: [tseslint.configs.recommended], languageOptions: { globals: { ...globals.node }, }, }, // ---- React hooks: the CORE rules (rules-of-hooks, exhaustive-deps) on // web + ui, ts AND tsx (hook files like use-sandbox-session.ts live in // .ts). eslint-plugin-react-hooks v7's `recommended` preset additionally // bundles the React-Compiler-era rules (purity, immutability, // set-state-in-effect, ...) which fire on shipped components; this gate // intentionally takes only the two core rules — the milestone goal is a // working lint gate, not maximal strictness (D-048). { files: [ 'apps/web/**/*.ts', 'apps/web/**/*.tsx', 'packages/ui/**/*.ts', 'packages/ui/**/*.tsx', ], plugins: { 'react-hooks': reactHooks }, rules: { 'react-hooks/rules-of-hooks': 'error', 'react-hooks/exhaustive-deps': 'warn', }, languageOptions: { globals: { ...globals.browser, ...globals.node }, }, }, );