Strict typing, linting, licensing and a README for newcomers - #2
Merged
Conversation
The typecheck only became meaningful once @types/react was installed, so strict had never actually been exercised. It passes with zero errors — the code was already well typed, nothing was enforcing it. noUnusedLocals surfaced 25 dead imports and variables, plus an effect in ClientPopup that returned a cleanup on only one path. hooks/useAIImage.ts is deleted outright: its last reference was a comment saying it had been removed. Prettier's first pass is folded into this commit rather than split out. It touches nearly every file, so isolating it would produce two large diffs over the same lines instead of one.
Nothing checked for the class of mistake that typechecking cannot see. jsx-a11y runs over the whole tree so the accessibility work is enforced rather than left to review; it immediately caught an unlabelled range input in the settings panel. Pinned to ESLint 9 because eslint-plugin-jsx-a11y does not support 10 yet — preferable to forcing the resolution and hoping. Four React Compiler rules are set to warn, with a comment on each explaining why: they flag real patterns in the game loop — randomness read during render, refs touched during render, state set from effects — and fixing them means restructuring how the simulation ticks. Left visible so the count can only fall. Lint and format now run in CI and in npm run check.
Running the game locally now comes before the design essay, the commands are a table instead of prose, and the three things that break quietly — the Tailwind safelist, the no-CDN rule, the asset budget — get their own section instead of being folklore.
The repository had no license at all, which by default means nobody may reuse any of it — the opposite of what a public showcase is for. Code is MIT: fork it, read it, ship it. The artwork is not, because commissioned art is the part with standing value here; it is CC BY-NC-ND, so it can be shared with credit but not sold, rebundled or shipped inside someone else's product. The boundary is written down rather than implied, since a single LICENSE file at the root would have read as MIT covering everything.
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.
Closes the last items from the production-readiness pass: strict typing, linting,
formatting, licensing, and a README written for someone arriving cold.
Quick path for reviewing this
eslint.config.js— the only file with judgement calls in it. Read the comments.README.md— rendered, not as a diff.LICENSE+ASSETS-LICENSE.md— the code/art boundary.Details
strict@types/reacthad been missing.noUnusedLocalsfound 25 unused imports and variables, plus an effect returning cleanup on only one path.hooks/useAIImage.tsdeleted — its last reference was a comment saying it was removed.eslint-plugin-jsx-a11ydoes not support 10 yet. Forcing the resolution would have been the other option; this seemed better than hoping.jsx-a11yruns over the whole tree, so the accessibility work is enforced instead of reviewed. It immediately caught an unlabelled range input in the settings panel.LICENSEwould have read as MIT covering the artwork too.The one judgement call
Four React Compiler rules are set to warn, not error:
They flag real patterns in the game loop — randomness and timestamps read during
render, refs touched during render, state set from effects. Fixing them means
restructuring how the simulation ticks, which is its own piece of work and not
something to bolt onto a tooling PR.
They are left visible rather than disabled, with the reasoning written in the
config, so the count can only go down. Promote them back to errors once the loop
is reworked.
Verification
npm run checkexits 0 — now six steps: typecheck → lint → format → test → build → budget.ASSETS-LICENSE.mdresolves to a real path.Out of scope
noUncheckedIndexedAccess(85 occurrences) andnoUnusedParameters(35) weremeasured and deliberately left off. Both are worth doing; neither belongs in the
same change as a formatting sweep.