Skip to content

Update zod to v4 and vite to v8 - #215

Merged
maccman merged 4 commits into
nextfrom
claude/angry-bhabha-e1b447
Jun 16, 2026
Merged

maccman merged 4 commits into
nextfrom
claude/angry-bhabha-e1b447

Conversation

@maccman

@maccman maccman commented Jun 16, 2026 •

Copy link
Copy Markdown
Contributor

What

Updates two dependencies to their latest major versions:

Dependency Before After Packages
zod ^3.23.0 / 3.23.0 ^4.4.3 / 4.4.3 core, extension, desktop
vite ^7.0.4 ^8.0.16 desktop
@vitejs/plugin-react ^4.6.0 ^6.0.2 desktop
vitest ^3 ^4 core, extension, desktop

Why

Requested dependency refresh to latest. zod and vite were the targets; the other two bumps are forced by vite 8 — vitest@3 caps at vite 7 and @vitejs/plugin-react@4 caps at vite 7. vitest is bumped in all three packages (not just desktop) so the lockfile doesn't carry a split major.

Code change

One file: the IPC call helper in packages/core/src/ipc/invoke.ts. zod 4 reworked ZodType's generics from <Output, Def, Input> to <Output, Input, Internals> and removed the exported ZodTypeDef, so ZodType<TOutput, ZodTypeDef, unknown> becomes ZodType<TOutput, unknown> — same output/input intent.

Reviewer notes

  • Vite 8 ships Rolldown as its default bundler (replacing Rollup). The desktop build's pre-existing chunk-size warning now references build.rolldownOptions instead of Rollup options.
  • A few zod APIs in the codebase are now deprecated-but-functional in v4: .passthrough() (3 sites) and z.string().uuid()/.url()/.datetime() (capture-envelope, page-text). They still work and all tests pass; migrating them to z.looseObject/z.uuid()/z.url() is optional follow-up, not done here to keep this change minimal.
  • AI SDK v6 (ai@6) accepts zod 4 (^4.1.8); Node v24 satisfies vite 8's >=22.12.0 engine.

Verification

All green:

  • pnpm typecheck — 4 packages
  • pnpm test — 1741 tests (core 761, desktop 948, extension 28, db 4)
  • pnpm lint — only pre-existing warnings, none in touched files
  • desktop vite build — succeeds (vite 8 / Rolldown)
  • extension wxt build — succeeds on Vite 8.0.16

🤖 Generated with Claude Code


Note

Medium Risk
Wide-reaching validation and desktop bundler changes (Zod 4 + Vite 8/Rolldown); capture z.guid() is a deliberate contract tweak that must stay in sync with the Rust host parity tests.

Overview
Major dependency refresh across the monorepo: Zod 3 → 4.4.3 (core, extension, desktop), Vite 7 → 8 and @vitejs/plugin-react 6 (desktop), and Vitest 3 → 4 (core, extension, desktop, db), with lockfile updates (Vite 8’s Rolldown-based bundler chain).

Zod 4 API migrations in shared validation code: IPC call now types schemas as ZodType<TOutput, unknown> (drops ZodTypeDef). Settings, frontmatter, and chat history use z.looseObject instead of .object().passthrough(). Capture and extension wire schemas move to z.guid(), z.url(), and z.iso.datetime() — notably z.guid() on capture id so drain validation matches the native host’s looser hex-UUID rules (not RFC z.uuid()). A parity fixture documents acceptance of non-RFC UUIDs.

Build/test tooling only: no product feature logic beyond validation shape compatibility.

Reviewed by Cursor Bugbot for commit 54bca82. Bugbot is set up for automated code reviews on this repo. Configure here.

Summary by CodeRabbit

  • Chores
    • Updated dependencies across all packages: validation library upgraded to major version 4, testing framework to version 4, build tooling and plugins updated to latest versions for improved stability.
    • Refined internal type signatures for compatibility with upgraded dependencies.

Bump `zod` ^3.23.0 → ^4.4.3 (core, extension, desktop) and `vite`
^7.0.4 → ^8.0.16 (desktop). Vite 8 forces two transitive bumps:
`vitest` ^3 → ^4 (vitest 3 caps at vite 7) and `@vitejs/plugin-react`
^4 → ^6 (plugin-react 4 caps at vite 7). vitest is bumped across all
three packages to avoid a split major in the lockfile.

The only code change is in the IPC `call` helper: zod 4 reworked
`ZodType`'s generics from `<Output, Def, Input>` to
`<Output, Input, Internals>` and dropped the exported `ZodTypeDef`,
so `ZodType<TOutput, ZodTypeDef, unknown>` becomes
`ZodType<TOutput, unknown>` (same output/input intent).

Verified: typecheck, full test suite (1741 tests), lint, the desktop
`vite build` (vite 8 / Rolldown), and the extension `wxt build` all
pass. Node v24 satisfies vite 8's engine; AI SDK v6 accepts zod 4.

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
@coderabbitai

