Skip to content

chore(deps): land the dependency upgrade stack on current main - #481

Merged
Shironex merged 6 commits into
mainfrom
chore/deps-backlog
Oct 1, 2026
Merged

Shironex merged 6 commits into
mainfrom
chore/deps-backlog

Conversation

@Shironex

@Shironex Shironex commented Oct 1, 2026

Copy link
Copy Markdown
Collaborator

Summary

Lands the 2026-08-31 dependency stack (#465, #466, #467, #468) on top of current main in one PR, since #465 no longer merged cleanly.

  • Safe bumps, TypeScript 6.0.3, the vitest family at 4.1.11, vite 8 (Rolldown) with plugin-react 5.2
  • bun.lock and Cargo.lock regenerated against main. cargo update moves Tauri 2.11 to 2.12 and collapses quick-xml to 0.42
  • Both audit ignore lists are now empty: vitest 4.1.11 retires GHSA-82fw-gwwq-j7x9 (its review date was 2026-10-21) and tauri-utils 2.10 drops the unmaintained unic-* warnings
  • Includes the GitHub Actions bump from chore(deps): bump the github-actions group across 1 directory with 2 updates #460 (upload-pages-artifact and deploy-pages v5)

Supersedes #465, #466, #467, #468, #460, #480, #453, #456, #457.

Notes for review

  • The lockfile had to be regenerated from the stack's lockfile, not main's: starting from main's kept a nested @vitest/spy@3.2.4 under storybook, which broke the web typecheck.
  • The desktop app has not been launched on Tauri 2.12 yet. Tests and builds only.

Test plan

  • bun run build, bun run lint, web build, docs build
  • bun run codegen:check
  • bun run test:node (2108 pass), test:plugin, test:web (2953 pass)
  • bun run check:rust (fmt, clippy, 1588 tests, ts-rs drift)
  • bun run audit and cargo audit clean with no ignores
  • Launch the desktop app once on the Tauri 2.12 build

Shironex and others added 6 commits August 31, 2026 15:42
…t advisories

Refreshes bun.lock and Cargo.lock within already-declared semver ranges to
resolve every currently-flagged JS advisory (11 new + 5 previously-ignored:
dompurify, ip-address, brace-expansion x3 chains, nanoid, hono,
@hono/node-server, fast-uri, js-yaml) and both Rust quick-xml DoS advisories
(RUSTSEC-2026-0194/0195, collapsed to a single quick-xml 0.41.0). Bumps the
zod exact pin 4.4.3 -> 4.5.4 across all 4 files that carry it (non-CVE,
matches the deliberate codegen-hoisting pin from 27755f8). Deletes the now-
stale entries from scripts/audit.ts's IGNORED array and .cargo/audit.toml's
ignore list, since both gates hard-fail on stale entries.

A handful of packages surfaced by the same lockfile refresh needed holding
back to stay in scope and avoid crossing majors nobody reviewed:

- shiki, lucide-react, motion, @tauri-apps/plugin-updater: pinned exact in
  apps/web/package.json at their pre-refresh versions. All four are
  Phase-2-flagged in the findings doc for a dedicated smoke-test pass
  (syntax highlighting, icon set, animated surfaces, the signed updater
  flow) and out of scope here.
- typescript-eslint (root) and the @typescript-eslint/utils hoisted slot
  serving @noctcore/eslint-plugin-*: held at 8.61.1 via a bounded override,
  matching the report's own Phase 2 entry for this exact transition.
- @hono/node-server: a transitive @modelcontextprotocol/sdk bump (1.29.0 ->
  1.30.0, itself just satisfying claude-agent-sdk's ">=1.29.0" peer range)
  widened its own declared range to permit a 2.x major. Bounded via
  override to stay on the 1.x line the CVE fix targets (1.19.15+).
- framer-motion / motion-dom: "motion" itself is held at 12.42.2, but its
  own internal (ranged, not pinned) dependency on these sibling packages
  drifted to 12.43.0 in a mixed state worse than either pinned or bumped.
  Pinned both back to keep the whole "motion" family in lockstep.

@anthropic-ai/sdk drifted 0.105.0 -> 0.122.0 as an incidental side effect
(it's peer-satisfied only, with no direct dependency edge to override
cleanly, and claude-agent-sdk's own peer range for it is a wide-open
">=0.93.0"). Left as-is: not imported anywhere in this codebase directly,
and not on the findings doc's own risk list.

Verified: bun run typecheck, apps/web typecheck, bun run lint (incl.
lint:meta), test:node (2 pre-existing unrelated failures in
packages/harness/src/cli.node.test.ts, reproduced identically on
unmodified main), test:web (514/514 files, 2937/2937 tests), test:plugin,
test:rust (1 failure traced to HISTFILE being present in the ambient shell
env, not the code; clean with HISTFILE unset), cargo fmt --check, cargo
clippy. bun run audit now exits 0 with an empty IGNORED array; cargo audit
exits 0 with quick-xml gone from the warning list entirely.

Pins the install linker to "hoisted" via a new bunfig.toml. Bun 1.3.x writes
`configVersion: 1` lockfiles, and that format defaults workspace installs to the
ISOLATED linker. This repo depends on hoisted layout: root-level scripts
(scripts/e2e/*.ts) import workspace packages such as @nightcore/contracts without
declaring them in the root manifest, so an isolated install correctly refuses to
resolve them and `e2e:ring3` dies with "Cannot find module '@nightcore/contracts'".

The pin is required because the brace-expansion advisories cannot be fixed any
other way: three majors are locked at once (1.1.16, 2.1.2, 5.0.8) and each needs
its own patched version, which a single `overrides` entry cannot express without
crossing a major -- exactly the failure reverted in #411. Only a full lockfile
re-resolution fixes all three, and that re-resolution is what migrates the lockfile
to configVersion 1. `bun install --force` preserves configVersion 0 but does not
re-resolve transitives, so it is not an alternative.

Verified: a clean `bun install --frozen-lockfile` with no linker flag (exactly
CI's invocation) installs 915 packages and links all 11 workspace packages at the
root, and `bun run e2e:ring3 --prove` is green.
…script-eslint bump

Retargets the pending TypeScript major from Dependabot's proposed 7.0.2 to
6.0.3. TS 7 is the Go-ported compiler and ships no classic Compiler API — its
root export is lib/version.cjs, and only unstable/* entries expose the new
JSON-RPC client. That breaks two things here outright: typescript-eslint pins
`typescript: ">=4.8.4 <6.1.0"` on every 8.x sub-package (the request to support
7.0.2 was closed not-planned), so `eslint .` would fail repo-wide; and
tools/codegen/gen-settings-scope.ts calls ts.createSourceFile directly, which
would throw. 6.0.3 is the last stable 6.x and the top of that supported window.

Rationale and the full breaking-change analysis: docs/migrations/2026-08-31-typescript.md.

Changes:

- typescript ^5.9.3/^5.6.0 -> ^6.0.3 in the four manifests declaring it.
- @typescript-eslint/{utils,parser,rule-tester} and root typescript-eslint
  8.61.1 -> 8.68.0, completing the Phase 2 bump that the bounded
  `@typescript-eslint/utils` override was holding scope for. That override is
  now deleted — a reviewed bump replaces the freeze.
- apps/web/tsconfig.json: drop `baseUrl: "."`. TS 6 no longer treats baseUrl as
  a module-resolution lookup root and now errors on it (TS5101). Behaviour is
  unchanged: baseUrl was already the tsconfig's own directory, and under
  `moduleResolution: bundler` `paths` resolves relative to that directory
  regardless.
- packages/{eslint-plugin,harness}/tsconfig.json: add `ignoreDeprecations: "6.0"`.
  This is NOT for our config — neither sets baseUrl. tsup 8.5.1 hardcodes
  `baseUrl: compilerOptions.baseUrl || "."` into its --dts build
  (tsup/dist/rollup.js), so every `tsup --dts` run trips TS5101 no matter what
  the tsconfig says. 8.5.1 is the current latest, so there is no version to
  upgrade to; this is the escape hatch TypeScript's own error text prescribes.
  Remove it once tsup stops injecting the option.

noUncheckedSideEffectImports (the one genuinely behavioural TS 6 default flip,
now true) surfaced zero errors. The repo's four in-scope side-effect imports are
all CSS and are satisfied by vite/client's `declare module '*.css' {}`, so no
opt-out was needed.

Verified: typecheck (tsc -b --force), tsc -b packages/engine, tsc -b apps/web,
lint (incl. tsup --dts builds, eslint ., lint:meta), test:node, test:web,
test:plugin, test:rust, check:rust, cargo fmt --check, cargo clippy
--all-targets, audit, and codegen:check — which is what actually exercises
gen-settings-scope.ts's Compiler API usage and is not CI-wired.

Dependabot PR #418 (7.0.2) left untouched.
…he app build)

PR A of the staged vite/vitest migration (docs/migrations/2026-08-31-vite.md).
vitest 4 runs on the vite already in the tree, so the vitest-side structural
changes land isolated from the app's own vite 7 -> 8 move (PR B).

  vitest / @vitest/browser / @vitest/coverage-istanbul  3.2.7 -> 4.1.11
  @vitest/browser-playwright                            new, 4.1.11
  packages/eslint-plugin's vitest                       3.2.7 -> 4.1.11

@vitest/browser is KEPT: @storybook/addon-vitest still peer-declares it.

Browser provider rewrite (BC-A1): vitest 4 replaced the `provider: 'playwright'`
string with a factory from a separate package. `contextOptions` moves to the
provider call rather than per-instance -- instance-level provider overrides do
not merge with the parent, and this repo runs one instance per project. The
reduced-motion emulation that de-flakes the sheet-animation click tests is
preserved and verified live.

Also swept BC-A2's deprecated `@vitest/browser/context` imports to
`vitest/browser` across 36 test files (+ an eslint --fix pass: the new specifier
sorts differently under simple-import-sort).

Three things the plan missed, all documented in a corrections section appended
to the migration doc -- read it before starting PR B:

- vite 8 arrives with PR A regardless. vitest 4 declares vite in DEPENDENCIES,
  not just peers, so bun resolves it independently to 8.2.2 (astro already had
  it in the tree). The app build genuinely stays on vite 7.3.6, but the test
  runner is on vite 8 + Rolldown today. Bun has no scoped-override mechanism to
  prevent it, and a global vite override would break astro. BC-B1's Rolldown
  dep-optimizer risk is therefore already paid here -- so this was stress-tested
  to PR B's standard: 4 cold-cache `test:web` runs, 517 files / 2953 tests green
  every time, zero `optimized dependencies changed`.

- vitest-browser-react 2.x made `render()` async, breaking 218 test files at
  runtime, not just in types. Held at ^1.0.0, whose peer range (`^4.0.0-0`)
  already covers vitest 4.1.11 -- a supported combination, not a workaround. The
  async-render migration is its own PR.

- storybook pins @vitest/spy at exactly 3.2.4 (still true on 10.5.10), so vitest
  4 leaves two structurally-incompatible copies: 159 type errors over 69 files.
  Collapsed via a root override. This crosses a major and so sits in tension
  with the documented override policy; it passes `bun run audit` because exact
  pins count as bounded. Rationale and removal condition are in the doc.

tsconfig's `types` entry also needed updating: @vitest/browser 4 dropped its
`./providers/*` exports, so it now points at @vitest/browser-playwright/context.
And .gitignore picks up vitest 4's new .vitest-attachments/ screenshot dir.

Gates: typecheck, apps/web tsc, lint (incl. lint:meta), codegen:check, audit,
e2e:ring3 --prove, test:node (2059), test:web (517/2953, x4 cold cache),
test:plugin (15), cargo fmt --check, cargo clippy --all-targets -- all green.
test:rust is 1585 pass / 3 fail, the documented pre-existing macOS-only
e2e::sidecar_boundary::contract trio.
…ct 5.2.0

PR B of the vite/vitest stack. PR A left `node_modules/vite` at 7.3.6, so the
production build and dev server were still the untested surface; this moves them.

Vite 8 is a four-engine swap, not just the dep-optimizer swap the migration plan
described: Rolldown replaces Rollup for the production bundle, Oxc replaces
esbuild for JS transform and minification, and Lightning CSS replaces esbuild for
CSS minification. No config edits were required because the repo configures none
of the renamed options (no rollupOptions/manualChunks/esbuild:/worker:/lib build)
— not because the API was unchanged.

The bump de-duplicates the tree rather than adding to it: the nested `astro/vite`
and `vitest/vite` 8.2.2 copies collapse into the single hoisted root, so the
lockfile delta is four entries removed and none added, and PR A's
`optimizeDeps.esbuildOptions` deprecation warning goes away.

All three `optimizeDeps` F3 guards were left byte-identical and remain sufficient
under Rolldown's scanner. `test:web` ran twice with a cold `.vite` cache: 517
files / 2953 tests green both times, zero `optimized dependencies changed`.
`vite build` drops 3.81s -> 715ms; dist grows 0.75% (Lightning CSS lowering) while
the main JS chunk sheds 60.5 kB, and all 322 asset/inter-chunk references resolve
with `base: './'` intact for Tauri's custom protocol.

Storybook is not a blocker: @storybook/react-vite and @storybook/builder-vite
10.5.10 both declare vite ^5 || ^6 || ^7 || ^8, as does every other vite-peer
consumer in the tree.

Still owed: a GUI `bun run desktop` smoke test of the Tauri WebView window.
Resolve the stack (safe bumps, TypeScript 6, vitest 4, vite 8) against main.
Both lockfiles are regenerated: bun.lock keeps a single @vitest/spy 4.1.11 so
storybook/test mocks type-check, and cargo update collapses quick-xml to 0.42.
The audit ignore lists are empty on both sides: vitest 4.1.11 retires
GHSA-82fw-gwwq-j7x9 and tauri-utils 2.10 drops the unic-* warnings.
…updates

Bumps the github-actions group with 2 updates in the / directory: [actions/upload-pages-artifact](https://github.com/actions/upload-pages-artifact) and [actions/deploy-pages](https://github.com/actions/deploy-pages).


Updates `actions/upload-pages-artifact` from 4 to 5
- [Release notes](https://github.com/actions/upload-pages-artifact/releases)
- [Commits](actions/upload-pages-artifact@v4...v5)

Updates `actions/deploy-pages` from 4 to 5
- [Release notes](https://github.com/actions/deploy-pages/releases)
- [Commits](actions/deploy-pages@v4...v5)

---
updated-dependencies:
- dependency-name: actions/deploy-pages
  dependency-version: '5'
  dependency-type: direct:production
  update-type: version-update:semver-major
  dependency-group: github-actions
- dependency-name: actions/upload-pages-artifact
  dependency-version: '5'
  dependency-type: direct:production
  update-type: version-update:semver-major
  dependency-group: github-actions
...

Signed-off-by: dependabot[bot] <support@github.com>
@Shironex Shironex added dependencies Pull requests that update a dependency file github_actions Pull requests that update GitHub Actions code rust Pull requests that update rust code javascript Pull requests that update javascript code security Sandbox, confinement, injection defense, permissions area: web React board (apps/web) area: tooling lint-meta, eslint plugin, CI, dogfood scripts P1 High - next up labels Oct 1, 2026
@github-project-automation github-project-automation Bot moved this to Todo in Nightcore Oct 1, 2026
@Shironex
Shironex merged commit 59c83ce into main Oct 1, 2026
17 checks passed
@Shironex
Shironex deleted the chore/deps-backlog branch October 1, 2026 21:19
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

area: tooling lint-meta, eslint plugin, CI, dogfood scripts area: web React board (apps/web) dependencies Pull requests that update a dependency file github_actions Pull requests that update GitHub Actions code javascript Pull requests that update javascript code P1 High - next up rust Pull requests that update rust code security Sandbox, confinement, injection defense, permissions

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant