Skip to content

Delete the dead tooling and stop CI repeating itself - #502

Merged
Zaldaryon merged 19 commits into
devfrom
chore/491-tooling-cleanup
Sep 15, 2026
Merged

Zaldaryon merged 19 commits into
devfrom
chore/491-tooling-cleanup

Conversation

@Pixnop

@Pixnop Pixnop commented Sep 15, 2026

Copy link
Copy Markdown
Contributor

What changes

Batch 1, pure deletions

  • Delete scripts/measure-windows-runtime.ps1 and benchmark:win, drop the @electron-toolkit/preload devDependency, drop the mac extendInfo boilerplate, rename docs/notes/notifications-audit.md (147 lines removed, net)
  • Rename fixed one code comment the issue's own audit missed: src/domain/notifications/failureReason.ts still pointed at the old notes path

Batch 2, mechanical folds

  • build-inno-fixtures.ts's hand-rolled CRC-32 → node:zlib (16 lines removed)
  • renderer-dom/setup.ts's unreachable localStorage polyfill deleted (26 lines removed)
  • electron-builder-locales.test.ts and electron-builder-keyring-deps.test.ts share one listUnder in tests/config/ymlBlock.ts (net 0 lines, one implementation instead of two)
  • tests/i18n/helpers.ts and action-label-locales.test.ts's hand-rolled recursive readdirs → the one-liner security-boundaries.test.ts already used (15 lines removed)
  • copy-tone-locales.test.ts's redundant seven-key describe deleted, its second flattener replaced by the shared flattenTranslationObject (44 lines removed)

Batch 3, the two #490 bugs (moved before the refactors that touch the same files)

  • startInstall stops telling players a failed installer is a "damaged archive": new notifications.body.installed/installError keys in all 14 locales, wording pointed at the log
  • useLaunchGame gains the see-report notification action MainMenu's old PlayHandler had and the hook dropped; MainMenu converted to call the hook, PlayHandler and its 183-line local copy of the backup-prompt machinery deleted

Batch 4, renderer shells (headless screenshots before merging, see below)

  • InstalledTagsFilter/InstalledModsSelectFilter, the last two hand-rolled dropdown triggers, moved onto MENU_TRIGGER_STYLES/MENU_OPTION_STYLES
  • Buttons.tsx/FormComponents/FormButtons.tsx collapsed onto one shared Button/ButtonLink body; NormalButton, LinkButton, FormButton, FormLinkButton become presets with identical public prop types
  • SideFilter/InstalledFilter folded onto one generic components/ui/SelectMenu.tsx (LanguagesMenu/ConfigPage's UIScale left as their own copies, no DOM test to check the change by hand, per the issue's own "stays out" list)
  • TagsFilter/VersionsFilter folded onto one generic components/ui/MultiSelectFilter.tsx (the "#" tag prefix kept as a hashPrefix flag)
  • TaskManagerContext's four task runners folded onto one runTask scaffold plus four thin wrappers; TaskContextType's four-signature public surface untouched

Batch 5

  • The six ManageMods render harnesses share one mountManageMods primitive (tests/renderer-dom/helpers/mountManageMods.tsx); each file's own fixture defaults and route stay local

CI fold

  • sonarcloud now depends on test-matrix and reads its ubuntu leg's uploaded coverage artifact instead of running test:coverage a second time
  • build/build-macos call a new build:unpack:no-typecheck script instead of build:unpack, since the standalone typecheck job already gates the same commit

