Modernize tooling: npm, vitest, TypeScript 6, Node 22+, ESLint flat config - #16
Merged
Merged
Conversation
…onfig - Switch package manager from yarn to npm (remove yarn.lock, add package-lock.json, update CI to npm ci) - Migrate the full test suite off jest onto vitest: new root vitest.config.ts covers unit/integration/e2e, jest.fn/mock/MockedClass/ MockedFunction usages converted to vitest's vi equivalents, jest/ts-jest/ @types/jest removed - Bump TypeScript to ^6.0.3 (not 7.x - that hard-crashes typescript-eslint 8.x today) and @types/node to ^22.9.4; fix the ~180 stricter compile errors this surfaced without changing runtime behavior, including a few genuine latent bugs found along the way (a copy-paste index bug in parser/encoding.ts, an unguarded socket access race in connection.ts, an uninitialized FlagList.hasWildcard) - Raise the Node engines floor to >=22 (18/20 are both past EOL and vitest 4.x/ESLint 10 require >=20 anyway); update CI's Node matrix to 22.x/24.x - Migrate ESLint to flat config (eslint.config.js) with ESLint 10 + the unified typescript-eslint 8 package, replacing .eslintrc.js/.eslintignore; preserve the old warn-level severity for no-explicit-any/no-unused-vars since the v8 recommended config promotes them to errors by default - Delete the dead pre-TypeScript test/test.js + test-connection-*.js files (they called a since-removed default Imap export); the specific historical-bug scenarios they encoded are written up in docs/superpowers/specs/2026-07-12-legacy-regression-scenarios-to-reverify.md for re-verification once FETCH/IDLE are (re)implemented - Add prettier as a real, runnable devDependency (config already existed but the package was never installed); wire the compliance suite into CI (it existed but was never run there); fix vitest's reportOnFailure default so coverage still gets reported when a test fails, matching jest's old behavior
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
yarn.lock, addpackage-lock.json, update CI tonpm ci)vitest.config.tscovers unit/integration/e2e,jest.fn/jest.mock/jest.MockedClass/jest.MockedFunctionusages converted to vitest'sviequivalents,jest/ts-jest/@types/jestremoved^6.0.3(not 7.x — that hard-crashes typescript-eslint 8.x today, confirmed empirically) and@types/nodeto^22.9.4; fix the ~180 stricter compile errors this surfaced without changing runtime behavior>=22(18 and 20 are both past EOL, and vitest 4.x/ESLint 10 require Node ≥20 anyway); update CI's Node matrix to 22.x/24.xeslint.config.js) with ESLint 10 + the unifiedtypescript-eslint8 package, replacing.eslintrc.js/.eslintignore; preserve the old warn-level severity forno-explicit-any/no-unused-varssince the v8 recommended config promotes them to errors by defaulttest/test.js+test-connection-*.jsfiles (they called a since-removed defaultImapexport); the specific historical-bug scenarios they encoded are written up indocs/superpowers/specs/2026-07-12-legacy-regression-scenarios-to-reverify.mdfor re-verification once FETCH/IDLE are (re)implementedprettieras a real, runnable devDependency (config already existed but the package was never installed); wire the compliance suite into CI (it existed but was never run there); fix vitest'sreportOnFailuredefault so coverage still gets reported when a test fails, matching jest's old behaviorReal bugs found and fixed along the way
parser/encoding.ts(seq[j]instead ofrpl[j])connection.tsaround close/endFlagList.hasWildcardwas never initializeduseDefineForClassFieldslandmine the TS target bump would otherwise have caused: every lexer token's.typeproperty would have silently goneundefined(fixed by removing redundant field re-declarations)Flagged, not fixed
parser.ts:parseTokens()returnsnullfor malformed input, which flows intothis.push(null)— normally Node's signal to end a stream. Types now correctly reflect this reality; whether that's the intended behavior is unclear and left as-is.ThreadMessage.get children()(inparser/structure/thread.ts) returnsthis.childreninstead ofthis._children— infinite recursion if ever called. Not a compile error, so untouched, just flagged.no-useless-escapein the regex-heavy parser code) — predate this work and were never enforced in CI before, so lint is non-blocking (continue-on-error) rather than failing every future PR on unrelated backlog.Test plan
npm run buildnpm run typechecknpm run typecheck:compliancenpm test(231/232 — the 1 failure is the same pre-existing one already documented as expected)npm run test:compliance(800 failed/431 passed — byte-identical to the pre-modernization baseline)npm run lint(non-blocking; pre-existing debt only)Generated by Claude Code