* refactor(cache): extract Cloudflare cache adapters into @vinext/cloudflare
Move the Cloudflare KV data cache and edge CDN cache adapters out of
vinext into a new publishable @vinext/cloudflare package:
- cache/kv-data-adapter(.runtime).ts (KVCacheHandler, kvDataAdapter)
- cache/cdn-adapter(.runtime).ts (CloudflareCdnCacheAdapter, cdnAdapter)
tpr.ts stays in vinext. vinext now depends on @vinext/cloudflare
(workspace:*) and the package declares vinext as a peer dep; both build
from source via tsconfig paths so there is no build-order cycle. The
vinext/cloudflare barrel still re-exports KVCacheHandler for back-compat.
Wires up tsconfig paths, a vitest source alias, root build/postinstall,
and the preview/publish workflows for the new package. Updates internal
consumers (apps/web, examples/workers-cache), docs, and tests.
* ci(create-next-app): install @vinext/cloudflare from local tarball
vinext now depends on @vinext/cloudflare, which isn't published to npm
yet. The create-next-app smoke test packs vinext locally and resolves
its deps from the registry, so the install (and dev server) failed with
ERR_PNPM_FETCH_404 for @vinext/cloudflare.
Pack @vinext/cloudflare alongside vinext and add a pnpm override in the
scaffolded project pointing at the local tarball so the dependency
resolves offline.
* refactor(cloudflare): address review feedback
- Remove the root barrel export from @vinext/cloudflare; expose only the
./cache/* subpaths via a wildcard export (no root main/types).
- vinext/cloudflare re-exports KVCacheHandler from the full subpath.
- Drop the redundant .npmignore (the package.json "files" allowlist
already restricts the publish to dist).
- Remove the unsupported imperative setCacheHandler/KVCacheHandler usage
from both READMEs; the cache plugin config is the supported approach.
- Simplify test wiring: drop the now-unused @vinext/cloudflare tsconfig
path and dedupe the vitest source alias into a shared constant.
* chore(cloudflare): drop unused vite devDependency
The @vinext/cloudflare config uses vite-plus and nothing imports vite, so
the vite devDependency was unused. build/check/knip stay green without it.
* Apply suggestion from @james-elicx
* feat(release): commit-driven changesets with auto-generated changesets
Adopt stock Changesets for versioning/changelog/publishing, with the only
bespoke surface being a script that creates changesets automatically from
Conventional Commits. Auto-generated changeset files never live on `main` —
they are written to the CI working tree, consumed by changesets/action into a
rolling Version PR, and discarded. Manually authored changesets still work.
- scripts/create-changeset.mjs: derive per-package bumps from Conventional
Commits (paths -> package, type -> bump). Includes the version-vs-tag guard
so a merged Version PR publishes instead of re-opening a PR.
- scripts/version.mjs: `changeset version` + append a `## Contributors` list to
each bumped package's CHANGELOG.md (idempotent, pure rewrite unit-tested).
- .github/workflows/release-pr.yml: version-only changesets/action (no publish).
- .github/workflows/publish.yml: guarded OIDC publish (preserves
`vp pm publish --provenance`); version now comes from `changeset version`.
- Reconcile packages/vinext version (0.0.5 -> 0.0.55) so the guard is coherent.
Unit tests for both scripts pass (35). The release orchestration (Version PR
creation, OIDC publish, gh contributor resolution) can only be validated in a
live CI run.
* refactor(release): collapse to a single changesets workflow
Let changesets/action own as much as possible. Delete the separate publish.yml
(guard job, manual bump, manual OIDC/tag/release/notify steps) and the
release-pr.yml split. One workflow now:
- create-changeset.mjs writes auto changesets to the working tree (its
version-vs-tag guard yields nothing right after a Version PR merges).
- changesets/action maintains the Version PR and, when no changesets remain,
publishes via `changeset publish` with OIDC trusted publishing + provenance,
and creates the git tag + GitHub Release.
Removes the unused release:version script. Contributors list still handled by
scripts/version.mjs as the action's version command.
* refactor(release): convert release scripts to .mts, drop .d.mts files
Replace the .mjs + hand-written .d.mts declaration pairs with real TypeScript
(.mts) source. Node >=24 (the setup default) runs .mts directly via native type
stripping; .mts is unambiguously ESM so it needs no "type": "module" and emits
no MODULE_TYPELESS warning. The cross-import uses an explicit .mts specifier
(Node requires it), permitted in tsc via allowImportingTsExtensions (safe: the
project is noEmit).
- scripts/create-changeset.{mjs,d.mts} -> scripts/create-changeset.mts
- scripts/version.{mjs,d.mts} -> scripts/version.mts
- tsconfig: allowImportingTsExtensions
- release.yml: run node scripts/*.mts
vp check (format + lint + types) clean; 35/35 unit tests pass.
* refactor(release): trim release scripts (~690→~470 source lines)
Cut comment bloat, remove dead code, tighten without dropping behavior:
- Condense verbose JSDoc/@param blocks to one-line purpose comments; keep the
load-bearing "why" (correctness-rule header, insertContributors idempotency).
- Delete unused `newestChangelogVersion` (+ its tests) — exported/tested but
never called.
- Tighten run()/insertContributors/latestTagVersion without behavior change.
Multi-package machinery and the bottom `## Contributors` list are retained per
requirements. vp check clean; 33 unit tests pass.
* feat(release): grouped conventional changelog + filter bot contributors
The default changesets changelog groups by bump level (### Minor Changes) and
renders our changeset summary as a nested bullet dump. Replace it with a real
conventional-commits changelog: version.mts now regroups each release's commits
into ### Features / ### Bug Fixes / ### Performance sections (scope bolded, type
prefix dropped) and rewrites the newest CHANGELOG section, then appends the
## Contributors list with [bot] accounts filtered out.
- create-changeset.mts: extract conventionalParts + collectReleaseCommits +
releaseRangeStart and export the commit-walk so version.mts reuses it (no
duplicate git logic).
- version.mts: groupedChangelogBody + rewriteReleaseSection (idempotent: only
`## <digit>` is a section boundary); dedupeSortLogins drops `[bot]` logins.
- Tests updated for the new pure builders.
vp check clean; 33 unit tests pass. Verified end-to-end with a local dry run.
* refactor(release): simplify per PR review
- discoverPublishablePackages: scan only packages/* (publishable packages don't
live elsewhere), drop the apps/examples/benchmarks scan.
- Delete isReleaseCommit: the "chore: version packages" release commit is a
`chore`, already excluded by parseBumpFromSubject returning null. No need to
hardcode release-message formats.
vp check clean; 31 unit tests pass.
* docs(release): clarify why the version-vs-tag guard exists
Per PR review: the guard was confusing. Document inline that it only suppresses
the post-merge/pre-publish window (version bumped, tag not yet created), which
would otherwise re-open a Version PR instead of publishing. Keeping the
never-on-main design per review decision.
* feat(release): sub-group changelog areas and humanize area names
Within each type section (### Features / ### Bug Fixes / …), areas (commit
scopes) with more than 3 items now get their own `#### <Area>` sub-group with
the scope prefix dropped; smaller areas and scopeless commits fall under
`#### Other`. When no area qualifies the list stays flat. Area names are
humanized (app-router → "App Router", css → "CSS", ppr → "PPR", i18n → "i18n")
in headings and in the bold prefixes.
Also: groupedChangelogBody now renders only known release types (GROUPS) — it
no longer leaks non-release types into an "Other Changes" bucket.
vp check clean; 32 unit tests pass. Verified with a local dry run.
* feat(release): rename changelog Other sub-group to Misc
* feat(release): sub-group areas with 3+ items (was >3)
* fix(release): address PR review (stale refs, contributor API, doc)
- Fix stale references to deleted files: .mjs → .mts and release-pr.yml →
release.yml in .changeset/README.md and the release.yml header comment.
- resolveContributors: one paginated `gh api compare` call instead of one
`gh api commits/<sha>` per commit (N round-trips → 1). This also removes
version.mts's local git() helper, so no more `fatal:` probe noise from it.
No behavior change to the changelog/contributor output (verified via dry run:
same 4 contributors resolved). vp check clean; 32 unit tests pass.
The bot's "no git tags" bootstrap concern does not apply: tags v0.0.10..v0.0.55
exist and CI checks out with fetch-depth: 0, so the guard resolves 0.0.55.
* fix(release): run pinned changeset CLI; drop dead affectedPackages branch
Per second bonk review:
- Invoke the pinned, installed @changesets/cli via `vp exec changeset` instead
of `vp dlx @changesets/cli` (which fetches a floating latest at run time) — in
release.yml publish and version.mts. Removes the reproducibility gap vs the
lockfile-pinned 2.31.0.
- affectedPackages: remove the unreachable `dir === "."` / empty-prefix branch
now that discovery only returns `packages/*` keys.
vp check clean; 32 unit tests pass.
* fix(release): only emit valid GitHub logins in Contributors; doc fix
Per third bonk review:
- resolveContributors: `.author.login // empty` (was `// .commit.author.name`),
so commits with an unlinked email contribute no entry instead of a raw git
display name. dedupeSortLogins now keeps only `[a-zA-Z0-9-]+` shapes, which
also subsumes the previous `[bot]` filter — no more broken `- @Full Name`
mentions.
- .changeset/README.md: suggest `vp exec changeset` instead of the floating
`vp dlx @changesets/cli` for manual changeset authoring.
vp check clean; 32 unit tests pass; dry run resolves the same valid handles.
* fix: replace relative shim imports with bare specifier vinext/shims/X (#1001)
Internally, server modules imported their own 'use client' shims via
relative paths (e.g. from "../shims/slot.js"). @vitejs/plugin-rsc's
packageSources tracking only fires for bare specifier imports, so
relative shim imports took a broken fallback path generating absolute
filesystem paths that fail against the package's exports field.
Changes:
- 67 relative shim imports across 34 source files rewritten to
"vinext/shims/<name>"
- Added .tsconfig paths mapping so TypeScript resolves shim types to
source (avoids type mismatch between dist and source module graphs)
- Added vitest project-level resolve aliases for vinext/shims -> source
(prevents separate module graph instances in unit tests)
- Added package.json exports for ./dist/shims/*.js as a safety net
- Added regression test (tests/shim-imports.test.ts) that asserts no
relative shim imports exist in source
* fix: address review feedback for relative shim imports (#1006)
- Convert missed side-effect import in dev-server.ts to vinext/shims/router-state
- Extend regression test regex to catch bare side-effect import statements
- Remove redundant ./dist/shims/*.js exports from package.json
* replace test with oxlint plugin
---------
Co-authored-by: James <james@eli.cx>
When vinext is installed from npm, the .ts source files aren't in the
package but .js.map files reference them, causing Vite to log many
'points to missing source files' warnings.
Adding inlineSources: true to tsconfig embeds the original TypeScript
source content directly in the .js.map files so no separate .ts files
are needed.
Fixes#2