{"_id":"@444leod/lint","_rev":"9-ca936fab153651717aefb603332c8c82","name":"@444leod/lint","dist-tags":{"latest":"1.0.0"},"versions":{"0.1.0":{"name":"@444leod/lint","version":"0.1.0","license":"MIT","_id":"@444leod/lint@0.1.0","maintainers":[{"name":"444leod","email":"perso.leo.dumont@gmail.com"}],"dist":{"shasum":"df8cda583e0fecbe2c5c63f2344f7649e39723a2","tarball":"https://registry.npmjs.org/@444leod/lint/-/lint-0.1.0.tgz","fileCount":40,"integrity":"sha512-AO087QT/jyoeuacNrq+cNOFg+/seRCBzfix7xAIJQ7hgss11Y/jhzQIarRsBurKzNasBev/q3f9tq3HDB6Vsqg==","signatures":[{"sig":"MEUCIQDMidKmI7LAnNT35fgn7SlRXVKpk74tJJyx6XUwot7g9AIgUpZQglgl0AXPBb3cx49hZHn3XZOvIfaQL4dQs6neqDc=","keyid":"SHA256:DhQ8wR5APBvFHLF/+Tc+AYvPOdTpcIDqOhxsBHRwC7U"}],"unpackedSize":209011},"main":"./dist/index.mjs","type":"module","types":"./dist/index.d.mts","exports":{"./eslint":{"types":"./dist/index.d.mts","import":"./dist/index.mjs"},"./biome.json":"./biome.json","./.oxlintrc.json":"./.oxlintrc.json","./react-doctor.config.json":"./react-doctor.config.json"},"scripts":{"dev":"turbo dev","build":"turbo build --filter=./packages/* && tsdown"},"_npmUser":{"name":"444leod","email":"perso.leo.dumont@gmail.com"},"workspaces":["packages/*"],"_npmVersion":"11.6.0","description":"Unified linting for Next.js + Elysia + TanStack Query + Drizzle monorepos","directories":{},"_nodeVersion":"22.19.0","dependencies":{"typescript-eslint":"^8.58.0","eslint-config-sheriff":"^31.3.0","@444leod/eslint-config":"workspace:*","eslint-plugin-react-doctor":"^0.2.0-beta.5","@444leod/eslint-plugin-guardrails":"workspace:*"},"_hasShrinkwrap":false,"packageManager":"bun@1.3.1","devDependencies":{"turbo":"^2.8.12","eslint":"^9","tsdown":"^0.21.7","typescript":"^5","@types/eslint":"^9"},"peerDependencies":{"eslint":">=9.0.0"},"_npmOperationalInternal":{"tmp":"tmp/lint_0.1.0_1779001752393_0.6740359143751491","host":"s3://npm-registry-packages-npm-production"}},"0.1.1":{"name":"@444leod/lint","version":"0.1.1","license":"MIT","_id":"@444leod/lint@0.1.1","maintainers":[{"name":"444leod","email":"perso.leo.dumont@gmail.com"}],"dist":{"shasum":"cc40dacb589d1c784b98f56eb353256712050adc","tarball":"https://registry.npmjs.org/@444leod/lint/-/lint-0.1.1.tgz","fileCount":7,"integrity":"sha512-VQNrkleJL2ccqTTKqZDjHsW7yYuLOOVDhHkcZRxTQWEoAjz/eEQETkjQfoCHkZQD2CXX4uazVfQE5AX6hzq9QA==","signatures":[{"sig":"MEUCIQCR8ugESUARNjoWbmVgJxNk0QSbxY4kWEtFCzgZm7ab7wIgHwLb7+ZfAul5fgXNJmyZa0YLIHVxM39HcTuweaA03Y0=","keyid":"SHA256:DhQ8wR5APBvFHLF/+Tc+AYvPOdTpcIDqOhxsBHRwC7U"}],"unpackedSize":28944},"main":"./dist/index.mjs","type":"module","types":"./dist/index.d.mts","exports":{"./eslint":{"types":"./dist/index.d.mts","import":"./dist/index.mjs"},"./biome.json":"./biome.json","./.oxlintrc.json":"./.oxlintrc.json","./react-doctor.config.json":"./react-doctor.config.json"},"scripts":{"dev":"tsdown --watch","build":"tsdown"},"_npmUser":{"name":"444leod","email":"perso.leo.dumont@gmail.com"},"_npmVersion":"11.6.0","description":"Unified linting for Next.js + Elysia + TanStack Query + Drizzle monorepos","directories":{},"_nodeVersion":"22.19.0","dependencies":{"typescript-eslint":"^8.58.0","eslint-config-sheriff":"^31.3.0","eslint-plugin-react-doctor":"^0.2.0-beta.5"},"_hasShrinkwrap":false,"packageManager":"bun@1.3.1","devDependencies":{"eslint":"^9","tsdown":"^0.21.7","typescript":"^5","@types/eslint":"^9"},"peerDependencies":{"eslint":">=9.0.0"},"_npmOperationalInternal":{"tmp":"tmp/lint_0.1.1_1779002295386_0.3156523304186303","host":"s3://npm-registry-packages-npm-production"}},"0.1.2":{"name":"@444leod/lint","version":"0.1.2","license":"MIT","_id":"@444leod/lint@0.1.2","maintainers":[{"name":"444leod","email":"perso.leo.dumont@gmail.com"}],"dist":{"shasum":"0db9677953712a97d25363b841471542147185f7","tarball":"https://registry.npmjs.org/@444leod/lint/-/lint-0.1.2.tgz","fileCount":7,"integrity":"sha512-1VxHrK+w5C5cc+AY68jH/PKqjRukKXCoDNZZSPRJt/K+n76czUtbX3YPLTUDqhr0DNmW8LLEfMZrQt1kgSu1ZQ==","signatures":[{"sig":"MEUCIH1OWG0N2wL6pEPjnlLy/SHlamlEg+OSNfMw7+P+qa6hAiEA3UcJy6VdAvqNbDwV5xrO+T1IxAESY1MNYmwaWfVfUjk=","keyid":"SHA256:DhQ8wR5APBvFHLF/+Tc+AYvPOdTpcIDqOhxsBHRwC7U"}],"unpackedSize":28997},"main":"./dist/index.mjs","type":"module","types":"./dist/index.d.mts","exports":{"./eslint":{"types":"./dist/index.d.mts","import":"./dist/index.mjs"},"./biome.json":"./biome.json","./.oxlintrc.json":"./.oxlintrc.json","./react-doctor.config.json":"./react-doctor.config.json"},"scripts":{"dev":"tsdown --watch","build":"tsdown"},"_npmUser":{"name":"444leod","email":"perso.leo.dumont@gmail.com"},"_npmVersion":"11.6.0","description":"Unified linting for Next.js + Elysia + TanStack Query + Drizzle monorepos","directories":{},"_nodeVersion":"22.19.0","dependencies":{"oxlint":"^1.59.0","@biomejs/biome":"^2.2.0","typescript-eslint":"^8.58.0","eslint-config-sheriff":"^31.3.0","eslint-plugin-react-doctor":"^0.2.0-beta.5"},"_hasShrinkwrap":false,"packageManager":"bun@1.3.1","devDependencies":{"eslint":"^9","tsdown":"^0.21.7","typescript":"^5","@types/eslint":"^9"},"peerDependencies":{"eslint":">=9.0.0"},"_npmOperationalInternal":{"tmp":"tmp/lint_0.1.2_1779002678583_0.9247391010701713","host":"s3://npm-registry-packages-npm-production"}},"0.1.3":{"name":"@444leod/lint","version":"0.1.3","license":"MIT","_id":"@444leod/lint@0.1.3","maintainers":[{"name":"444leod","email":"perso.leo.dumont@gmail.com"}],"dist":{"shasum":"8dd05cb97144515265974f877dbd5b85037a767d","tarball":"https://registry.npmjs.org/@444leod/lint/-/lint-0.1.3.tgz","fileCount":7,"integrity":"sha512-/RwQlIRxGCCZxsF1hE/5GxDcvrZbgnXuDj8ZbRL928mWU8q9NHxUkr6Stf8YUCOQ1M3oy5ERGywHaPUgmKDrWA==","signatures":[{"sig":"MEUCIEu6GSH/PDtN8DG+OiaMQEA8MprUsF0uJ8HHHzbZXFIUAiEAkK0pC4YlAN0DvnV1+r+ZiKn0aY/IWPADu33xmUc/K/s=","keyid":"SHA256:DhQ8wR5APBvFHLF/+Tc+AYvPOdTpcIDqOhxsBHRwC7U"}],"unpackedSize":28997},"main":"./dist/index.mjs","type":"module","types":"./dist/index.d.mts","exports":{"./eslint":{"types":"./dist/index.d.mts","import":"./dist/index.mjs"},"./biome.json":"./biome.json","./.oxlintrc.json":"./.oxlintrc.json","./react-doctor.config.json":"./react-doctor.config.json"},"scripts":{"dev":"tsdown --watch","build":"tsdown"},"_npmUser":{"name":"444leod","email":"perso.leo.dumont@gmail.com"},"_npmVersion":"11.6.0","description":"Unified linting for Next.js + Elysia + TanStack Query + Drizzle monorepos","directories":{},"_nodeVersion":"22.19.0","dependencies":{"oxlint":"^1.59.0","@biomejs/biome":"^2.2.0","typescript-eslint":"^8.58.0","eslint-config-sheriff":"^31.3.0","eslint-plugin-react-doctor":"^0.2.0-beta.5"},"_hasShrinkwrap":false,"packageManager":"bun@1.3.1","devDependencies":{"eslint":"^9","tsdown":"^0.21.7","typescript":"^5","@types/eslint":"^9"},"peerDependencies":{"eslint":">=9.0.0"},"_npmOperationalInternal":{"tmp":"tmp/lint_0.1.3_1779002898285_0.25964235223351806","host":"s3://npm-registry-packages-npm-production"}},"0.2.0":{"name":"@444leod/lint","version":"0.2.0","license":"MIT","_id":"@444leod/lint@0.2.0","maintainers":[{"name":"444leod","email":"perso.leo.dumont@gmail.com"}],"bin":{"444lint":"dist/cli.mjs"},"dist":{"shasum":"8502fcc2921e799091768f4328f8e7a34ccbf458","tarball":"https://registry.npmjs.org/@444leod/lint/-/lint-0.2.0.tgz","fileCount":10,"integrity":"sha512-QlwLZVyKyEjRVfnYhOHnHnuKoqbVrFyNefwgI21SoSOHk7EFA0nOdxjVckTFC8HF7qhzkylFHUR41Lof3huCuw==","signatures":[{"sig":"MEUCIFAgTL7UGTNuUf3XA2bsXrSBGU2uOxYaKhfvEVUyqDpzAiEAzmRpmVGOo8iPgDLST+1X75GDBySZ2BLa+4jaDQ+/QGI=","keyid":"SHA256:DhQ8wR5APBvFHLF/+Tc+AYvPOdTpcIDqOhxsBHRwC7U"}],"unpackedSize":34885},"main":"./dist/index.mjs","type":"module","types":"./dist/index.d.mts","exports":{"./eslint":{"types":"./dist/index.d.mts","import":"./dist/index.mjs"},"./biome.json":"./biome.json","./.oxlintrc.json":"./.oxlintrc.json","./react-doctor.config.json":"./react-doctor.config.json"},"scripts":{"dev":"tsdown --watch","build":"tsdown","prepublishOnly":"tsdown"},"_npmUser":{"name":"444leod","email":"perso.leo.dumont@gmail.com"},"_npmVersion":"11.14.1","description":"Unified linting for Next.js + Elysia + TanStack Query + Drizzle monorepos","directories":{},"_nodeVersion":"22.19.0","dependencies":{"oxlint":"^1.59.0","@biomejs/biome":"^2.4.15","typescript-eslint":"^8.58.0","eslint-config-sheriff":"^31.3.0","eslint-plugin-react-doctor":"^0.2.0-beta.5"},"publishConfig":{"access":"public"},"_hasShrinkwrap":false,"packageManager":"bun@1.3.1","devDependencies":{"eslint":"^9","tsdown":"^0.21.7","typescript":"^5","@types/eslint":"^9"},"peerDependencies":{"eslint":">=9.0.0"},"_npmOperationalInternal":{"tmp":"tmp/lint_0.2.0_1783878464153_0.44378639529744635","host":"s3://npm-registry-packages-npm-production"}},"0.3.0":{"name":"@444leod/lint","version":"0.3.0","license":"MIT","_id":"@444leod/lint@0.3.0","maintainers":[{"name":"444leod","email":"perso.leo.dumont@gmail.com"}],"bin":{"444lint":"dist/cli.mjs"},"dist":{"shasum":"4fb9785ec75354c4ff373d39050fa9ad07ce4f06","tarball":"https://registry.npmjs.org/@444leod/lint/-/lint-0.3.0.tgz","fileCount":10,"integrity":"sha512-QDWKVC579H0YHTn3NPPunjXMxWSRWwU2k6TJRiuty1e/Dqinl0lEzFjoT19W+kFt58xmKjrSxUimraMRS19sxQ==","signatures":[{"sig":"MEYCIQCFWqiTM0ggZ6vzsfNksfwfyGVXR3IlOKO3nin7BxM7cwIhAKRdRQd/k89Gx4+RZGJafofa6Ewzgvi5iXxZcgaMljiT","keyid":"SHA256:DhQ8wR5APBvFHLF/+Tc+AYvPOdTpcIDqOhxsBHRwC7U"}],"unpackedSize":34925},"main":"./dist/index.mjs","type":"module","types":"./dist/index.d.mts","exports":{"./eslint":{"types":"./dist/index.d.mts","import":"./dist/index.mjs"},"./biome.json":"./biome.json","./.oxlintrc.json":"./.oxlintrc.json","./react-doctor.config.json":"./react-doctor.config.json"},"gitHead":"397dde02b590ed4ccc81d95b3220339d18b8ebcc","scripts":{"dev":"tsdown --watch","build":"tsdown","typecheck":"tsc --noEmit","prepublishOnly":"tsdown"},"_npmUser":{"name":"444leod","email":"perso.leo.dumont@gmail.com"},"_npmVersion":"11.14.1","description":"Unified linting for Next.js + Elysia + TanStack Query + Drizzle monorepos","directories":{},"_nodeVersion":"22.19.0","dependencies":{"oxlint":"1.73.0","@biomejs/biome":"2.5.3","typescript-eslint":"8.63.0","eslint-config-sheriff":"31.4.0","eslint-plugin-react-doctor":"0.7.6"},"publishConfig":{"access":"public"},"_hasShrinkwrap":false,"packageManager":"bun@1.3.1","devDependencies":{"eslint":"9.39.4","tsdown":"0.22.5","typescript":"5.9.3","@types/node":"22.20.1"},"peerDependencies":{"eslint":">=9.0.0"},"_npmOperationalInternal":{"tmp":"tmp/lint_0.3.0_1783887939646_0.8300972001862512","host":"s3://npm-registry-packages-npm-production"}},"0.4.0":{"name":"@444leod/lint","version":"0.4.0","license":"MIT","_id":"@444leod/lint@0.4.0","maintainers":[{"name":"444leod","email":"perso.leo.dumont@gmail.com"}],"bin":{"444lint":"dist/cli.mjs"},"dist":{"shasum":"84d702e050de5d41d1e87773f632fdade472d242","tarball":"https://registry.npmjs.org/@444leod/lint/-/lint-0.4.0.tgz","fileCount":10,"integrity":"sha512-G6v1BTaMgDzH6vqoskXRmd0uAenAnXAlxZE5exrDT6DWfYNSXWQDwFOBssC8Evz99sdcK+gOdk/nFBt0zcUobg==","signatures":[{"sig":"MEUCIQC0+UtVsUPZg2wI8O4krD9PPvVJIGmjTQ6ZqTmqJxq4zgIge8hrSCbS4Z8GVmaBgwZGb527nN1KjABsVuvLWMmFES0=","keyid":"SHA256:DhQ8wR5APBvFHLF/+Tc+AYvPOdTpcIDqOhxsBHRwC7U"}],"unpackedSize":37121},"main":"./dist/index.mjs","type":"module","types":"./dist/index.d.mts","exports":{"./eslint":{"types":"./dist/index.d.mts","import":"./dist/index.mjs"},"./biome.json":"./biome.json","./.oxlintrc.json":"./.oxlintrc.json","./react-doctor.config.json":"./react-doctor.config.json"},"gitHead":"7136ba308072c1ebe2b3e0fc644752c0e23a499c","scripts":{"dev":"tsdown --watch","build":"tsdown","typecheck":"tsc --noEmit","prepublishOnly":"tsdown"},"_npmUser":{"name":"444leod","email":"perso.leo.dumont@gmail.com"},"_npmVersion":"11.14.1","description":"Unified linting for Next.js + Elysia + TanStack Query + Drizzle monorepos","directories":{},"_nodeVersion":"22.19.0","dependencies":{"oxlint":"1.73.0","react-doctor":"0.7.6","@biomejs/biome":"2.5.3","typescript-eslint":"8.63.0","eslint-config-sheriff":"31.4.0","eslint-plugin-react-doctor":"0.7.6"},"publishConfig":{"access":"public"},"_hasShrinkwrap":false,"packageManager":"bun@1.3.1","devDependencies":{"eslint":"9.39.4","tsdown":"0.22.5","typescript":"5.9.3","@types/node":"22.20.1"},"peerDependencies":{"eslint":"^9"},"_npmOperationalInternal":{"tmp":"tmp/lint_0.4.0_1783891998620_0.22175166649252498","host":"s3://npm-registry-packages-npm-production"}},"0.5.0":{"name":"@444leod/lint","version":"0.5.0","license":"MIT","_id":"@444leod/lint@0.5.0","maintainers":[{"name":"444leod","email":"perso.leo.dumont@gmail.com"}],"bin":{"444lint":"dist/cli.mjs"},"dist":{"shasum":"eed32732e39c7f2c82f103f520283b07c03cdebd","tarball":"https://registry.npmjs.org/@444leod/lint/-/lint-0.5.0.tgz","fileCount":10,"integrity":"sha512-akzS7vYNAWdt948OEstD53G1Sm5BfmOvEJJzsqGCSj1uRdc5Mp7v28EX7x9rSi88/uECGziY77hqCtZnknWayg==","signatures":[{"sig":"MEUCIQCCc3LywIHegg2rguS6nVFAjk7gPZVbf35jFxG8Vfj+fAIgQj0RchROKYBR/hymV3oNaYrQZI4IMKpxNyhpnKzimG8=","keyid":"SHA256:DhQ8wR5APBvFHLF/+Tc+AYvPOdTpcIDqOhxsBHRwC7U"}],"unpackedSize":39637},"main":"./dist/index.mjs","type":"module","types":"./dist/index.d.mts","exports":{"./eslint":{"types":"./dist/index.d.mts","import":"./dist/index.mjs"},"./biome.json":"./biome.json","./.oxlintrc.json":"./.oxlintrc.json","./react-doctor.config.json":"./react-doctor.config.json"},"gitHead":"3ecdef497841e24ad1bef4cf8b9d7eac23c1bab7","scripts":{"dev":"tsdown --watch","build":"tsdown","typecheck":"tsc --noEmit","prepublishOnly":"tsdown"},"_npmUser":{"name":"444leod","email":"perso.leo.dumont@gmail.com"},"_npmVersion":"11.14.1","description":"Unified linting for Next.js + Elysia + TanStack Query + Drizzle monorepos","directories":{},"_nodeVersion":"22.19.0","dependencies":{"oxlint":"1.73.0","react-doctor":"0.7.6","@biomejs/biome":"2.5.3","typescript-eslint":"8.63.0","eslint-config-sheriff":"31.4.0","eslint-plugin-react-doctor":"0.7.6"},"publishConfig":{"access":"public"},"_hasShrinkwrap":false,"packageManager":"bun@1.3.1","devDependencies":{"eslint":"9.39.4","tsdown":"0.22.5","typescript":"5.9.3","@types/node":"22.20.1"},"peerDependencies":{"eslint":"^9"},"_npmOperationalInternal":{"tmp":"tmp/lint_0.5.0_1783896044782_0.04742007256358205","host":"s3://npm-registry-packages-npm-production"}},"1.0.0":{"name":"@444leod/lint","version":"1.0.0","description":"Unified linting for Next.js + Elysia + TanStack Query + Drizzle monorepos","license":"MIT","type":"module","main":"./dist/index.mjs","types":"./dist/index.d.mts","bin":{"444lint":"dist/cli.mjs"},"exports":{"./eslint":{"import":"./dist/index.mjs","types":"./dist/index.d.mts"},"./biome.json":"./biome.json","./.oxlintrc.json":"./.oxlintrc.json","./react-doctor.config.json":"./react-doctor.config.json"},"scripts":{"build":"tsdown","dev":"tsdown --watch","lint":"bun src/cli.ts --no-score --profile eslint-plugin --profile test-fixture","pack:check":"bun scripts/verify-package.ts","prepublishOnly":"bun run verify","test":"vitest run","test:watch":"vitest","typecheck":"tsc --noEmit","verify":"bun run lint && bun run typecheck && bun run test && bun run build && bun run pack:check"},"publishConfig":{"access":"public"},"dependencies":{"@biomejs/biome":"2.5.3","eslint-config-sheriff":"31.4.0","eslint-plugin-react-doctor":"0.7.6","oxlint":"1.73.0","react-doctor":"0.7.6","typescript-eslint":"8.63.0"},"peerDependencies":{"eslint":"^9"},"devDependencies":{"@types/node":"22.20.1","eslint":"9.39.4","tsdown":"0.22.5","typescript":"5.9.3","vitest":"^2.1.9"},"packageManager":"bun@1.3.1","gitHead":"0aa6504c34f81226d1050a60698a6e4402f94137","_id":"@444leod/lint@1.0.0","_nodeVersion":"22.19.0","_npmVersion":"11.14.1","dist":{"integrity":"sha512-mMkKI7J2YXYvNg6YF6SE4BaJJmZr8qY0LeRmzgxL1X0x2gU4XKOOhwSgUmklWHOaLyylEVsV+qYbpw5Q5KKLlQ==","shasum":"9883e218b3a7cb734012beff066d32e37929880f","tarball":"https://registry.npmjs.org/@444leod/lint/-/lint-1.0.0.tgz","fileCount":10,"unpackedSize":48265,"signatures":[{"keyid":"SHA256:DhQ8wR5APBvFHLF/+Tc+AYvPOdTpcIDqOhxsBHRwC7U","sig":"MEYCIQCsuBDiUMEjannZRth5Jnx3/5mSdyWRyFs+i4D+YFleWwIhANfN0YmebOz6JypoQJK0xso2C/YeMe/KxaDivUgqYPTB"}]},"_npmUser":{"name":"444leod","email":"perso.leo.dumont@gmail.com"},"directories":{},"maintainers":[{"name":"444leod","email":"perso.leo.dumont@gmail.com"}],"_npmOperationalInternal":{"host":"s3://npm-registry-packages-npm-production","tmp":"tmp/lint_1.0.0_1783964165651_0.6880869594174321"},"_hasShrinkwrap":false}},"time":{"created":"2026-05-17T07:09:12.306Z","modified":"2026-07-13T17:36:05.922Z","0.1.0":"2026-05-17T07:09:12.632Z","0.1.1":"2026-05-17T07:18:15.532Z","0.1.2":"2026-05-17T07:24:38.712Z","0.1.3":"2026-05-17T07:28:18.431Z","0.2.0":"2026-07-12T17:47:44.299Z","0.3.0":"2026-07-12T20:25:39.844Z","0.4.0":"2026-07-12T21:33:18.763Z","0.5.0":"2026-07-12T22:40:44.905Z","1.0.0":"2026-07-13T17:36:05.805Z"},"license":"MIT","description":"Unified linting for Next.js + Elysia + TanStack Query + Drizzle monorepos","maintainers":[{"name":"444leod","email":"perso.leo.dumont@gmail.com"}],"readme":"# @444leod/lint\n\nUnified linting for **Next.js + Elysia + TanStack Query + Drizzle** monorepo projects.\n\nOne dependency. Four tools: **Biome** (formatting), **Oxlint** (fast bug detection), **ESLint** (custom architectural rules + Sheriff baseline), **React Doctor** (React health scoring).\n\n## Installation\n\n```bash\nbun add -D @444leod/lint\n```\n\n## Quick Start\n\nOne dependency, two scripts, **no config files**. The bundled `444lint` CLI runs Biome, Oxlint, and ESLint against this package's own configs, auto-detecting your stack from `package.json`:\n\n```json\n{\n  \"scripts\": {\n    \"lint\": \"444lint\",\n    \"lint:fix\": \"444lint --fix\"\n  }\n}\n```\n\n```bash\nbun run lint             # biome + oxlint + eslint + React Doctor (offline)\nbun run lint --fix       # auto-fix what can be fixed\nbun run lint --score     # add React Doctor's networked 0–100 health score\nbun run lint --no-score  # skip the React Doctor phase entirely\nbun run lint --help      # usage + all flags\n```\n\n**React Doctor runs fully offline by default** — it reports every local finding but makes **no network calls** (its hosted 0–100 score and the Socket.dev supply-chain scan are both skipped). Pass `--score` to opt into the networked health score when you want the number; pass `--no-score` to skip React Doctor altogether.\n\n> **Privacy note:** even with `--score`, React Doctor never uploads your source code or file paths — it sends only which rule ids fired plus framework/version/dependency metadata (and, in a git repo, the repo name + commit SHA). The default offline mode sends nothing.\n\n### Auto-detection\n\n`444lint` reads your `package.json` dependencies and enables the matching rule sets — you don't configure anything:\n\n| Dependency | Enables |\n|------------|---------|\n| `next` | Next.js rules (ESLint + React Doctor `next`) |\n| `react` / `react-dom` | React rules |\n| `@tanstack/react-query` | React Doctor `tanstack-query` rules |\n| `@tanstack/react-start` | React Doctor `tanstack-start` rules |\n| `vitest`, `jest`, `@playwright/test`, `storybook`, `lodash`, `remeda`, `astro` | matching Sheriff presets |\n\n### Editor integration (optional)\n\nThe CLI needs no local files, but editor extensions (format-on-save, inline squiggles) look for config in your project root. If you want that, add these tiny stubs:\n\n`eslint.config.js`\n```js\nimport { createConfig } from \"@444leod/lint/eslint\";\n\nexport default createConfig({ next: true, react: true, tanstackQuery: true });\n```\n\n`biome.json`\n```json\n{\n  \"$schema\": \"https://biomejs.dev/schemas/2.5.3/schema.json\",\n  \"extends\": [\"@444leod/lint/biome.json\"]\n}\n```\n\n`.oxlintrc.json`\n```json\n{ \"extends\": [\"@444leod/lint/.oxlintrc.json\"] }\n```\n\n## Architecture\n\n| Tool | Role | Speed |\n|------|------|-------|\n| **Biome** | Formatting and basic JS/TS/React linting | ~20x ESLint |\n| **Oxlint** | Fast bug detection — TS, React, import rules | ~100x ESLint |\n| **ESLint** | Sheriff baseline + 11 custom architectural guardrail rules | Baseline |\n| **React Doctor** | React health score (0-100) + React-specific diagnostics | Fast scan |\n\n## Engineering baseline\n\nThe package enforces only rules with deterministic implementations and tests.\nSee [docs/engineering-rules-baseline.md](docs/engineering-rules-baseline.md)\nfor the boundary between lint rules, CI invariants, repository architecture,\nand human workflow guidance.\n\nFormatting can be overridden by a project-level `biome.json` or `biome.jsonc`\nthat extends this package. Local overrides must not weaken correctness,\nsecurity, or architecture rules.\n\n## Profiles\n\nNew repositories should declare their conformance profiles explicitly. Profiles\ncompose with the existing ecosystem flags, and an explicit legacy flag keeps\npriority over a profile default.\n\n```typescript\nexport default createConfig({\n  profiles: [\"next\", \"test-fixture\"],\n  tanstackQuery: true,\n});\n```\n\nAvailable profiles are `library`, `react`, `next`, `elysia`, `bun-worker`,\n`eslint-plugin`, and `test-fixture`.\n\n## Factory API\n\n```typescript\nimport { createConfig } from \"@444leod/lint/eslint\";\n\nexport default createConfig({\n  // Ecosystem flags\n  next: true,\n  react: true,\n\n  // React Doctor ESLint rule sets, layered by stack.\n  // `recommended` is always included; `next` follows the `next` flag above.\n  tanstackQuery: true,\n  tanstackStart: false,\n\n  // Override any rule severity\n  rules: {\n    \"no-raw-fetch\": \"warn\",\n    \"thin-controller-db-call\": \"off\",\n  },\n\n  // Custom file patterns\n  patterns: {\n    serverRoutes: \"src/server/routes/**/*.ts\",\n    webApp: \"src/web/**/*.{ts,tsx}\",\n    apiHooks: \"**/hooks/api/**/*.ts\",\n    components: \"**/components/**/*.{ts,tsx}\",\n    envPackage: \"**/packages/env/**\",\n  },\n\n  // Extra ignores\n  ignores: [\"**/vendor/**\", \"**/generated/**\"],\n\n  // Sheriff options\n  sheriff: {\n    jest: false,\n    vitest: true,\n    playwright: false,\n    storybook: false,\n    lodash: false,\n    remeda: false,\n    astro: false,\n  },\n});\n```\n\n## React Doctor\n\nReact Doctor diagnoses React code for security, performance, correctness, accessibility, bundle-size, architecture, and design issues. It plugs in two ways, both wired here:\n\n| Path | Package | Role | Config |\n|------|---------|------|--------|\n| **ESLint plugin** | `eslint-plugin-react-doctor` | Inline enforcement — `react-doctor/*` rules in your normal `eslint .` run | `eslint.config.js` (the factory) |\n| **CLI scan** | `react-doctor` (pinned dependency) | Full scan + **0–100 health score** | `react-doctor.config.json` in your project root (optional) |\n\nThe ESLint side is driven by stack flags on `createConfig`: `recommended` is always on, `next` layers Next.js rules when `next: true`, and `tanstackQuery` / `tanstackStart` add the matching TanStack rule sets. Override any React Doctor rule through the same top-level `rules` field, e.g. `\"react-doctor/query-no-query-in-effect\": \"error\"`.\n\nThe CLI side runs a **pinned** `react-doctor` (not `@latest`) so the score is reproducible. react-doctor auto-discovers a `react-doctor.config.json` by walking up from the scanned directory — it does **not** read this package's bundled config automatically. To tune `failOn`/ignore globs, drop a `react-doctor.config.json` in your project root; you can start from this package's default, exported at `@444leod/lint/react-doctor.config.json`. Run it in CI to track the health score over time.\n\n## Custom ESLint Rules\n\n### Server Rules\n\n| Rule | Severity | Detects |\n|------|----------|---------|\n| `thin-controller-db-call` | error | `db.select()` etc. inside Elysia route handlers |\n| `require-http-error-factory` | error | `throw forbidden()`, `throw new Error()`, `set.status = N` |\n| `no-response-constructor` | error | `return new Response()` |\n| `no-return-in-transaction` | error | `return <value>` inside `db.transaction()` |\n| `no-hardcoded-sort-order-zero` | warn | `sortOrder: 0` in `.values()` inserts |\n| `no-process-env` | error | Direct `process.env.*` access |\n| `no-silent-catch` | error | Empty `catch {}` blocks |\n\n### Client Rules\n\n| Rule | Severity | Detects |\n|------|----------|---------|\n| `no-eden-in-components` | error | `eden.*()` calls inside React components |\n| `enforce-suspense-query` | error | `useQuery()` without `enabled` or `refetchInterval` |\n| `no-use-effect-data-sync` | error | `fetch()`, `eden.*()`, `setState()` at top level of `useEffect` |\n| `no-raw-fetch` | error | Raw `fetch()` calls in web app code |\n\n## Development\n\n```bash\n# Install\nbun install\n\n# Build\nbun run build\n\n# Build with watch\nbun run dev\n```\n\n## Release\n\n`@444leod/lint` is public on npm. A release is allowed only when `bun run\nverify` passes locally and in CI.\n\n1. Review behavior and SemVer impact.\n2. Update version and changelog/release notes.\n3. Run `bun install --frozen-lockfile` and `bun run verify`.\n4. Inspect `npm pack --dry-run --json` output.\n5. Confirm the consumer fixture imports `@444leod/lint/eslint`.\n6. Publish manually with the existing npm account and 2FA policy.\n7. Verify `npm view @444leod/lint version dist-tags --json`.\n\nThe package does not claim that a rule is reliable unless the rule has valid,\ninvalid, path-scope, and regression tests. Application migrations compare old\nand new diagnostics before deleting local configuration.\n\n### From 0.5.x\n\nExisting `createConfig` flags remain supported. New repositories should declare\n`profiles` explicitly. The `test-fixture` profile permits `process.env` only in\ntest/spec files and `tests/` directories. No existing repository should remove\nits local config until old and new lint outputs have been compared.\n\n## License\n\nMIT\n","readmeFilename":"README.md"}