SIGN IN SIGN UP

chore: replace eslint with oxlint (#4756)

* chore: replace eslint+prettier with oxlint+oxfmt

Swap ESLint + 10 related plugins for oxlint, and Prettier for oxfmt.
Lint rules from eslint.config.mjs are mapped in .oxlintrc.json; unmappable
rules (import/no-extraneous-dependencies, valid-expect-in-promise) and the
vitest/jest plugin conflict are documented inline.

- Delete eslint.config.mjs, add .oxlintrc.json with TS-only no-empty/no-var
- Rename .prettierignore -> .oxfmtignore
- Update lint/format scripts in package.json
- Split lint-staged into ts/js (lint+fmt) and json/yml/md (fmt only)
- Add indent_size = 2 to .editorconfig for json/yml/md/svg

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>

* chore: format codebase with oxfmt

Mechanical reformat across 183 files. No behavior changes.

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>

* chore: guard against focused tests in pre-commit and CI

oxlint's vitest plugin does not include a no-focused-tests rule, so a stray
it.only / describe.only could silently disable the rest of a test file
after the eslint -> oxlint migration. Adds a small script that scans test
files for *.only(...) and wires it into both lint-staged (per-file on
commit) and the CI codeQuality job (full sweep, can't be skipped with
--no-verify).

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>

* chore: address PR review feedback on oxlint migration

- pkg-check.js: split broken console.warn(...).process.exit(0) chain into
  two statements. The bug pre-dates this PR (oxfmt only collapsed the
  multi-line form to one line) and the branch is dead code on modern Node,
  but the call would have thrown if ever reached.
- .oxlintrc.json: update stale ">=v18" engines comment to ">=22.12.0",
  matching the current package.json after v21.0.0.
- check-no-focused-tests.js: scan whole-file rather than line-by-line so
  multi-line forms (`it\n  .only(...)`) are caught, and stop the regex at
  a token boundary so chained variants like `it.only.each(...)` match.

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>

* test: assert specific error messages on toThrow

Promote vitest/require-to-throw-message from default (warn) to error and
fix the three call sites that were warning. Bare .toThrow() can pass on
the wrong error type/message; asserting the expected message makes the
tests fail loudly when the thrown error changes.

- Question.test.ts: assert "Question: name is required"
- load.test.ts: assert /Cannot find module/ from resolve-extends

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>

---------

Co-authored-by: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
E
escapedcat committed
6099ae50aa71fe7f99d75af1b8d9537aa7685747
Parent: a6e9108
Committed by GitHub <noreply@github.com> on 5/12/2026, 9:14:29 AM