build: replace ESLint with type-aware Oxlint - #79
Draft
SBoudrias wants to merge 12 commits into
Draft
Conversation
- Remove eslint, eslint-config-xo, typescript-eslint, eslint-config-prettier - Add oxlint + oxlint-tsgolint with typeAware enabled and all rule categories at error severity; churn-heavy rules documented as off - Bump typescript to ^7.0.2 and yarn to 4.18.0 (TS7 compat patch fix) - Update pretest, nano-staged, CI lint step and dependabot groups - Type-check spec files from the root tsconfig - Core fixes: mem-fs Store (accessibility, param reassignment, promise chains), editor state.ts return types, typed state.spec.ts fixture Co-Authored-By: Oz <oz-agent@warp.dev>
- Replace file.contents?.toString() with a contentsString() helper that narrows contents to Buffer first (typescript/no-base-to-string) - Narrow vinyl stat access to file.stat?.isDirectory() (typescript/no-unnecessary-condition) - Use string describe titles distinct from imported function names (vitest/valid-title, vitest/prefer-describe-function-title) - Replace named node:path import with default import (unicorn/import-style) - Use import.meta.dirname instead of __dirname (unicorn/prefer-module) - Replace files[index]! with a checked local and index++ with index += 1 (typescript/no-non-null-assertion, eslint/no-plusplus) - Type stream data handlers as (file: File) instead of implicit any (typescript/no-unsafe-member-access) - Type the change listener mock as vi.fn<(path: string) => void>() (vitest/require-mock-type-parameters, typescript/strict-void-return) - Name the async generator and use a ternary yield (eslint/func-names, unicorn/prefer-ternary) - Replace (store as any).store with an internalStoreMap() helper using a documented, disabled narrowing assertion into the store internals (typescript/no-unsafe-*) - Drop now-unneeded eslint-disable comments Co-Authored-By: Oz <oz-agent@warp.dev>
Add explicit return types to exported actions, make nullable boolean checks explicit, replace param reassignment with locals, merge duplicate imports, name default-exported functions, reorder helpers before use, convert transform.ts to async/await, and scope two justified oxlint disables (Transform callback API, compat-mode EJS options assertion). Co-Authored-By: Oz <oz-agent@warp.dev>
- Merge duplicate-path import handling per unicorn/import-style (default-only node:path imports) - Replace for-loop over describes with describe.each (vitest/prefer-each) and extract the copyTpl-only test into its own describe (vitest/no-conditional-tests) - Use template-literal titles (vitest/valid-title) and typed vi.fn()/hoisted mocks (vitest/require-mock-type-parameters) - Type tinyglobby mocks through non-deprecated glob/globSync signatures (typescript/no-deprecated); string-form vi.mock with a documented prefer-import-in-mock suppression - Replace narrowing 'as' casts on readJSON results with whole-object toEqual assertions (typescript/no-unsafe-type-assertion) - Type JSON.stringify replacer params as unknown (typescript/no-unsafe-return) - Store spies in typed MockInstance locals (typescript/unbound-method) and use chai assert for the beforeEach invariant (vitest/no-standalone-expect) - Name async generator filters (eslint/func-names), use += 1 and a for loop (eslint/no-plusplus), and convert eslint-disable comments to oxlint form - Add explicit types to fixtures.ts; suppress its type-aware no-unsafe-* rules with a documented block disable (file is outside every tsconfig include, so type-aware linting resolves imports to error types) - Fix latent tsc errors: index-signature property access via brackets (TS4111), undefined-safe random tmpdir segment, and per-branch typed fileTransform mocks instead of union-call mismatches (TS2322) - Add expect.hasAssertions() where assertions run inside the fileTransform callback (vitest/expect-expect) Co-Authored-By: Oz <oz-agent@warp.dev>
- resolveGlobOptions: branch-neutral explicit boolean comparisons - transform/read-json: v8-ignore hints on defensive non-Error fallbacks - include packages/*/test/**/*.ts in root tsconfig so type-aware linting covers shared test helpers (drops the fixtures.ts suppression block) Co-Authored-By: Oz <oz-agent@warp.dev>
Co-Authored-By: Oz <oz-agent@warp.dev>
Drops the contentsString() helper — no stringification is needed at all, which also keeps no-base-to-string satisfied without narrowing casts. Co-Authored-By: Oz <oz-agent@warp.dev>
FileTransform is now PipelineTransform<AsyncIterable<StoreFile>, StoreFile>, so pipeline() accepts the store stream and user transforms without any. Co-Authored-By: Oz <oz-agent@warp.dev>
SBoudrias
force-pushed
the
replace-eslint-oxlint
branch
from
August 17, 2026 21:16
8046222 to
018c129
Compare
Co-Authored-By: Oz <oz-agent@warp.dev>
Compare Buffer contents directly instead of stringifying. Co-Authored-By: Oz <oz-agent@warp.dev>
Allow that one loose-equality form in oxlint. Keep strict ===/!== when null is a vinyl contents sentinel. Co-Authored-By: Oz <oz-agent@warp.dev>
- Remove the beforeEach addSpy length check; the test that needs it already uses toHaveBeenCalledOnce() - Restore the original Transform .then() callback - Drop explicit public member accessibility - Turn off Node callback/bitwise rules that only produced ignore comments Co-Authored-By: Oz <oz-agent@warp.dev>
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.
Summary
Replace the ESLint stack with Oxlint and enable type-aware linting via
oxlint-tsgolint:eslint,eslint-config-xo,typescript-eslint,eslint-config-prettier; addoxlint@^1.78.0+oxlint-tsgolint@^7.0.2001.oxlint.config.ts(TS config, same style asoxfmt.config.ts):options.typeAware: true, pluginstypescript, unicorn, oxc, import, promise, node, vitest, and all seven rule categories aterror(correctness, suspicious, pedantic, perf, style, restriction, nursery) — 545 rules active. Rules that would force codebase-wide rewrites are disabled individually, each with a comment explaining why (e.g.node/no-sync— sync APIs are the library's purpose;unicorn/no-null— vinyl usesnullcontents;typescript/consistent-type-definitions— interfaces are required for the intentional declaration merging in mem-fs-editor).typescript/no-unsafe-*family,strict-boolean-expressions,no-unnecessary-condition,no-floating-promises, etc., which the old config never ran (XO +tseslint.configs.recommendedhad no type information).Toolchain changes
compat/typescriptpatch hard-fails on TS 7's native package layout (ENOENT lib/_tsc.js); the fix shipped in Yarn 4.17.1 (Handle optional compat patch failures for TypeScript 7 yarnpkg/berry#7190).pretest,nano-staged, the CI lint job and dependabot groups now reference oxlint;eslint.config.jsis deleted.**/*.spec.tsandpackages/*/test/**/*.ts, so tests and test helpers are type-checked and get accurate type-aware linting (they were previously invisible to tsc).Code changes (~220 violations resolved)
Store, editor actions,state.ts).strict-boolean-expressions,no-unnecessary-condition,prefer-nullish-coalescing).state.spec.tshad an untypedlet file), JSON assertions use whole-objecttoEqualinstead of member access onany, narrowing casts replaced with typed locals.no-param-reassign/no-shadowcleanups, merged duplicate imports,node:protocol imports, async/await instead of.then()chains inStore.getAsyncand the commit transform.state.spec.tsasserted onfile.clearedState(nonexistent property, alwaysundefined) — it now asserts onstateClearedwith the expected value.Intentional suppressions (documented inline)
Store extends EventEmitter— EventEmitter is the public API (unicorn/prefer-event-target).pipeline()calls in mem-fs keep theiranyassertions behind a block disable — the stream overloads can't express the object-mode generic types.transform.ts(callback-based Node API; rules conflict).Errorfallback branches carry/* v8 ignore */hints to keep the 100% branch-coverage threshold.Validation
yarn oxlint— 0 errors, 0 warnings (545 rules, type-aware)yarn oxfmt --check— cleanyarn tsc— clean (packages + specs)yarn test— 230/230 pass, 100% branch coverage maintainedWorked on with Oz: https://app.warp.dev/conversation/06648078-feae-4605-a4d4-78df45a31302
Co-Authored-By: Oz oz-agent@warp.dev