build: migrate from Bun + Biome to Vite+ (pnpm, Oxlint, Oxfmt, tsdown)#118
build: migrate from Bun + Biome to Vite+ (pnpm, Oxlint, Oxfmt, tsdown)#118
Conversation
…own) Replace Bun with pnpm as the package manager, Biome with Oxlint/Oxfmt for linting and formatting, and tsc with vp pack (tsdown) for library builds. All tooling is now unified under the Vite+ CLI (`vp`). Key changes: - Add root vite.config.ts with lint, fmt, and staged config - Add pnpm-workspace.yaml replacing bun workspaces - Update all package.json scripts from bun/bunx to vp/pnpm exec - Update CI workflows to use voidzero-dev/setup-vp action - Update lefthook hooks to use vp check and pnpm exec - Update fidnii exports to .mjs/.d.mts (tsdown output) - Delete biome.json and bun.lock - Update all documentation to reference new tooling Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
Deploying convert-fidnii with
|
| Latest commit: |
70a8669
|
| Status: | ✅ Deploy successful! |
| Preview URL: | https://f6fe8e50.convert-fidnii.pages.dev |
| Branch Preview URL: | https://a115-migrate-from-bun.convert-fidnii.pages.dev |
📝 WalkthroughWalkthroughThe repository's developer tooling and CI are migrated from Bun/Biome to Vite+ (vp) with pnpm workspaces; CI workflows, hooks, configs, package manifests, docs, and example commands are updated to use vp/pnpm and related tooling. Most edits are tooling, config, and formatting changes, not runtime code. Changes
Estimated code review effort🎯 4 (Complex) | ⏱️ ~60 minutes Possibly related PRs
Suggested reviewers
Poem
🚥 Pre-merge checks | ✅ 3✅ Passed checks (3 passed)
✏️ Tip: You can configure your own custom pre-merge checks in the settings. ✨ Finishing Touches🧪 Generate unit tests (beta)
Comment |
Greptile SummaryThis PR completes a toolchain migration from Bun + Biome to Vite+ ( Key changes:
Issues found:
Confidence Score: 3/5
Important Files Changed
Flowchart%%{init: {'theme': 'neutral'}}%%
flowchart TD
subgraph Before["Before (Bun + Biome)"]
B1["oven-sh/setup-bun@v2"] --> B2["bun install --frozen-lockfile"]
B2 --> B3["bunx biome ci . (lint/fmt)"]
B2 --> B4["bun run build"]
B2 --> B5["bun run test"]
BL["bun.lock"] -.->|resolves| B2
BCF["biome.json"] -.->|configures| B3
end
subgraph After["After (Vite+ / pnpm)"]
A1["voidzero-dev/setup-vp@v1\n(Node 24 + pnpm)"] --> A2["vp install --frozen-lockfile"]
A2 --> A3["vp check\n(Oxlint + Oxfmt)"]
A2 --> A4["vp run -r build"]
A2 --> A5["vp run -r test"]
AL["pnpm-lock.yaml\npnpm-workspace.yaml"] -.->|resolves| A2
ACF["vite.config.ts\n(Oxlint + Oxfmt config)"] -.->|configures| A3
OVR["pnpm.overrides:\nvite → @voidzero-dev/vite-plus-core@latest"] -.->|aliases| A2
end
Before -->|migrated by this PR| After
Reviews (1): Last reviewed commit: "build: migrate from bun + biome to vite+..." | Re-trigger Greptile |
There was a problem hiding this comment.
Pull request overview
Migrates the monorepo tooling from Bun + Biome to Vite+ (vp) + pnpm, updating configs, scripts, CI, and docs accordingly.
Changes:
- Introduce Vite+ configuration (Oxlint/Oxfmt + staged checks) and switch repo scripts/hooks to
vp/pnpm. - Update CI/release workflows to use
voidzero-dev/setup-vpand replacebun/bunxcommands withvp/pnpm exec. - Update the
fidniipackage build pipeline tovp pack(tsdown) and adjust published entry/type file paths; apply formatting changes across docs/examples.
Reviewed changes
Copilot reviewed 31 out of 34 changed files in this pull request and generated 1 comment.
Show a summary per file
| File | Description |
|---|---|
vite.config.ts |
Adds Vite+ root config for lint/format/staged checks. |
pnpm-workspace.yaml |
Defines pnpm workspace package globs. |
package.json |
Switches root scripts from bun/biome to vp; sets pnpm + overrides for Vite+. |
lefthook.yml |
Updates hooks to run vp check --fix and pnpm exec commitlint. |
fidnii/vite.config.ts |
Switches config import to vite-plus and adds pack (tsdown) config. |
fidnii/test-page/index.html |
Formatting-only (doctype casing). |
fidnii/src/ViewportBounds.ts |
Uses a type-only vec3 import instead of inline import typing. |
fidnii/playwright.config.ts |
Uses pnpm run dev for the Playwright web server command. |
fidnii/package.json |
Updates package metadata and build output paths for vp pack output. |
fidnii/README.md |
Formatting-only changes in code samples. |
fidnii/CHANGELOG.md |
Minor formatting/whitespace cleanup. |
examples/getting-started/playwright.config.ts |
Uses pnpm run dev for the Playwright web server command. |
examples/getting-started/package.json |
Bumps Vite devDependency version. |
examples/getting-started/index.html |
Formatting-only (doctype + CSS formatting). |
examples/getting-started/README.md |
Updates setup/run instructions to vp install + pnpm filtering. |
examples/convert/package.json |
Removes tsc from build script; bumps Vite version; removes bun packageManager. |
examples/convert/index.html |
Formatting-only HTML/CSS and attribute layout changes. |
examples/convert/README.md |
Updates setup/run instructions to vp install + pnpm filtering. |
bun.lock |
Removes Bun lockfile (migration away from Bun). |
biome.json |
Removes Biome configuration (migration to Oxlint/Oxfmt). |
README.md |
Updates developer docs and commands from bun/biome to vp/pnpm; reformats examples. |
CONTRIBUTING.md |
Updates contributing instructions for vp/pnpm and new lint/format tooling. |
AGENTS.md |
Updates agent guidance for vp/pnpm workflows and tooling. |
.gitignore |
Removes Bun lock ignore entry. |
.github/workflows/shared/reporting.md |
Markdown formatting (blank lines) for readability. |
.github/workflows/shared/mcp/serena-ts.md |
Markdown formatting (blank lines) for readability. |
.github/workflows/release.yml |
Replaces bun setup/install/build with vp/pnpm equivalents. |
.github/workflows/duplicate-code-detector.md |
YAML/Markdown formatting adjustments. |
.github/workflows/duplicate-code-detector.lock.yml |
Formatting/quoting normalization in the lock workflow. |
.github/workflows/code-simplifier.md |
YAML/Markdown formatting adjustments. |
.github/workflows/code-simplifier.lock.yml |
Formatting/quoting normalization in the lock workflow. |
.github/workflows/ci.yml |
Updates CI to use vp/pnpm; replaces Biome CI with vp check. |
.changeset/README.md |
Updates changeset command invocation from bunx to pnpm exec. |
Comments suppressed due to low confidence (1)
.github/workflows/release.yml:33
voidzero-dev/setup-vp@v1already installs Node (and sets up caching). The additionalactions/setup-node@v4step reconfigures Node again, which is redundant and can make the runtime/caching behavior harder to reason about. Consider removing the extra setup-node step unless it’s required for a specific reason.
- uses: actions/setup-node@v4
with:
node-version: 24
💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.
| [Vite+](https://viteplus.dev/) handles linting (Oxlint), formatting (Oxfmt), | ||
| and type checking — configured in the root `vite.config.ts`: | ||
|
|
||
| ```bash | ||
| bun run check # Lint + format + import sorting (same as CI) | ||
| bun run lint # Lint only | ||
| bun run format # Auto-format all files | ||
| vp check # Lint + format + type check (same as CI) |
There was a problem hiding this comment.
AGENTS.md states that vp check performs type checking and that Vite+ handles type checking, but the root vite.config.ts disables type checking (typeCheck: false) and CI runs pnpm exec tsc --noEmit separately. Please update this section to match the actual workflow (or enable type checking in the Vite+ config if that’s the intent).
|
|
||
| import { resolve } from "node:path" | ||
| import { createLogger, defineConfig } from "vite" | ||
| import { createLogger, defineConfig } from "vite-plus" |
There was a problem hiding this comment.
Phantom dependency:
"vite-plus" not declared in fidnii/package.json
fidnii/vite.config.ts imports from "vite-plus", but fidnii/package.json only declares "vite": "^8.0.0" (redirected to @voidzero-dev/vite-plus-core via the pnpm override). The "vite-plus" package itself is only present in the root package.json devDependencies.
This currently works via Node.js's upward node_modules traversal (pnpm hoists root-workspace packages into the root node_modules, which child packages can still discover), but it is a phantom dependency from pnpm's perspective. If pnpm isolation is ever tightened (e.g., node-linker=pnp, stricter hoisting rules, or public-hoist-pattern changes), running vite or vp inside fidnii/ would fail with a module-not-found error.
To be explicit, add "vite-plus" to fidnii/package.json's devDependencies:
"devDependencies": {
"@fideus-labs/fizarrita": "^1.4.1",
"@fideus-labs/worker-pool": "^1.0.0",
"@playwright/test": "^1.58.1",
"@types/node": "^20.19.30",
"fflate": "^0.8.2",
"typescript": "^5.9.3",
"vite": "^8.0.0",
"vite-plus": "latest"
}`voidzero-dev/setup-vp@v1` installs the `vp` CLI but does not put `pnpm` on PATH, so all `pnpm exec` calls fail with "command not found". Replace with `vp exec` which is available after setup-vp. Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
There was a problem hiding this comment.
Actionable comments posted: 3
Caution
Some comments are outside the diff and can’t be posted inline due to platform limitations.
⚠️ Outside diff range comments (1)
.github/workflows/duplicate-code-detector.md (1)
173-231:⚠️ Potential issue | 🟡 MinorFix mismatched code fences in the issue template block.
Line 197 closes the 4-backtick block too early, and Line 231 then closes with 3 backticks. This breaks the intended single template code block.
🛠️ Proposed fix
-```` + ``` @@ -```` +```` @@ -``` +````🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed. In @.github/workflows/duplicate-code-detector.md around lines 173 - 231, The template's code-fence markers are mismatched: the block opened with "````markdown" around the "# 🔍 Duplicate Code Detected: [Pattern Name]" section but is closed inconsistently with "````" and "```"; make them consistent by keeping the outer template block using four backticks (open with "````markdown" and close with "````") and ensure any inner example/code samples use triple backticks ("```"). Specifically, replace the premature closing marker that currently breaks the outer block so the outer block is closed with "````" and change the final trailing "```" to "````" while leaving nested code-sample fences as "```".
🧹 Nitpick comments (2)
package.json (1)
22-35: Consider pinningvite-plusversion for reproducibility.Using
"latest"forvite-plusand@voidzero-dev/vite-plus-core@latestin overrides may cause unexpected breakage when new versions are released. Consider pinning to a specific version once the tooling stabilizes.The
pnpm.overridessection correctly aliasesvitetovite-plus-core, ensuring all dependencies use the Vite+ fork.🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed. In `@package.json` around lines 22 - 35, The package.json currently pins "vite-plus" to "latest" and uses "@voidzero-dev/vite-plus-core@latest" in pnpm.overrides which risks non-reproducible builds; update the "vite-plus" entry and the "@voidzero-dev/vite-plus-core@latest" override to specific version numbers (e.g., replace "latest" with a pinned semver like "1.2.3" or a commit/hash), ensuring both the "vite-plus" dependency and the pnpm.overrides entry reference the same stable version to keep installs reproducible.vite.config.ts (1)
9-15: Optional: deduplicate shared ignore patterns to prevent drift.Both
lint.ignorePatternsandfmt.ignorePatternsrepeat the same paths.♻️ Small maintainability refactor
import { defineConfig } from "vite-plus" +const IGNORE_PATTERNS = [ + "dist/**", + "dist-test-page/**", + "node_modules/**", + "playwright-report/**", + "test-results/**", +] + export default defineConfig({ // Oxlint — replaces Biome linting lint: { - ignorePatterns: [ - "dist/**", - "dist-test-page/**", - "node_modules/**", - "playwright-report/**", - "test-results/**", - ], + ignorePatterns: IGNORE_PATTERNS, @@ fmt: { @@ - ignorePatterns: [ - "dist/**", - "dist-test-page/**", - "node_modules/**", - "playwright-report/**", - "test-results/**", - "pnpm-lock.yaml", - ], + ignorePatterns: [...IGNORE_PATTERNS, "pnpm-lock.yaml"], },Also applies to: 54-61
🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed. In `@vite.config.ts` around lines 9 - 15, The lint.ignorePatterns and fmt.ignorePatterns blocks repeat the same paths; refactor by extracting a single shared constant (e.g., IGNORE_PATTERNS) near the top of vite.config.ts and replace both lint.ignorePatterns and fmt.ignorePatterns with that constant so both use the same maintained list (update references in the objects where lint.ignorePatterns and fmt.ignorePatterns are declared).
🤖 Prompt for all review comments with AI agents
Verify each finding against the current code and only fix it if needed.
Inline comments:
In `@examples/convert/package.json`:
- Line 8: Restore package-level type-checking by adding back a tsc-based step:
update the "build" script in package.json (the "build" entry) to either run
"pnpm exec tsc --noEmit" before "vite build" or add a separate "typecheck"
script (e.g., "typecheck": "pnpm exec tsc --noEmit") and have "build" invoke it;
reference the "build" script and the tsc CLI invocation to locate where to
insert the check so local builds run TypeScript type-checking as CI does.
In `@fidnii/package.json`:
- Line 56: The package manifest now depends on "vite": "^8.0.0" but lacks a Node
engine guard; add an "engines": { "node": ">=20.19.0 || >=22.12.0" } (or simply
">=20.19.0") entry to package.json to declare the minimum supported Node version
for Vite 8, update any install or CI validation to respect this engines.node
constraint, and ensure package metadata (e.g., under the package.json root where
"vite" is declared) reflects this engine requirement.
In `@fidnii/vite.config.ts`:
- Around line 64-71: The pack configuration in vite.config.ts should specify an
outExtension so tsdown generates .d.mts files to match package.json; update the
pack block (the object with keys entry, format, dts, sourcemap) to include
outExtension: { dts: '.d.mts' } so declaration files are emitted as .d.mts
instead of the default .d.ts.
---
Outside diff comments:
In @.github/workflows/duplicate-code-detector.md:
- Around line 173-231: The template's code-fence markers are mismatched: the
block opened with "````markdown" around the "# 🔍 Duplicate Code Detected:
[Pattern Name]" section but is closed inconsistently with "````" and "```"; make
them consistent by keeping the outer template block using four backticks (open
with "````markdown" and close with "````") and ensure any inner example/code
samples use triple backticks ("```"). Specifically, replace the premature
closing marker that currently breaks the outer block so the outer block is
closed with "````" and change the final trailing "```" to "````" while leaving
nested code-sample fences as "```".
---
Nitpick comments:
In `@package.json`:
- Around line 22-35: The package.json currently pins "vite-plus" to "latest" and
uses "@voidzero-dev/vite-plus-core@latest" in pnpm.overrides which risks
non-reproducible builds; update the "vite-plus" entry and the
"@voidzero-dev/vite-plus-core@latest" override to specific version numbers
(e.g., replace "latest" with a pinned semver like "1.2.3" or a commit/hash),
ensuring both the "vite-plus" dependency and the pnpm.overrides entry reference
the same stable version to keep installs reproducible.
In `@vite.config.ts`:
- Around line 9-15: The lint.ignorePatterns and fmt.ignorePatterns blocks repeat
the same paths; refactor by extracting a single shared constant (e.g.,
IGNORE_PATTERNS) near the top of vite.config.ts and replace both
lint.ignorePatterns and fmt.ignorePatterns with that constant so both use the
same maintained list (update references in the objects where lint.ignorePatterns
and fmt.ignorePatterns are declared).
ℹ️ Review info
⚙️ Run configuration
Configuration used: Organization UI
Review profile: CHILL
Plan: Pro
Run ID: 09ad6d91-ced3-42a0-ba26-d97674ae5a79
⛔ Files ignored due to path filters (2)
bun.lockis excluded by!**/*.lockpnpm-lock.yamlis excluded by!**/pnpm-lock.yaml
📒 Files selected for processing (32)
.changeset/README.md.github/workflows/ci.yml.github/workflows/code-simplifier.lock.yml.github/workflows/code-simplifier.md.github/workflows/duplicate-code-detector.lock.yml.github/workflows/duplicate-code-detector.md.github/workflows/release.yml.github/workflows/shared/mcp/serena-ts.md.github/workflows/shared/reporting.md.gitignoreAGENTS.mdCONTRIBUTING.mdREADME.mdbiome.jsonexamples/convert/README.mdexamples/convert/index.htmlexamples/convert/package.jsonexamples/getting-started/README.mdexamples/getting-started/index.htmlexamples/getting-started/package.jsonexamples/getting-started/playwright.config.tsfidnii/CHANGELOG.mdfidnii/README.mdfidnii/package.jsonfidnii/playwright.config.tsfidnii/src/ViewportBounds.tsfidnii/test-page/index.htmlfidnii/vite.config.tslefthook.ymlpackage.jsonpnpm-workspace.yamlvite.config.ts
💤 Files with no reviewable changes (3)
- .gitignore
- biome.json
- fidnii/CHANGELOG.md
| "scripts": { | ||
| "dev": "vite", | ||
| "build": "tsc && vite build", | ||
| "build": "vite build", |
There was a problem hiding this comment.
🧩 Analysis chain
🏁 Script executed:
#!/bin/bash
set -euo pipefail
echo "== scripts in examples/convert/package.json =="
rg -n '"(dev|build|typecheck|check)"\s*:' examples/convert/package.json -C1
echo
echo "== type-check plugins/usages in examples/convert/vite.config.ts =="
rg -n 'vite-plugin-checker|rollup-plugin-typescript2|fork-ts-checker|tsc' examples/convert/vite.config.ts -C2 || true
echo
echo "== CI/workflow references for convert package build/typecheck =="
rg -n '@fideus-labs/fidnii-example-convert|examples/convert|typecheck|tsc --noEmit' .github -g '*.yml' -g '*.yaml' -C2 || trueRepository: fideus-labs/fidnii
Length of output: 613
Restore type-checking in the build script.
Removing tsc from the build script (Line 8) eliminates type-checking during local builds. While CI enforces pnpm exec tsc --noEmit at the project level, removing it from the package-level build removes an early safety gate for developers working on this package locally. For consistency and better developer experience, add an explicit typecheck script:
Proposed fix
"scripts": {
"dev": "vite",
- "build": "vite build",
+ "typecheck": "tsc --noEmit",
+ "build": "pnpm run typecheck && vite build",
"generate:colormap-icons": "tsx generate-colormap-icons.ts",
"preview": "vite preview"
},🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.
In `@examples/convert/package.json` at line 8, Restore package-level type-checking
by adding back a tsc-based step: update the "build" script in package.json (the
"build" entry) to either run "pnpm exec tsc --noEmit" before "vite build" or add
a separate "typecheck" script (e.g., "typecheck": "pnpm exec tsc --noEmit") and
have "build" invoke it; reference the "build" script and the tsc CLI invocation
to locate where to insert the check so local builds run TypeScript type-checking
as CI does.
| "fflate": "^0.8.2", | ||
| "typescript": "^5.9.3", | ||
| "vite": "^5.4.21" | ||
| "vite": "^8.0.0" |
There was a problem hiding this comment.
🧩 Analysis chain
🌐 Web query:
What Node.js versions are required by Vite 8 according to the official Vite documentation and release notes?
💡 Result:
Vite 8 requires Node.js 20.19+ or 22.12+.
Citations:
- 1: https://vite.dev/blog/announcing-vite8
- 2: https://npmx.dev/package/vite/v/%5E8.0.0
- 3: https://vite.dev/guide/
- 4: https://github.com/vitejs/vite/blob/main/package.json
- 5: https://www.npmjs.com/package/vite
Add a Node engine guard to match Vite 8's minimum requirements.
Upgrading to vite: ^8.0.0 requires a Node.js engine declaration. Vite 8 requires Node.js 20.19+ (or 22.12+), and without an explicit engines.node constraint, users on unsupported Node versions could encounter install or runtime failures.
🔧 Suggested manifest hardening
{
"name": "@fideus-labs/fidnii",
"version": "0.7.4",
+ "engines": {
+ "node": ">=20.19.0"
+ },
"description": "Render OME-Zarr images in NiiVue with progressive multi-resolution loading",🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.
In `@fidnii/package.json` at line 56, The package manifest now depends on "vite":
"^8.0.0" but lacks a Node engine guard; add an "engines": { "node": ">=20.19.0
|| >=22.12.0" } (or simply ">=20.19.0") entry to package.json to declare the
minimum supported Node version for Vite 8, update any install or CI validation
to respect this engines.node constraint, and ensure package metadata (e.g.,
under the package.json root where "vite" is declared) reflects this engine
requirement.
|
|
||
| // tsdown library packaging configuration | ||
| pack: { | ||
| entry: ["src/index.ts"], | ||
| format: ["esm"], | ||
| dts: true, | ||
| sourcemap: true, | ||
| }, |
There was a problem hiding this comment.
🧩 Analysis chain
🌐 Web query:
vite-plus pack configuration tsdown options
💡 Result:
In Vite+, the vp pack command uses tsdown for building libraries, standalone executables, and publishable packages. Configuration is done in the pack block of vite.config.ts, not in a separate tsdown.config.ts (which is not recommended with Vite+). Example basic configuration: import { defineConfig } from 'vite-plus'; export default defineConfig({ pack: { dts: true, format: ['esm', 'cjs'], sourcemap: true, }, }); The pack options directly map to tsdown's configuration options. Key common options include: - entry: Entry point(s), e.g., ['src/index.ts'] or glob patterns. Defaults to src/index.ts. - dts: boolean | object - Generate TypeScript declaration files (.d.ts). Auto-detected from package.json types field if true. - format: string | string[] - Output formats: 'esm', 'cjs', 'iife', 'umd'. Defaults to ['esm']. - sourcemap: boolean | 'inline' | 'hidden' - Generate source maps. - platform: 'node' | 'neutral' | 'browser' - Target runtime. Defaults to 'node'. - target: string | string[] | false - JS target(s), e.g., 'node18', 'es2020'. - outDir: string - Output directory. Defaults to 'dist'. - exe: boolean - [experimental] Build standalone executable. - clean: boolean - Clean output dir before build. Defaults to true. - plugins: RolldownPlugin[] - tsdown/Rolldown plugins. - unbundle: boolean - Mirror input file structure (no bundling). - tsconfig: string | boolean - Path to tsconfig.json. For full list and details, refer to tsdown docs (https://tsdown.dev/reference/config-options). CLI overrides: vp pack src/index.ts --dts --watch. Usage: vp pack (builds library), vp pack --watch (watch mode).
Citations:
- 1: https://viteplus.dev/config/pack
- 2: https://viteplus.dev/config/
- 3: https://viteplus.dev/guide/pack
- 4: https://tsdown.dev/reference/config-options
- 5: https://tsdown.dev/reference/api/interface.userconfig
- 6: https://tsdown.dev/options/sourcemap
- 7: https://tsdown.dev/reference/cli
- 8: https://main.tsdown.dev/options/dts
🏁 Script executed:
cat -n fidnii/package.json | grep -A 15 '"exports"'Repository: fideus-labs/fidnii
Length of output: 541
🌐 Web query:
tsdown ESM format dts output file extension .d.mts .d.ts
💡 Result:
In tsdown (a library bundler powered by Rolldown), when building in ESM format, the default output for JavaScript files is typically .mjs (or .js if "type": "module" in package.json with fixedExtension), but declaration files (.d.ts) are generated with the .d.ts extension, not .d.mts. This is handled by the rolldown-plugin-dts plugin, which produces .d.ts files alongside JS outputs in a single ESM build process. Examples from tsdown's own published package show files like config.d.mts and index.d.mts in dist/, indicating support for .d.mts generation in some cases (possibly for its own config or when outExtension is customized). To explicitly control the DTS output extension to .d.mts for ESM, use the outExtension option in tsdown config: export default defineConfig({ format: 'esm', outExtension: { dts: '.d.mts' }, // or as a function outExtension({ format }) { return format === 'esm' ? { js: '.mjs', dts: '.d.mts' } : { js: '.cjs', dts: '.d.cts' }; }, dts: true }); This mirrors tsup's approach where users request .d.mts for ESM typings. TypeScript's tsc always emits .d.ts regardless of module format (ESM/CJS), without native .d.mts support unless input files use .mts extensions.
Citations:
- 1: https://tsdown.dev/options/output-format
- 2: https://tsdown.dev/options/dts
- 3: https://main.tsdown.dev/options/dts
- 4: https://github.com/rolldown/tsdown
- 5: https://www.npmjs.com/package/tsdown
- 6: https://github.com/sxzz/rolldown-plugin-dts
- 7: https://registry.npmjs.org/rolldown-plugin-dts
- 8: https://main.tsdown.dev/reference/api/Interface.OutExtensionObject
- 9: support
outExtensionrolldown/tsdown#114
🏁 Script executed:
cat -n fidnii/vite.config.tsRepository: fideus-labs/fidnii
Length of output: 2631
Add outExtension configuration to generate .d.mts declaration files.
The pack configuration currently lacks the outExtension option needed to align with package.json exports. With dts: true, tsdown generates .d.ts files by default, not .d.mts. Since package.json specifies ./dist/index.d.mts, add outExtension: { dts: '.d.mts' } to the pack block to ensure type declarations are generated with the correct extension.
🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.
In `@fidnii/vite.config.ts` around lines 64 - 71, The pack configuration in
vite.config.ts should specify an outExtension so tsdown generates .d.mts files
to match package.json; update the pack block (the object with keys entry,
format, dts, sourcemap) to include outExtension: { dts: '.d.mts' } so
declaration files are emitted as .d.mts instead of the default .d.ts.
There was a problem hiding this comment.
Actionable comments posted: 1
🤖 Prompt for all review comments with AI agents
Verify each finding against the current code and only fix it if needed.
Inline comments:
In @.github/workflows/release.yml:
- Around line 25-28: Replace the mutable action tags with immutable commit SHAs:
change the uses entry "voidzero-dev/setup-vp@v1" to the full 40-character commit
SHA for that action (same pattern for "actions/checkout@v4" and
"actions/setup-node@v4"), updating the workflow to reference the exact commit
instead of the tag; ensure you paste the exact commit SHA string for each action
in the uses field so the release.yml uses pinned, immutable references.
ℹ️ Review info
⚙️ Run configuration
Configuration used: Organization UI
Review profile: CHILL
Plan: Pro
Run ID: a82cabef-ec03-4ed2-87f0-3bc9e11ae7a2
📒 Files selected for processing (2)
.github/workflows/ci.yml.github/workflows/release.yml
🚧 Files skipped from review as they are similar to previous changes (1)
- .github/workflows/ci.yml
| - uses: voidzero-dev/setup-vp@v1 | ||
| with: | ||
| node-version: "24" | ||
| cache: true |
There was a problem hiding this comment.
🧩 Analysis chain
🏁 Script executed:
#!/bin/bash
set -euo pipefail
python - <<'PY'
import re
from pathlib import Path
wf = Path(".github/workflows/release.yml")
text = wf.read_text(encoding="utf-8").splitlines()
pattern = re.compile(r'^\s*-\s*uses:\s*([^@]+)@([^\s#]+)')
sha40 = re.compile(r'^[0-9a-f]{40}$')
for i, line in enumerate(text, 1):
m = pattern.search(line)
if not m:
continue
action, ref = m.group(1), m.group(2)
if not sha40.fullmatch(ref):
print(f"{wf}:{i}: non-SHA ref -> {action}@{ref}")
PYRepository: fideus-labs/fidnii
Length of output: 275
Pin voidzero-dev/setup-vp to a full commit SHA.
Mutable action tags (@v1) in publish workflows create supply-chain risks. Use a full 40-character commit SHA instead.
Suggested change
- - uses: voidzero-dev/setup-vp@v1
+ - uses: voidzero-dev/setup-vp@<full-40-char-commit-sha>Note: actions/checkout@v4 (line 23) and actions/setup-node@v4 (line 30) should also be pinned to commit SHAs for consistency.
🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.
In @.github/workflows/release.yml around lines 25 - 28, Replace the mutable
action tags with immutable commit SHAs: change the uses entry
"voidzero-dev/setup-vp@v1" to the full 40-character commit SHA for that action
(same pattern for "actions/checkout@v4" and "actions/setup-node@v4"), updating
the workflow to reference the exact commit instead of the tag; ensure you paste
the exact commit SHA string for each action in the uses field so the release.yml
uses pinned, immutable references.
Summary
Replaces the entire build toolchain with Vite+ (
vpCLI), unifying package management, linting, formatting, and library packaging under a single tool.vp install)vp lint/vp check)vp fmt/vp check)tsc→ tsdown (viavp pack) — outputs.mjs+.d.mtsbun run/bunx→vp run/pnpm execWhat changed
New files
vite.config.ts(root) — Central config for Oxlint rules, Oxfmt settings, andstagedpre-commit config (replacesbiome.json)pnpm-workspace.yaml— Defines workspace packages (replacesworkspacesin rootpackage.json)pnpm-lock.yaml— pnpm lockfile (replacesbun.lock)Deleted files
biome.json— Replaced by lint/fmt config in rootvite.config.tsbun.lock— Replaced bypnpm-lock.yamlModified files
package.json(root) —packageManager→ pnpm, scripts usevpcommands,pnpm.overridesaliasesviteto@voidzero-dev/vite-plus-corefidnii/package.json— Build script →vp pack, exports updated to.mjs/.d.mtsextensionsfidnii/vite.config.ts— Addedpackconfig block for tsdownexamples/*/package.json— Vite^7.3.1→^8.0.0lefthook.yml— Pre-commit usesvp check --fix, commit-msg usespnpm exec commitlint.github/workflows/ci.yml—oven-sh/setup-bun→voidzero-dev/setup-vp@v1, Node 24, all commands updated.github/workflows/release.yml— Same Bun → Vite+ migrationfidnii/src/ViewportBounds.ts— Added explicitimport type { vec3 }to satisfyconsistent-type-importsruleAGENTS.md,CONTRIBUTING.md,README.md, example READMEs,.changeset/README.md— Allbun/bunx/biomereferences updated tovp/pnpm exec/Oxlint/OxfmtFormatting changes
vp check --fixWhy
Vite+ provides a unified, Rust-based toolchain that combines Vite 8, Oxlint, Oxfmt, and tsdown under a single
vpCLI. This reduces the number of separate tools to configure and maintain, while improving lint/format performance through native Rust implementations.Verification
vp checkpasses clean (lint + format)vp run -r buildsucceeds for all workspace packagesvp devstarts correctly on port 5173vp check --fix) and commit-msg hook (commitlint) both passTest plan
vp install --frozen-lockfileworks in clean checkoutvp run -r buildproduces correct output infidnii/dist/vp run -r test)🤖 Generated with Claude Code
Summary by CodeRabbit