coderabbitai Bot commented Jun 16, 2026 •

Copy link
Copy Markdown

Review Change Stack

Walkthrough

Upgrades zod from v3 to v4 and vitest from v3 to v4 across packages/core, apps/extension, and apps/desktop. The desktop app also bumps vite to v8 and @vitejs/plugin-react to v6. The IPC call function in packages/core/src/ipc/invoke.ts is updated to use Zod v4's two-parameter ZodType<TOutput, unknown> generic instead of the three-parameter v3 form, removing the ZodTypeDef import.

Changes

Zod v4 and tooling upgrade

Layer / File(s) Summary
Dependency version bumps across packages
packages/core/package.json, apps/desktop/package.json, apps/extension/package.json
zod bumped to ^4.4.3 and vitest to ^4 in all three packages; desktop additionally bumps @vitejs/plugin-react to ^6.0.2 and vite to ^8.0.16.
Adapt IPC invoke.ts to Zod v4 generics
packages/core/src/ipc/invoke.ts
Removes the ZodTypeDef import and changes the schema parameter of call<TOutput> from ZodType<TOutput, ZodTypeDef, unknown> to ZodType<TOutput, unknown> to match Zod v4's updated generic shape.

Estimated code review effort

🎯 2 (Simple) | ⏱️ ~10 minutes

🚥 Pre-merge checks | ✅ 5
✅ Passed checks (5 passed)
Check name Status Explanation
Title check ✅ Passed The title accurately captures the main changes: updating zod to v4 and vite to v8, which are the primary dependencies updated across the packages.
Docstring Coverage ✅ Passed No functions found in the changed files to evaluate docstring coverage. Skipping docstring coverage check.
Linked Issues check ✅ Passed Check skipped because no linked issues were found for this pull request.
Out of Scope Changes check ✅ Passed Check skipped because no linked issues were found for this pull request.
Description Check ✅ Passed Check skipped - CodeRabbit’s high-level summary is enabled.

✏️ Tip: You can configure your own custom pre-merge checks in the settings.

✨ Finishing Touches
📝 Generate docstrings
  • Create stacked PR
  • Commit on current branch

Comment @coderabbitai help to get the list of available commands and usage tips.

Follow-up cleanup of the deprecated-but-functional zod calls left after
the v4 bump. In zod 4 these are thin aliases over the new top-level
functions, so the migration is behavior-preserving (the existing test
suite already runs on zod 4.4.3 and the capture-envelope fixtures pin
the edge cases — uppercase UUIDs, localhost URLs, calendar-invalid
timestamps):

- z.string().uuid()      -> z.uuid()
- z.string().url()       -> z.url()
- z.string().datetime()  -> z.iso.datetime()
- z.object(...).passthrough() -> z.looseObject(...)

Verified: typecheck, full test suite (1741 tests), and lint all pass.

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>

@cursor cursor Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

Cursor Bugbot has reviewed your changes using default effort and found 1 potential issue.

Fix All in Cursor

❌ Bugbot Autofix is OFF. To automatically fix reported issues with cloud agents, enable autofix in the Cursor dashboard.

Reviewed by Cursor Bugbot for commit 3da5fa3. Configure here.

Comment thread packages/core/src/actions/capture-envelope.ts Outdated
maccman and others added 2 commits June 15, 2026 18:56
Bugbot caught a contract regression introduced by the zod 3→4 bump:
`z.uuid()` enforces RFC 4122 version/variant nibbles, but the native
host's `is_uuid` (apps/native-host/src/envelope.rs) accepts any
8-4-4-4-12 hex string. A stricter drain would quarantine captures the
host already spooled. zod 3's `z.string().uuid()` was loose; zod 4
silently tightened it (the deprecated method aliases the strict
`z.uuid()`), and the fixtures only covered RFC-valid v4 UUIDs so the
gap went unnoticed.

Switch the envelope id to `z.guid()` — zod 4's loose 8-4-4-4-12 hex
validator — which mirrors the host exactly (verified: it still rejects
dots/traversal, preserving the path-safety guard). Add a shared parity
fixture with a non-RFC hex id so both the zod and Rust parity tests pin
this and the drift can't recur silently.

Verified: typecheck, full TS suite (1742 tests), the Rust parity test
(shared_fixtures_pin_the_ts_contract), and lint all pass.

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
The vite-8 cascade bumped vitest to ^4 in core, extension, and desktop
but missed packages/db, leaving it on ^3 — a split vitest major in one
workspace. Bump it too; its single dialect test passes unchanged on
vitest 4.

(The lingering transitive vite@7.3.5 is wxt-internal, owned by
wxt@0.20.26 / @wxt-dev/module-react, not this skew — left as-is since
the extension still builds on vite 8.)

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
@maccman
maccman merged commit 9972ae4 into next Jun 16, 2026
4 checks passed
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