Skip to content

chore(deps): eslint 10 — the new hooks rules count, and the count is visible - #451

Merged
github-actions[bot] merged 1 commit into
mainfrom
chore/fleet-currency
Aug 31, 2026
Merged

chore(deps): eslint 10 — the new hooks rules count, and the count is visible#451
github-actions[bot] merged 1 commit into
mainfrom
chore/fleet-currency

Conversation

@catomean

Copy link
Copy Markdown
Collaborator

Fleet currency arc, Wave 1 (final piece). eslint ^9 → ^10.

  • eslint-config-next's plugin-react version: 'detect' calls the removed context.getFilename and crashes ESLint 10 — pinned settings.react.version AFTER the next configs (order matters; a pin before them was overridden in a sibling repo).
  • The compiler-era hooks rules flag 35 long-standing call sites across ten control components — real findings, but effect/ref restructuring is a refactor, not a deps bump. Downgraded to warn so every lint run prints the count; the downgrade block says to delete itself when the burn-down PR lands.
  • Confirms the audit's node-version: description oddity is a false positive (a workflow_call input's description key, matched across lines by the harvest regex).

lint 0 errors / 40 warnings · tsc clean · 124/124 unit test files.

🤖 Generated with Claude Code

https://claude.ai/code/session_01WqKqMnHQHSmkGFfc5t7Rxn

…visible

Fleet currency arc, Wave 1 (final piece). eslint ^9 -> ^10.

Two things ESLint 10 surfaces, handled where each belongs:
- eslint-config-next's eslint-plugin-react ships version 'detect', which
  calls the removed context.getFilename and crashes the run. Pinned
  settings.react.version, AFTER the next configs — a pin placed before them
  was overridden by their 'detect' in a sibling repo.
- The compiler-era hooks rules (set-state-in-effect, refs, purity,
  immutability, preserve-manual-memoization) flag 35 long-standing call
  sites across ten control components. Real findings, but restructuring
  effects and ref discipline is a functional refactor, not a dependency
  bump — downgraded to warn so every lint run prints the count, with a
  note to delete the downgrades once the burn-down PR lands.

Also confirms the harvest's 'node-version: description' oddity is a false
positive: selfhost-deploy.yml declares node-version as a workflow_call
input whose next line is its description key.

lint 0 errors / 40 warnings; tsc clean; 124/124 unit test files.

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01WqKqMnHQHSmkGFfc5t7Rxn
@github-actions
github-actions Bot merged commit 9974129 into main Aug 31, 2026
3 checks passed
@github-actions
github-actions Bot deleted the chore/fleet-currency branch August 31, 2026 15:28
github-actions Bot pushed a commit that referenced this pull request Sep 1, 2026
…rules bind as errors (#459)

PR #451 downgraded five react-hooks rules to "warn" with a note to delete
the block once the call sites were fixed. This is that burn-down: all 35
findings restructured, the downgrade block deleted, so
set-state-in-effect / refs / purity / immutability /
preserve-manual-memoization now bind at error severity (verified by
mutation probe: a violating file fails lint with exit 1).

By class:

set-state-in-effect (25) — three recipes, chosen per call site:
- Prop/URL→state mirror effects became guarded render-time adjustments
  (React's "adjusting state when props change" pattern): ProjectAutopilotToggle,
  ZellijLivePanel, LiveUrlField, ProjectWorkspaceHeader (x2), ProjectCard
  (capacity re-arm + agent-running transition), ControlPanel (selection
  reconciliation), CommandPalette (open-reset), LokiWorkspace (?q= prefill,
  selection seed, transcript switch), use-auto-continue, use-poll,
  use-project-card-actions. Same commit semantics, one paint earlier.
- Async loaders called from mount effects were split into pure fetch cores
  whose every setState lives in a promise callback (.then/.catch/.finally),
  with thin event-context wrappers that prime spinners for buttons/timers:
  ActivityTimeline, PeekTabDrawer (fetchRemotePeek now returns content
  instead of applying it), PeopleBookPanel, LokiWorkspace reloads,
  use-control-data (fetchControl core + refresh wrapper).
- Values readable at first render moved into useState lazy initializers:
  CommandPalette recents (sessionStorage), BillingSettings ?billing= notice.
  MermaidDiagram's matchMedia mirror became a useSyncExternalStore
  subscription. LogConversationButton clears results in the input's
  onChange (the actual event) instead of the debounce effect.

refs (6):
- ProjectOperationsView's frozen row order moved from a ref mutated inside
  useMemo to state adjusted during render behind the same setKey guard.
- queue-list/queue-item-row: editRef existed only to focus the edit
  textarea after open; the textarea mounts with autoFocus instead and the
  ref plumbing is deleted.
- TerminalView's fontOverrideRef is now mirrored via an effect (declared
  before the mount effect so declaration-order seeding still precedes the
  first read), matching the file's existing onLive/onGeometry pattern.

purity (1):
- ProjectCard no longer calls Date.now() in render; it receives nowS from
  ControlPanel's per-render clock via buildCardProps, so the card's
  staleness math now uses the same clock as the snapshots it renders.

immutability (1):
- BillingSettings navigates to Stripe Checkout via window.location.assign()
  (method call) instead of assigning location.href.

preserve-manual-memoization (2):
- TerminalSurface.switchAgent and AskLokiButton.ask captured whole context
  objects while declaring narrowed deps; the needed field (tabDir /
  workspaceKey) is now a local, making the manual deps match what the
  compiler infers.

Two targeted eslint-disable-next-line react-hooks/set-state-in-effect
remain, each with an inline justification: ProjectCard's auto-reroute
automation (once-per-capacity-episode loop guard around a live
agent-switching path) and ControlPanel's ?focus= deep-link handler (App
Router param changes only surface as re-renders; splitting it would
resolve the target twice against possibly-different data). Two unused
directives (ready-banner, ShellWorkspace) were removed.

Verified: npm run lint (0 errors; 3 pre-existing @next/next location
warnings untouched), npx tsc --noEmit, npm run test:unit 124/124.


Claude-Session: https://claude.ai/code/session_01WqKqMnHQHSmkGFfc5t7Rxn

Co-authored-by: Mao Nakamoto <41178744+maonakamoto@users.noreply.github.com>
Co-authored-by: Claude Fable 5 <noreply@anthropic.com>
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