Skip to content

build(deps): take vitest 4 and @eslint/js 10, and pin @types/node to the runtime - #67

Merged
semics-tech merged 1 commit into
mainfrom
build/toolchain-majors
Jul 31, 2026
Merged

build(deps): take vitest 4 and @eslint/js 10, and pin @types/node to the runtime#67
semics-tech merged 1 commit into
mainfrom
build/toolchain-majors

Conversation

@semics-tech

Copy link
Copy Markdown
Owner

Closes #40 and #42. Closes #39 without taking it — see below.

vitest 4 removes the workspace file

vitest.workspace.ts and defineWorkspace are gone. Projects are now test.projects in vitest.config.ts. The five projects, their roots and their timeouts carry over unchanged.

The way this fails is worth knowing, and there's a comment at the top of the new file saying so. vitest 4 does not warn about a workspace file it no longer reads — it just finds no projects. pnpm test:unit names its projects with --project, so it errored loudly and the problem was obvious:

Error: No projects matched the filter "protocol", "server", "worker", "dashboard".

An unfiltered vitest run would have collected nothing, reported no failures, and exited 0. A green CI would have meant the tests did not run.

@eslint/js 10 turns on no-useless-assignment

Three dead initialisers, all real, all fixed rather than suppressed:

  • hub.ts declared identity as AuthenticatedWorker | null = null, then assigned it in a try whose catch always returns. The null was a value no path could observe — and a second binding (const authenticated = identity) existed further down purely to narrow it back to non-null. Both gone; there's one authenticated now, declared without an initialiser, which TypeScript accepts because it can see the catch return.
  • job-edit.ts seeded startStepId from the definition, then reassigned it on every branch.
  • agent-repo.ts assigned 'unknown' twice — at the declaration and again in the catch.

Why #39 (@types/node 26) is closed, not merged

@types/node should track the runtime, not the newest release. Everything here is Node 24engines, both Dockerfile stages, CI's NODE_VERSION, and the runtime baked into the single-file executables — and that's deliberate: release.yml already says 26 is the Current line and the worker ships its runtime onto customer database servers.

Types from a newer major describe APIs that are not there. The failure wouldn't land in CI (which also runs 24) — it'd land at runtime on someone else's SQL host.

There's now a dependabot.yml ignore for @types/node majors, alongside the existing one for argon2, saying to raise it when NODE_VERSION moves, in the same change.

Verified on vitest 4

typecheck 7/7 · lint · 357 unit · 18 integration · 25 e2e

🤖 Generated with Claude Code

https://claude.ai/code/session_01AyYg2j8FVkLjiaVcj5HCkj

@semics-tech
semics-tech force-pushed the build/toolchain-majors branch from 8bb21e5 to 7e17a95 Compare July 31, 2026 12:22
…the runtime

Closes dependabot #40 and #42, and closes #39 without taking it.

vitest 4 removes the workspace file. `vitest.workspace.ts` and
`defineWorkspace` are gone; projects are declared as `test.projects` in
vitest.config.ts, which is what this adds. The five projects, their roots
and their timeouts are carried over unchanged.

The way that removal fails is worth recording, and is in a comment at the
top of the new file. vitest 4 does not warn about a workspace file it no
longer reads — it just finds no projects. `pnpm test:unit` names its
projects with --project, so it errored and the problem was obvious. An
unfiltered `vitest run` would have collected nothing, reported no failures
and exited 0, and a green CI would have meant the tests did not run.

@eslint/js 10 turns on `no-useless-assignment`, which found three dead
initialisers. All three are real and all three are fixed rather than
suppressed:

  - hub.ts declared `identity` as `AuthenticatedWorker | null = null`, then
    assigned it in a try whose catch always returns. The null was a value no
    path could observe, and a second binding existed further down purely to
    narrow it back to non-null. Both are gone; there is one `authenticated`
    now, declared without an initialiser, which TypeScript accepts because
    it can see the catch return.
  - job-edit.ts seeded `startStepId` from the definition and then reassigned
    it on every branch.
  - agent-repo.ts assigned 'unknown' twice, at the declaration and again in
    the catch.

@types/node stays on 24 and dependabot is told not to offer 26 again.
Everything here runs Node 24 — engines, both Dockerfile stages, CI, and the
runtime baked into the single-file executables — because 26 is the Current
line and the worker ships its runtime onto customer database servers.
Types from a newer major describe APIs that are not present, and the
failure would land at runtime on someone else's SQL host rather than in CI.
The ignore says to raise it when NODE_VERSION moves, in the same change.

Verified on vitest 4: typecheck 7/7, lint, 357 unit, 18 integration, 25 e2e.

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01AyYg2j8FVkLjiaVcj5HCkj
@semics-tech
semics-tech force-pushed the build/toolchain-majors branch from 7e17a95 to 338266d Compare July 31, 2026 12:27
@semics-tech
semics-tech merged commit 91d5258 into main Jul 31, 2026
9 checks passed
@semics-tech
semics-tech deleted the build/toolchain-majors branch July 31, 2026 12:29
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.

1 participant