Repository navigation
Description
Summary
Enable ESLint in CI. This was originally part of #135 and was split out after four CR
rounds showed that most findings were edges of this one change — it alters lint resolution for
every package, for editors, for per-package invocation, and for apps/web's separate Next
config. It needs to land where those effects are the only thing under review.
Why it is not already on
CI's required check is named "Lint, Typecheck & Test" but runs only build, typecheck and
test. #135 adds a comment making that gap explicit rather than silently misleading, but does
not close it.
The blocker: ESLint 9 defaults to flat config, this repo uses .eslintrc.cjs, and the
ESLINT_USE_FLAT_CONFIG=false opt-out does not survive turbo's env sanitization.
Work, in the order it was validated during the split
eslint.config.cjstranslating the current rules viaFlatCompat(@eslint/eslintrc
is already installed, but must be declared — it and@eslint/jsare otherwise phantom
deps resolving only through pnpm's hoisting of eslint's transitives).- Exclude
apps/web(ignores: ['apps/web/**']). It keeps its own.eslintrc.cjswith
the Next and react-hooks plugins and is linted bynext lint. Without the exclusion, the
root flat config shadows it andnpx eslintthere fails with
Definition for rule 'react-hooks/exhaustive-deps' was not found. - Add
root: truetoapps/web/.eslintrc.cjs. The root eslintrc currently provides it;
once that file is deleted, web's config cascades past the repo into the developer's
~/.eslintrc*and lint results vary by machine. - Fix the 4 errors this surfaces — three empty-interface and one
no-explicit-any, all
already fixed in chore: secret hygiene, deployment doc corrections, and typing fixes #135 — plusapps/worker's lint script, currently
echo 'no eslint config for worker yet', which exempts the service that owns the
SHADOW_MODEpost-back gate. turbo.json: declare the config as aglobalDependenciescache input (in chore: secret hygiene, deployment doc corrections, and typing fixes #135), so a
rule change does not serve a cached pass.- Add the CI Lint step and confirm the required check finally does what its name says.
Decisions worth making deliberately
- Warnings are unbounded. ~48 exist repo-wide (
no-unused-vars,
consistent-type-imports, plusreact-hooks/exhaustive-depsandno-img-elementin web).
Adding--max-warnings 0means clearing them first; without it the gate blocks on errors
only. Either is defensible — decide, and say which in the PR. no-unused-varssets onlyargsIgnorePattern: '^_', so the repo's own_-prefix
convention still warns on variables (_transformed,_ticket). AddingvarsIgnorePattern
andcaughtErrorswould remove several warnings for free.- Coverage gaps to name explicitly:
scripts/*.tsand the rootvitest.config.tssit
outside every workspace package soturbo run lintnever reaches them (0 errors, 4 warnings
when linted directly);apps/docshas no lint script at all;
apps/discord-mcp/test/server.test.tsand the per-packagevitest.config.tsfiles are
linted by nothing.
Verification the split proved necessary
Comparing problem counts in one package is not sufficient — that is what let the
apps/web rule-shadowing through. Verify every affected scope: a package using the root
config, apps/web (both bare eslint and next lint), a per-package invocation from inside
the package directory, and an editor/LSP run.
Acceptance criteria
-
pnpm lintpasses from the repo root with no environment variable set -
cd apps/<any> && pnpm lintpasses standalone -
apps/webkeeps its Next + react-hooks rules undernext lint, and bareeslintthere
does not error - Lint runs in CI and the required check name matches what it does
-
apps/workeris no longer exempt
Split out of #135.
Activity
style(ai): format the eval module with prettier
ci: run eslint and a format check on every pull request
style(ai): format the eval module with prettier
ci: run eslint and a format check on every pull request
ci: run eslint and a format check on every pull request