chore(deps): dependency sweep, security fix, and Dependabot grouping - #52
Merged
Conversation
Move the transitive brace-expansion that eslint pulls in through minimatch off 5.0.7, which carries GHSA-mh99-v99m-4gvg (high): a crafted brace pattern expands without bound and crashes the process out of memory. Patched in 5.0.8. minimatch 10.2.5 already declares ^5.0.5, so this is an in-range resolution refresh and needs no manifest change. The pending eslint 10.8.0 bump does not fix this on its own. eslint 10.8.0 still resolves @eslint/config-array 0.23.5 and minimatch 10.2.5, so a plain install would keep the vulnerable resolution. - brace-expansion 5.0.7 -> 5.0.9 (transitive, via eslint and minimatch) Dev-only path, no runtime exposure. Verified locally: pnpm audit reports no known vulnerabilities, and build, lint, typecheck, and test all pass.
react-dom asserts exact version equality with react at module load and throws rather than warning, and the guard is compiled into the development client build that jsdom loads as well as every server build. react-dom 19.2.7 declares a peer of ^19.2.7, which 19.2.8 satisfies, so pnpm reports no peer problem while the runtime contract is broken. Dependabot #48 proposed react alone and its lockfile pins react-dom@19.2.7(react@19.2.8), so merging it would have failed the jsdom tests and broken SSR. The @types packages move along because @types/react-dom peers on @types/react. packages/ui keeps its react and react-dom peerDependencies at ^19.0.0. That range states what the package supports, not what it was last built against, and narrowing it would falsely drop 19.0 and 19.1. - react 19.2.7 -> 19.2.8 (apps/web, packages/ui) - react-dom 19.2.7 -> 19.2.8 (apps/web, packages/ui) - @types/react 19.2.17 -> 19.2.18 (apps/web, packages/ui) - @types/react-dom 19.2.3 -> 19.2.4 (apps/web, packages/ui) Supersedes Dependabot #48. Verified locally: the lockfile carries no 19.2.7 reference, and build, lint, typecheck, and test all pass.
Radix component packages share internal packages (react-primitive, react-slot, react-context, react-presence, roving-focus, and others), so bumping one in isolation forks those internals to two versions each. That is what #49 did on its own: it took react-tabs to 1.1.19 and left 12 shared internals at two versions apiece, including two copies of react-slot while packages/ui imports Slot directly in button.tsx. Moving the whole set to latest collapses every one of them back to a single version, which is why this commit removes more lockfile lines than it adds. - @radix-ui/react-avatar 1.2.2 -> 1.2.6 (packages/ui) - @radix-ui/react-dialog 1.1.19 -> 1.1.23 (packages/ui) - @radix-ui/react-dropdown-menu 2.1.20 -> 2.1.24 (packages/ui) - @radix-ui/react-label 2.1.11 -> 2.1.15 (packages/ui) - @radix-ui/react-slot 1.3.0 -> 1.3.3 (packages/ui) - @radix-ui/react-tabs 1.1.19 -> 1.1.21 (packages/ui) - lucide-react 1.25.0 -> 1.28.0 (packages/ui) Verified locally: every shared Radix internal resolves to a single version, and build, lint, typecheck, and test all pass.
All patch or minor, all inside the existing ranges. The eslint bump also raises the tooling/eslint-plugin devDependency, but its peerDependency stays at ^10.6.0: that range states the supported floor, which has not moved, and the rules use only the stable Rule and RuleTester APIs. Dependabot #47 narrowed it to ^10.8.0, which would have dropped support the plugin still has. - eslint 10.6.0 -> 10.8.0 (root, tooling/eslint-plugin) - typescript-eslint 8.63.0 -> 8.65.0 (root) - turbo 2.10.4 -> 2.10.8 (root) - @playwright/test 1.53.2 -> 1.62.1 (root) - vite 8.1.5 -> 8.2.0 (apps/web) - @vitejs/plugin-react 6.0.3 -> 6.0.5 (apps/web) - tsx 4.23.0 -> 4.23.4 (apps/api, packages/db) - @types/node 26.1.1 -> 26.1.2 (apps/api, packages/config, packages/db, tooling/eslint-plugin) - @types/pg 8.20.0 -> 8.20.3 (packages/db) - hono 4.12.30 -> 4.12.33 (apps/api) - @hono/node-server 2.0.10 -> 2.0.12 (apps/api) Supersedes Dependabot #47, #50, and #51. Holds back @testing-library/jest-dom 7.0.0 (major) and the @tanstack/react-start and react-router bumps, which need individually verified changes. Verified locally: routeTree.gen.ts does not drift, and build, lint, typecheck, and test all pass.
The stock config opened one PR per package, which produced two structurally broken proposals: a react bump with no react-dom (they assert exact version equality at runtime), and a single Radix component bump that would have forked 15 shared internal packages. Grouping the packages that must move together makes both defects impossible to generate. The default open-pull-requests-limit of 5 also hid the backlog: 27 packages were outdated while only 5 were visible. Raising it to 10 surfaces the rest. Production dependencies outside the three groups keep arriving individually, as does every major, so each still gets its own review. Verified: the config parses and the catch-all dev-tooling group sorts last, which matters because a dependency joins the first group it matches.
This was referenced Aug 2, 2026
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.
Clears the open high-severity advisory, brings every patch/minor dependency current, and fixes the Dependabot config that was generating structurally broken update PRs. Supersedes #47, #48, #50, and #51, and repairs the lockfile damage from the already-merged #49.
Five commits, each independently verified, so any one can be reverted without taking the others.
What this changes
b9f7dd0security, lockfile only.brace-expansion 5.0.7 -> 5.0.9, transitive througheslint > @eslint/config-array > minimatch. GHSA-mh99-v99m-4gvg, high: a crafted brace pattern expands without bound and crashes the process out of memory. Dev-only path, no runtime exposure. Kept separate so a revert of any bump below cannot silently take the security fix with it.583135creact and react-dom to 19.2.8 in lockstep, plus@types/react 19.2.18and@types/react-dom 19.2.4.packages/uikeeps its peer range at^19.0.0.0d2e0b8the Radix set plus lucide. All six@radix-ui/*packages move together (react-tabsto 1.1.21), pluslucide-react 1.28.0. Net effect on the lockfile is a deletion of 260 lines, because collapsing duplicate internals outweighs the version bumps.c6d89c4dev tooling and API runtime. eslint 10.8.0, typescript-eslint 8.65.0, turbo 2.10.8, @playwright/test 1.62.1, vite 8.2.0, @vitejs/plugin-react 6.0.5, tsx 4.23.4, @types/node 26.1.2, @types/pg 8.20.3, hono 4.12.33, @hono/node-server 2.0.12.tooling/eslint-pluginkeeps its eslint peer range at^10.6.0.ab404e0Dependabot grouping. Groups react with react-dom and their types, groups@radix-ui/*, groups@tanstack/*, and groups remaining dev tooling for minor/patch only. Raisesopen-pull-requests-limitto 10.Why not just merge the five PRs
Three of them were defective, and the defects came from the config rather than from bad luck.
#48 (react alone) would have failed
pnpm test. Its lockfile pinsreact-dom@19.2.7(react@19.2.8).react-domasserts exact version equality withreactat module load and throws rather than warning, and the guard is compiled into the development client build that jsdom loads as well as every server build. Becausereact-dom@19.2.7declares a peer of^19.2.7, which19.2.8satisfies, pnpm reports no peer problem while the runtime contract is broken.#49 (react-tabs alone) forked the shared Radix internals. Merging it left 12 internal packages at two versions each on
main, including two copies of@radix-ui/react-slot(1.3.0 and 1.3.1) whilepackages/ui/src/components/button.tsximportsSlotdirectly. Nothing in the four gates detects this.0d2e0b8collapses them back to one version each. The other risk on that PR did not land: it was two commits behind and its lockfile predated the Tailwind v4 work, but git's text merge preserved all 50tailwindcssentries.#47 (eslint) did not actually fix the advisory the way a hand-applied bump would. eslint 10.8.0 still resolves
@eslint/config-array 0.23.5andminimatch 10.2.5, andminimatchdeclaresbrace-expansion: ^5.0.5, so editing the manifest and runningpnpm installkeeps the vulnerable 5.0.7 locked. Dependabot's lockfile only moved because it regenerates from scratch. Hence the explicitpnpm updateinb9f7dd0.Separately, the default
open-pull-requests-limitof 5 was hiding the backlog: 27 packages were outdated while only 5 were visible.Verification
pnpm audit: no known vulnerabilities.TURBO_FORCE=true, andpnpm test:e2epasses.pnpm install --frozen-lockfile, so no commit carries a lockfile out of sync with its manifests.react@19.2.7references remain in the lockfile, andreact-dom@19.2.8(react@19.2.8)is matched.(ssr) connected, with noIncompatible React versionserror. This is the exact path chore(deps): bump react from 19.2.7 to 19.2.8 #48 would have broken.apps/web/src/routeTree.gen.tsdoes not drift.Held back
Majors and the SSR framework, each of which deserves its own verified change:
@testing-library/jest-dom 7.0.0,typescript 7.0.2,jsdom 30.0.1, and the@tanstack/react-startandreact-routerbumps.Note for whoever merges
Merging this closes #47, #48, #50, and #51 automatically. Do not merge #48 directly in the meantime; it would reintroduce the react/react-dom skew.
The
@playwright/testbump needs newer browser binaries, so runpnpm exec playwright install chromiumafter pulling orpnpm test:e2efails with a missing executable.