Skip to content

chore: declare eslint + typescript-eslint as root devDependencies#7

Merged
iaj6 merged 1 commit into
mainfrom
chore/eslint-root-devdeps
Jun 4, 2026
Merged

chore: declare eslint + typescript-eslint as root devDependencies#7
iaj6 merged 1 commit into
mainfrom
chore/eslint-root-devdeps

Conversation

@iaj6

@iaj6 iaj6 commented Jun 4, 2026

Copy link
Copy Markdown
Owner

Summary

Closes the deferred follow-up from #5: the shared eslint.config.base.mjs (used by core/db/cli/sdk) imported typescript-eslint only through npm-workspace hoisting — it was a transitive dep of the web package's eslint-config-next. That worked, but if web's lint toolchain ever changed, npm run lint would break with Cannot find module typescript-eslint. This declares the toolchain explicitly.

Changes

  • Root devDependencies: eslint@^9 + typescript-eslint@^8 — removes the implicit coupling to web. Updated the base-config comment accordingly.
  • overrides: eslint-plugin-react-hooks pinned to 7.0.1. eslint-config-next requests ^7.0.0, and a fresh lock resolves 7.1.x, whose stricter React-Compiler rules flag ~12 pre-existing components (EventLog, ApiTokensSection, AuditSection, CommandPalette, …). Pinning keeps lint behavior identical so this PR stays focused. (Upgrading the plugin + fixing those 12 is a separate, PR5-sized follow-up.)
  • package-lock.json regenerated via npm install --include=optional --force, per the repo's macOS→Linux optional-deps rule.

Verification (the lock-regen gates)

  • All 29 Linux-only optional deps preserved in the lock (@rollup/rollup-linux-*, @emnapi/*, …) — the exact thing the rule guards against.
  • npm ci succeeds against the fresh lock (no Missing … from lock file).
  • npm run lint = 0 errors across all packages (react-hooks pin held).
  • Build clean; 1166 tests pass.

The large package-lock.json diff is the expected result of a full regeneration; the meaningful change is 3 lines in package.json + the config comment.

🤖 Generated with Claude Code

Previously the shared eslint.config.base.mjs (used by core/db/cli/sdk)
imported `typescript-eslint` only via npm-workspace hoisting — it was a
transitive dependency of the web package's eslint-config-next. That worked
but was fragile: removing web's lint toolchain would break `npm run lint`
with "Cannot find module typescript-eslint". Declaring them at the root
removes that implicit coupling.

- Add `eslint`/`typescript-eslint` to root devDependencies and update the
  base-config comment.
- Pin `eslint-plugin-react-hooks` to 7.0.1 via overrides: eslint-config-next
  requests ^7.0.0, and a fresh lock resolves 7.1.x, whose stricter React
  Compiler rules flag ~12 pre-existing components. Keeping the lint behavior
  identical here keeps this change focused; upgrading the plugin and fixing
  those is a separate follow-up.
- Regenerated package-lock.json with `npm install --include=optional --force`
  per the project's macOS->Linux rule; verified the 29 Linux-only optional
  deps (@rollup/rollup-linux-*, @emnapi/*) survived and `npm ci` succeeds.

Build clean; lint 0 errors across all packages; 1166 tests pass.

Co-Authored-By: Claude Opus 4.8 (1M context) <[email protected]>
@iaj6 iaj6 merged commit 21ba977 into main Jun 4, 2026
3 checks passed
@iaj6 iaj6 deleted the chore/eslint-root-devdeps branch June 4, 2026 23:33
iaj6 added a commit that referenced this pull request Jun 5, 2026
…d smells (#8)

Bumps the override from 7.0.1 (pinned in PR #7 to dodge the new rules) to
7.1.1, which activates the React Compiler lint rules (purity,
set-state-in-effect, refs, immutability), and resolves the 12 violations
they surface. Kept as an explicit pin: this plugin adds CI-gating rules in
minor releases (eslint-config-next only requests ^7.0.0), so deliberate
bumps avoid surprise breakage.

Real fixes (behavior-preserving):
- useEventSource: write onEvent into the ref from an effect, not during
  render (refs rule). Only async SSE handlers read it, after commit.
- useSessions: hoist the markUpdated useCallback above its first use
  (immutability rule) — declaration-order only.
- ApiTokens/Users settings sections: move the mount fetch into a
  cancellable async IIFE so setState lands after the await
  (set-state-in-effect), keeping the try/finally so a rejected fetch can't
  strand the loading spinner.
- EventLog: read the clock from an interval-refreshed `now` state instead
  of during render (purity). Strictly less churny than the prior
  per-render Date.now(); the time-window cutoff lags <=30s.

Scoped, justified eslint-disables for genuine false positives: terminating
derived-state resets (setPage(0), setSelectedIndex(0)) and intentional
point-in-time pause snapshots in EventLog.

Verification: web lint 0/0, full build green, 1166 tests pass, clean
npm ci. An adversarial 4-lens review caught the stranded-spinner error
path, now fixed.

Co-authored-by: Claude Opus 4.8 (1M context) <[email protected]>
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant