chore: replace Biome with oxlint, oxfmt and Knip - #7
Open
Thomasims wants to merge 4 commits into
Open
Conversation
Swaps @biomejs/biome for the shared @antelopejs/tooling-configs presets:
oxlint (type-aware, via oxlint-tsgolint) for linting, oxfmt for formatting
and Knip for dead-code and dependency analysis. The lint / format scripts
are repointed and a `knip` script is added; CI already runs `pnpm lint`.
tsconfig: tsgolint rejects the `moduleResolution: "node"` (node10) value
TypeScript 7 removed, and it discovers each file's tsconfig itself, so the
field is dropped rather than raised — `module: "commonjs"` is untouched so
the emit stays byte-compatible. `baseUrl` is dropped too and the
self-referencing `paths` entry the conformance suite uses to import
`@antelopejs/interface-redis` is rewritten as a relative path.
No source changes were required beyond the import order oxlint autofixed in
src/tests/index.test.ts. Four `typescript(unbound-method)` warnings on the
chai assertions in that suite are left as-is: warnings are a deliberate
backlog, only errors gate the build.
Knip needs two declarations, both commented in knip.config.ts: the
conformance suite lives in src/tests/ and src/antelope.test.ts rather than
the preset's src/test/ spelling (without the entry the whole shipped suite
plus chai and @types/chai read as dead code), and the `ajs` binary comes
from a globally installed @antelopejs/core rather than a dependency.
Verified: dist/index.js and dist/index.d.ts are byte-identical to those
built from origin/main, the runtime export keys of the `.` subpath match
(GetClient, internal{client,SetClient,UnsetClient}), and the conformance
suite is 14 passing on both origin/main and this branch.
Thomasims
marked this pull request as ready for review
September 7, 2026 16:10
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Replaces
@biomejs/biomewith the shared@antelopejs/tooling-configspresets: oxlint (type-aware, viaoxlint-tsgolint) for linting, oxfmt for formatting, and Knip for dead-code and dependency analysis.Tooling swap
biome.jsondeleted,@biomejs/biomeremoved.oxlint.config.ts,oxfmt.config.ts,knip.config.ts, each extending the shared preset.oxlintis pinned to exactly1.81.0— the JS plugin API is alpha and has to match the versiontooling-configsbuilds against.lint→oxlint,lint:fix→oxlint --fix,format→oxfmt .,format:check→oxfmt --check ., plus a newknip..github/workflows/ci.ymlgainspnpm format:checkandpnpm knipsteps next to the existingpnpm lintandpnpm test, in a separateci:commit.oxfmt.config.tscarries a temporary.github/ISSUE_TEMPLATE/**ignore — those are Markdown templates with a.ymlextension that oxfmt cannot parse. It goes away with tooling-configs#5.tsconfig
Type-aware linting runs tsgolint, which rejects options TypeScript 7 removed and auto-discovers each file's
tsconfig.json(so pointing it at a separate config does not help). Two changes:"moduleResolution": "node"deleted. tsgolint only rejects the explicit removednode10value, so dropping the field satisfies it while the emit stays byte-compatible."module": "commonjs"is deliberately left alone — raising it tonode16makes tsc emit native ESM dynamic imports that bypass the CommonJS resolver detour theajsruntime installs."baseUrl": "."deleted and the self-referencingpathsentry rewritten to the relative./src/index.ts. That mapping is what lets the conformance suite import@antelopejs/interface-redisby its published name; nothing else relied onbaseUrl.pnpm buildsucceeds with no source changes.What the linter forced
Only import order, autofixed by
oxlint --fix:chainow sorts before@antelopejs/interface-redisinsrc/tests/index.test.ts. No cycles, nothing disabled anywhere in the repo.Four
typescript(unbound-method)warnings remain on the chai assertions in that suite (expect(client.set).to.be.a("function")and friends). Warnings across this migration are a deliberate backlog — only errors gate the build — so they are left untouched rather than silenced.What Knip needed
Two declarations, both commented in
knip.config.ts:entryforsrc/tests/**/*.test.tsandsrc/antelope.test.ts. This is an interface package:ajs module testreadsantelopeJs.testto build the test project and runs the compiled suites out ofdist/tests, and that compiled tree ships in the package as the conformance suite the implementing modules run. The preset only knows the singularsrc/test/spelling, so without this entry the whole suite — pluschaiand@types/chai— reads as dead code.ignoreBinaries: ["ajs"]— the CLI comes from@antelopejs/core, which CI installs globally rather than pulling into every package's dependency tree.Nothing was deleted.
pnpm knipexits 0 (the remaining "configuration hints" are preset globs that do not match this repo).Verification
The public surface of a versioned interface must not move, so it was checked against a build from an untouched
origin/mainworktree:package.jsonexportsdeclares.and./package.json. The runtime export keys of.are identical:GetClient, andinternalwith{client, SetClient, UnsetClient}.dist/index.jsanddist/index.d.tsare byte-identical to theorigin/mainbuild. The only differences anywhere indistare the order of tworequire()calls in the compiled test file and the correspondingmappingsshift indist/tests/index.test.js.map, both from the import sort above.origin/main, and 14 passing, 0 failing on this branch.What that suite actually exercises:
ajs module testruns this branch's compileddist/tests/**, but the interface implementation those tests call through resolves to the published@antelopejs/interface-redis@0.0.8inside.antelope/cache/@antelopejs/redis/node_modules, not to this branch'sdist/index.js. Verified by poisoning the localdist/index.jswith a top-levelthrow: the suite still reports 14 passing. So the pass count proves the branch's compiled conformance suite still builds and runs; it does not independently validate the branch'sdist/index.js. That rests on the byte-diff above.pnpm lint,pnpm knipandpnpm format:checkall exit 0.The oxfmt pass is a separate commit recorded in
.git-blame-ignore-revsto keepgit blamereadable. It normalizespackage.jsonkey order and reflows Markdown code blocks inAGENTS.md,CHANGELOG.md,docs/andskills/; no source file changed.