Docs

  • docs/architecture.md: stripped all 17 stale :NN-NN citations and 7 stale line counts, kept the paths; rewrote the CI paragraph from the post-fold ci.yml (it previously described 5 jobs, missed test-matrix entirely, and cited a line for lint:ci's wiring that pointed at a setup-node block)

What does not change

Every fold's commit carries a diffed before/after test run: same test files, same test count, same test names, in the fold's own commit message. Two independent proofs beyond the test suite:

  • The CRC-32 fold: compared over 200 random buffers plus the empty buffer against node:zlib, zero mismatches; regenerating every fixture under tests/fixtures/inno/ produced byte-identical .bin files (verified via md5sum diff before deleting the old implementation).
  • The two readdir folds: both old walkers benchmarked byte-identical, sorted, against the replacement on the real tree (168 .ts/.tsx files, 87 .tsx).

The renderer shell folds (Batch 4) were checked live, headless, against a seeded config with a real Installation and Mods folder, screenshots under pr-assets/contrast-pass/mods-pass/ (491-*.png):

  • 491-home.png: Home page, Play button and the quick-action icons through the collapsed Button/ButtonLink
  • 491-mods-browse.png, 491-mods-sidefilter-open.png, 491-mods-tagsfilter-open.png: the Mods browse filter bar, SelectMenu (Side filter) and MultiSelectFilter (Tags, with its "#" prefix) opened
  • 491-managemods-actionbar.png, 491-managemods-filters-open.png: Manage Mods' action bar and its Author filter (InstalledModsSelectFilter) on MENU_TRIGGER_STYLES
  • 491-install-inprogress.png, 491-activitycenter.png: a real ModDB download-and-extract run through the folded runTask, completing with the correct toast text and Activity Center entry

I did not click Join on a saved server or Play in the live check (both launch the real game process); useLaunchGame's see-report action is covered instead by the new, red-then-green test in manageInstallationServers.test.tsx, and launchPlayGame.test.tsx (717 lines, unchanged) still passes running through the hook instead of the deleted PlayHandler.

Bugs fixed on the way (#490)

Two real bugs, named in #490, moved before the refactors that touch the same files rather than waiting behind them:

  1. startInstall was copied from startExtract and never reworded: a failed Windows installer told the player to check that "the archive is not damaged," which cannot be true of an installer. Fixed with new locale keys, added to all 14 locales in the same commit.
  2. MainMenu's PlayHandler and the extracted useLaunchGame had drifted: Play offered a "see the session report" action after a crash, Join (through the hook) did not. Ported into the hook first, proven with a test written red against the current hook and green after, before converting MainMenu to use the hook.

This PR does not close #490 itself; the filter-props consolidation, folder-picker sharing and useExternalLinks items there are left to that issue's own pass.

Testing

  • Gate: npm run typecheck (0 errors), npm run lint:ci (0 errors, 14 pre-existing warnings), npm run format:check (clean), npm run test:coverage (234 files, 4423 tests, 2 pre-existing skips; statements 94.55%, branches 91.18%, functions 95.37%, lines 96.21%, all above the ratchet floors).
  • CI minutes: the sonarcloud job's own npm run test:coverage measured at 237s on run 34959134901; folded onto test-matrix's ubuntu leg via an uploaded artifact, so that run no longer happens a second time. build:unpack:no-typecheck drops the ~24s standalone typecheck from both build legs and, on a workflow_dispatch run, from build-macos at its 10x multiplier. Combined estimate carried over from the issue: roughly 5 of the run's ~29 billed minutes on a normal push/PR, closer to a third whenever build-macos fires. This PR's own push to chore/491-tooling-cleanup is the live measurement of the folded workflow (act is not installed; the YAML was validated with python3 -c "import yaml; yaml.safe_load(...)" and read carefully before pushing).
  • The mac entitlementsInherit/notarize stanza is left as an open question in a comment rather than fixed silently: build/entitlements.mac.plist has never existed in git history, and dropping the two keys would be a codesigning-intent call, not a debt cleanup.

Left out

  • LanguagesMenu and ConfigPage's UIScale Listbox conversions, and the folder-picker triple: no DOM test covers either, and the issue's own "stays out" list defers them to a maintainer who can check the result by hand.
  • The no-restricted-imports/exhaustive-deps ESLint allowlist: left alone deliberately, trimming it blind risks the exact stale-closure bugs the rule was turned on to catch.
  • useExternalLinks' mods wrapper (Fold the repeated renderer shells into one component each #489/One launch path, one filter object, one task runner #490): rated worth "low" in both issues, 7 lines, the aliasing problem it targets does not exist.
  • Branch protection's required-check list needs a maintainer's re-check after this PR: sonarcloud now depends on test-matrix succeeding first (a solo re-run of test-matrix will not automatically refresh a sonarcloud run that already finished), and build/build-macos no longer typecheck, so typecheck staying a required check matters more than it did.

Closes #491. Part of #492.

scripts/measure-windows-runtime.ps1 is reachable only through
benchmark:win, which nothing in CI, docs, the PR template or
CONTRIBUTING mentions, and its default $AppPath points at the
pre-rename "VS Launcher.exe" that electron-builder stopped producing.
Delete the script and the npm script with it; the two remaining
mentions (a comment in electron-builder.yml and the exclusion-line
assertion in electron-builder-icon-files.test.ts) are untouched.

@electron-toolkit/preload has zero imports anywhere in src, tests or
scripts; drop the devDependency and regenerate the lockfile.

electron-builder.yml's mac stanza loses the four NSCamera/NSMicrophone/
NSDocuments/NSDownloads extendInfo lines: boilerplate for a launcher
that never touches a camera, mic, or those folders. entitlementsInherit
and notarize: false are left in place with a comment flagging them for
a maintainer's call rather than a silent fix: build/entitlements.mac.plist
has never existed in git history, build-macos in CI only runs
build:unpack (--dir, unsigned, entitlements never consulted), and
build:mac is the only script that would hit the missing file, which
nobody runs from CI.

Rename docs/notes/notifications-audit.md to
docs/notes/archive/notifications-audit-2026-08.md, content unchanged.
One code comment in src/domain/notifications/failureReason.ts did
reference the old path (missed by the issue's own audit) and is
updated to match.
tests/fixtures/build-inno-fixtures.ts hand-rolled a 256-entry reflected
CRC-32 table and function that its sibling build-fixtures.ts, in the
same directory, already gets from node:zlib. This builder is not under
the purity constraint that justifies the hand-rolled CRC-32 in
src/domain/inno/crc32.ts (that layer stays pure; this one already
imports node:crypto, node:fs and node:child_process).

Verified before deleting the local implementation: compared over 200
random buffers plus the empty buffer, zero mismatches against
node:zlib's crc32, and regenerating every fixture under
tests/fixtures/inno/ produces byte-identical .bin files to the
committed ones (md5sum diff empty). tests/domain/inno/ stays at 5
files, 105 tests, same names, before and after.
Under vitest's default jsdom url (http://localhost:3000, never
overridden in this repo's environmentOptions), jsdom always exposes a
real localStorage, so the "if (!window.localStorage)" branch building a
25-line Map-backed Storage shim was never entered. On an opaque origin
jsdom's own getter throws SecurityError on the property read inside the
if, before the branch is even evaluated, so the shim could not install
itself there either.

The three window.localStorage.removeItem calls in beforeEach keep
running unchanged, against jsdom's own implementation. Before and after:
tests/renderer-dom/ stays at 82 files, 805 tests, same names.
…config tests

electron-builder-locales.test.ts's inline block extractor and
electron-builder-keyring-deps.test.ts's listUnder(section, key) are the
same regex-split-and-collect loop, one reading a top-level key and one
reading a key nested inside a section. Move listUnder to
tests/config/ymlBlock.ts, taking the yml text and an empty section
string for a top-level key, and have both tests call it. The "read as
text, js-yaml is only transitive" comment now lives once, on the shared
file, instead of once per test file.

Both test files pass unchanged: 3 tests in electron-builder-locales,
4 in electron-builder-keyring-deps, same names, before and after.
… used next door

tests/i18n/helpers.ts's listSourceFiles (readdirSync plus statSync) and
tests/action-label-locales.test.ts's tsxFiles (withFileTypes plus
flatMap) both walk a directory tree by hand for the same purpose that
tests/security-boundaries.test.ts already gets from
readdirSync(dir, { recursive: true, encoding: "utf8" }). Replace both
with that call, filtered by extension and re-joined onto dir since the
recursive form returns paths relative to it. action-label-locales.test.ts
now imports listSourceFiles from tests/i18n/helpers.ts instead of
keeping tsxFiles.

Benchmarked against both existing walkers on the real tree before
deleting either: listSourceFiles's 168 .ts/.tsx files and tsxFiles's 87
.tsx files come back byte-identical, sorted, from the new one-liner.
tests/action-label-locales.test.ts, tests/i18n/ and
tests/security-boundaries.test.ts stay at 3 files, 54 tests, same
names, before and after.
The first describe asserted seven named en-US keys carry no exclamation
mark; the second walks every string value in en-US.json with an empty
allowlist and asserts the same thing, so the seven were a strict subset
and a regression in any of them already failed the second block first
(#446, closing #411, whose own body says the second commit "went past
those seven and swept the other 40 en-US strings").

Delete the first describe and its KEYS list, and import
flattenTranslationObject from tests/i18n/helpers.ts instead of keeping
a second flattener (collectStringPaths): verified identical over the
real en-US.json, 898 string values from both. Moved the #411 reference
onto the surviving describe so the seven keys keep their trail.

Test count goes from 906 to 899, all 899 the same assertions as
before (the surviving describe's own 899, unchanged); only the
duplicate seven are gone. The "does a renamed key still exist" case is
still covered: tests/i18n/i18n-parity.test.ts already asserts, codebase
wide, that every statically referenced key exists in en-US.json.
TaskManagerContext.tsx's startInstall was copied from startExtract and
kept its locale keys: on failure it raised notifications.body.extractError
("Couldn't unpack {{name}}. Check that the archive is not damaged and
that there is room on the drive."), which is wrong advice for an
installer that timed out, was missing, or is not-windows, exactly the
InstallerRunResult reasons this catch classifies.

Add notifications.body.installed/installError to all 14 locale files
(i18n-parity.test.ts's fr-FR parity check and the Activity Center
namespace check both gate a partial add) and point startInstall at
them. The failure sentence points at the log rather than the archive,
since the specific reason already rides along on the notification's
`reason` option to the Activity Center row.

tests/renderer-dom/taskManagerStartInstall.test.tsx gets two new tests
pinning the installer's own wording; both fail red against the
unfixed hook (asserting the body doesn't mention "unpack" or "archive")
and pass green after. taskManagerFlows.test.tsx and the rest of
tests/i18n/ stay green unchanged.
MainMenu's PlayHandler and useLaunchGame drifted apart after the hook
was extracted (#460): PlayHandler builds a see-report notification
action navigating to /installations/report/:id off
pickPlayOutcomeNotification's report field, useLaunchGame drops that
field on the floor. A crash after joining a saved server therefore
offered no report link, while the same crash after Play did.

Added a failing test first: manageInstallationServers.test.tsx now
renders a WhereProbe alongside the page (mirroring launchPlayGame.test.tsx's
own probe) and asserts Join surfaces the same see-report action and
navigates to the same route Play does. Confirmed red against the
current hook (no such button exists), then ported the report-action
block from PlayHandler into useLaunchGame's outcome-notification
handling, gaining useNavigate. launchPlayGame.test.tsx stays green
unchanged: MainMenu's own copy is untouched by this commit.
MainMenu still carried its own PlayHandler (106-208), skipBackupPrompt
state, askToLaunchWithoutBackup, the teardown effect, and an inline
copy of LaunchBackupPrompt, comment for comment, even though
useLaunchGame was extracted from that exact function to give Join the
same launch path (#460). The previous commit ported the one place they
had drifted (the see-report action) into the hook, so this conversion
carries no behaviour change of its own.

MainMenu now calls useLaunchGame() for launchGame/skipBackupPromptOpen/
answerSkipBackupPrompt and renders the shared LaunchBackupPrompt
component instead of its own copy. Dropped with PlayHandler: the
gameVersions/configDispatch/os/openExternalLink/goTo locals and the
getInstallationVersionStatus/pickPlayOutcomeNotification/logLaunch/
runGame/preventAppClose imports it alone used; checkInstallationPathExists
and useMakeInstallationBackup stay, still used by the quick-backup
button.

launchPlayGame.test.tsx stays green unchanged: same 23 tests, same
names, now exercising the hook through MainMenu instead of the deleted
local copy. The whole renderer-dom suite: 82 files, 808 tests (805 plus
the 3 added across the previous two commits).
…R_STYLES

InstalledTagsFilter and InstalledModsSelectFilter were the last two
Listbox triggers still hand-rolling their border/background/shadow
classes; every other dropdown in the renderer (SideFilter,
InstalledFilter, OrderFilter, AuthorFilter, TagsFilter, VersionsFilter,
LanguagesMenu, ConfigPage, InstallationsDropdownMenu, and others)
already shares MENU_TRIGGER_STYLES/MENU_OPTION_STYLES from
components/ui/buttonStyles.ts. Moved both onto the shared styles,
keeping each option row's own text sizing (moved onto the inner <p>,
which is where every other migrated dropdown already carries it) and
InstalledTagsFilter's "#" prefix and checkmark. The outer dropdown
panel wrapper (border, background, shadow) stays local, same as it
does on every other filter already using these constants.

tests/renderer-dom/manageMods*.test.tsx (6 files, 138 tests) and
text-contrast.test.ts stay green.
…ne shared body each

Buttons.tsx and FormButtons.tsx carried two near-identical HeadlessUI
Button wrappers and two near-identical Link wrappers, differing only in
default variant (ghost vs secondary), whether overflow-hidden is forced
on, and FormButton's extra ariaExpanded prop and stricter
submit-vs-onClick typing. Factored the shared rendering into Button and
ButtonLink in Buttons.tsx; NormalButton, LinkButton, FormButton and
FormLinkButton become thin presets over them, each keeping its own
exact public prop type (including FormButton's FormButtonAction union
and FormLinkButton's lack of an ariaLabel prop, which the previous
FormLinkButton also never exposed) so no call site's type surface
changes.

The one detail that had to move rather than merge: LinkButton always
sets aria-label to `ariaLabel ?? title`; FormLinkButton has never set
aria-label at all. That default now lives in each preset rather than
in the shared ButtonLink, so FormLinkButton keeps omitting the
attribute exactly as before instead of gaining one.

All four exported names, and every one of their ~400 call sites, are
unchanged. The whole test suite (234 files, 4423 tests, 2 pre-existing
skips) passes unchanged, actionBusyState.test.tsx included; lint:ci
stays at 0 errors, 14 pre-existing warnings.
Both were the same single-select Listbox scaffold with one fixed
option list swapped for another: same trigger, same animated panel,
same zebra-striped MENU_OPTION_STYLES rows, already sharing
animateVariants.ts's DROPDOWN_MENU_WRAPPER_VARIANTS. Moved the shared
shell into components/ui/SelectMenu.tsx (generic over a string union),
leaving each file as its own translated option list plus a one-line
call.

LanguagesMenu and ConfigPage's UIScale are left as their own hand-rolled
copies for now: neither has DOM test coverage, and the issue's own
"stays out" list defers that pair to a maintainer who can check the
result by hand.

tests/renderer-dom/listModsFilterBar.test.tsx and five other Mods
browse test files (6 files, 51 tests) pass unchanged, same names,
before and after.
Both were the same multi-select Listbox scaffold: a chip-filled
trigger, an animated panel with a lookup-failed row, a checkmark on
each selected option, already sharing DROPDOWN_MENU_WRAPPER_VARIANTS
and MENU_OPTION_STYLES. The one real visual difference is Tags'
"#category" hash prefix on both the trigger chips and the option rows,
which Versions never had; kept as a `hashPrefix` flag rather than
forcing one look on both.

Moved the shared shell into components/ui/MultiSelectFilter.tsx,
generic over anything with a tagid/name pair (both
DownloadableModTagType and DownloadableModGameVersionType already have
that shape). Each preset keeps its own lookup hook
(useTagsLookup / useGameVersionsLookup) and placeholder text.

Same six Mods browse test files (51 tests) pass unchanged, same names,
before and after; lint:ci stays at 0 errors, 14 pre-existing warnings.
The MultiSelectFilter fold moved TagsFilter's and VersionsFilter's
"nothing picked yet" placeholder styling (tagsFilter.length < 1 / ...)
into the new shared components/ui/MultiSelectFilter.tsx as
selected.length < 1, so text-contrast.test.ts's pinned source anchors
for those two rows stopped matching (the class did not change, only
which file it lives in). Repointed both anchors at the shared file;
the contrast floor being checked is unchanged. Caught by running the
full suite after the previous commit rather than only the files that
looked affected -- the lesson for the rest of this pass is to run it
before every commit, not just the ones a fold's own tests suggest.
startDownload, startExtract, startInstall and startCompress were the
same scaffold with one line changed: generate an id, prevent-close,
log and dispatch the pending task, run the host call, dispatch
completion plus an optional toast, or on a throw classify the failure,
dispatch it failed, and show an optional error toast, then release the
prevent-close token either way.

Factored that into runTask, which takes the task's type (download,
extract, install or compress, doubling as the log/notification key
root), an optional noun override for the three whose prevent-close and
"adding" wording is not just the type word (extraction, installation,
compression), and an `operation(tag)` closure holding everything
actually specific to one task: its own running/done log line, the host
call, and any post-processing that has to run before the task counts
as done (startExtract's awaited chmod, startInstall's ok-check with the
reason folded into the thrown message). Those per-task comments
recording past bugs stay on the wrappers, where the code they explain
now lives.

TaskContextType's four-signature public surface is untouched.
startDownload's onFinish is still the three-argument contract
(status, path, error) the other three don't share:  matching it here
would have forced every runner through the widest shape, so each
wrapper turns runTask's `{ ok, result }` / `{ ok: false, error }`
outcome into whatever its own onFinish expects instead. startOptimumPatch
is unrelated (a different onFinish shape entirely) and untouched.

One deliberate wording simplification, not a behaviour change: startCompress's
"Adding compression of [PATH] to [PATH]." debug log line becomes
"Adding compression to [PATH].", the same wording the other three
already used for their own single path. Nothing reads this text; it is
not covered by any test, and log-provenance.test.ts (which does govern
what a log line may interpolate) stays green.

Net line count grew slightly (167 to about 196) against the issue's
own estimate of a reduction, because every institutional comment and
the exact notification/log text stayed put; what actually shrank is
the duplication: four near-identical try/catch/dispatch bodies down to
one. tests/renderer-dom/taskManagerFlows.test.tsx,
taskManagerStartInstall.test.tsx and log-provenance.test.ts (3 files,
44 tests) pass unchanged, same names, before and after; full suite 234
files, 4423 tests, 2 pre-existing skips; lint:ci 0 errors, 14
pre-existing warnings.
manageMods.test.tsx, manageModsHealth.test.tsx, manageModsDetails.test.tsx,
manageModsServerMods.test.tsx, manageModsUnreadableArchive.test.tsx and
manageModsMissingInstallation.test.tsx each built the identical
<Routes><Route path="/installations/mods/:id" element={<TaskProvider>
<ManageMods /><NotificationsOverlay /></TaskProvider>} /></Routes> at
the same route through renderWithProviders. Moved that block into
mountManageMods (tests/renderer-dom/helpers), taking an optional route
override for manageModsMissingInstallation's "/installations/mods/missing".

Each file's own fixture defaults (its installMockWindowApi calls),
route override where it has one, and return type stay local: the
netManager/modsManager mocks differ substantially per file (a full
ModDB simulation, a DETAILS-only stub, an empty listing, a mocked
bridge to hand back), which is exactly why only the mount moved and
not the surrounding renderManageMods wrapper.

Same six files, 138 tests, same names, before and after. Full suite:
234 files, 4423 tests, 2 pre-existing skips; lint:ci 0 errors, 14
pre-existing warnings; format:check clean.
sonarcloud reran npm run test:coverage standalone (measured 237s) after
its own npm ci, duplicating test-matrix (ubuntu-latest)'s identical
step. test-matrix now uploads its ubuntu leg's coverage/ as an
artifact (coverage-ubuntu, 1-day retention: sonarcloud is the only
consumer and runs in the same workflow run); sonarcloud gets
needs: [test-matrix] and downloads that artifact instead of
regenerating it. This means sonarcloud only runs once every test-matrix
leg has succeeded, and only within the run that produced the artifact:
a solo re-run of test-matrix produces fresh coverage this job will not
automatically pick back up, noted in a comment on the job so whoever
re-runs test-matrix alone knows to re-run sonarcloud too.

build:unpack runs npm run build (typecheck && electron-vite build),
redoing the standalone typecheck job's work (24s) on both build legs
and, when triggered, on build-macos at its 10x multiplier. Added
build:unpack:no-typecheck (electron-vite build && electron-builder
--dir, no typecheck) and pointed the build and build-macos jobs at it;
build:unpack itself is untouched, so a local unpacked build still gets
the typecheck safety net by default. Updated the one comment in
electron-builder.yml that named build:unpack for what build-macos
actually runs now.

Combined, roughly 5 of the run's ~29 billed minutes on ubuntu-latest,
closer to a third whenever build-macos fires. Validated the workflow
with python3 yaml.safe_load and confirmed tests/config/
electron-binary-download-skip.test.ts's job-name parsing still finds
typecheck/lint/test/build unchanged (it parses "  name:$"-shaped lines,
which the new comments do not match).

Flagging rather than fixing: dropping typecheck from build:unpack:no-typecheck
means a type error can only be caught by the standalone typecheck job now,
not by build itself, so branch protection's required-check list needs a
maintainer's re-check to confirm typecheck (not just build and test)
stays required, including on workflow_dispatch runs where a required
check might not gate the same way.
17 path:NN-NN citations and 7 raw line counts had all drifted against
origin/dev: ListMods.tsx cited at 301 lines is well past that today,
ports.ts at 321 is 383, lzma.ts at 670 is 687, extract.ts at 345 is
374, preload/index.ts at 107 is 125, and so on. A line number survives
no edit to the file it points at; the path it sits on does. Stripped
every :NN-NN suffix and raw line count, keeping the path and the
reasoning; the "pages around 250 lines" section now names the pages
that have grown past the soft ceiling without pinning a count to any
of them, and says to check the file itself instead.

The CI paragraph was the one part actually wrong rather than merely
stale: it described five job definitions when the workflow (before or
after the CI fold) defines seven, never mentioned test-matrix, called
build-macos "a sixth", and cited ci.yml:23-33 for where lint:ci is
wired in, which points at a setup-node block. Rewritten from the
post-fold ci.yml: all seven jobs named, what test exists for and why,
and sonarcloud's new needs: [test-matrix] plus artifact read, and the
build/build-macos jobs' build:unpack:no-typecheck.

Left alone: a separate, pre-existing inaccuracy this pass did not
touch (the closing "Issue #31 and #24, both cited on this page" no
longer matches the page, which now only cites #8) is out of scope here
and flagged separately.
@Pixnop
Pixnop requested a review from Zaldaryon September 15, 2026 19:17
@Pixnop
Pixnop force-pushed the chore/491-tooling-cleanup branch from 43bd3fc to d16202b Compare September 15, 2026 20:58
@Pixnop
Pixnop marked this pull request as draft September 15, 2026 20:59
@Pixnop
Pixnop marked this pull request as ready for review September 15, 2026 21:00

@Zaldaryon Zaldaryon left a comment

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Reviewed the current head. The tooling cleanup removes unused project pieces and consolidates the renderer filter controls without leaving unresolved references. The required checks pass in the Node 22 CI environment, including typecheck, lint, the Ubuntu and Windows test matrix, build, SonarCloud, and the gate test. Approving.

@Zaldaryon
Zaldaryon merged commit 031b075 into dev Sep 15, 2026
9 checks passed
@Zaldaryon
Zaldaryon deleted the chore/491-tooling-cleanup branch September 15, 2026 22:31
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.

2 participants