Skip to content

build: migrate from Bun + Biome to Vite+ (pnpm, Oxlint, Oxfmt, tsdown)#118

Open
thewtex wants to merge 2 commits intomainfrom
a115-migrate-from-bun
Open

build: migrate from Bun + Biome to Vite+ (pnpm, Oxlint, Oxfmt, tsdown)#118
thewtex wants to merge 2 commits intomainfrom
a115-migrate-from-bun

Conversation

@thewtex
Copy link
Contributor

@thewtex thewtex commented Mar 25, 2026

Summary

Replaces the entire build toolchain with Vite+ (vp CLI), unifying package management, linting, formatting, and library packaging under a single tool.

  • Package manager: Bun → pnpm (via vp install)
  • Linter: Biome → Oxlint (via vp lint / vp check)
  • Formatter: Biome → Oxfmt (via vp fmt / vp check)
  • Library build: tsctsdown (via vp pack) — outputs .mjs + .d.mts
  • Script runner: bun run / bunxvp run / pnpm exec

What changed

New files

  • vite.config.ts (root) — Central config for Oxlint rules, Oxfmt settings, and staged pre-commit config (replaces biome.json)
  • pnpm-workspace.yaml — Defines workspace packages (replaces workspaces in root package.json)
  • pnpm-lock.yaml — pnpm lockfile (replaces bun.lock)

Deleted files

  • biome.json — Replaced by lint/fmt config in root vite.config.ts
  • bun.lock — Replaced by pnpm-lock.yaml

Modified files

  • package.json (root) — packageManager → pnpm, scripts use vp commands, pnpm.overrides aliases vite to @voidzero-dev/vite-plus-core
  • fidnii/package.json — Build script → vp pack, exports updated to .mjs/.d.mts extensions
  • fidnii/vite.config.ts — Added pack config block for tsdown
  • examples/*/package.json — Vite ^7.3.1^8.0.0
  • lefthook.yml — Pre-commit uses vp check --fix, commit-msg uses pnpm exec commitlint
  • .github/workflows/ci.ymloven-sh/setup-bunvoidzero-dev/setup-vp@v1, Node 24, all commands updated
  • .github/workflows/release.yml — Same Bun → Vite+ migration
  • fidnii/src/ViewportBounds.ts — Added explicit import type { vec3 } to satisfy consistent-type-imports rule
  • AGENTS.md, CONTRIBUTING.md, README.md, example READMEs, .changeset/README.md — All bun/bunx/biome references updated to vp/pnpm exec/Oxlint/Oxfmt

Formatting changes

  • Oxfmt produces slightly different output than Biome for markdown tables and HTML — auto-formatted via vp check --fix

Why

Vite+ provides a unified, Rust-based toolchain that combines Vite 8, Oxlint, Oxfmt, and tsdown under a single vp CLI. This reduces the number of separate tools to configure and maintain, while improving lint/format performance through native Rust implementations.

Verification

  • vp check passes clean (lint + format)
  • vp run -r build succeeds for all workspace packages
  • vp dev starts correctly on port 5173
  • Pre-commit hook (vp check --fix) and commit-msg hook (commitlint) both pass

Test plan

  • CI passes on all platforms (Ubuntu, macOS, Windows)
  • vp install --frozen-lockfile works in clean checkout
  • vp run -r build produces correct output in fidnii/dist/
  • Playwright tests pass (vp run -r test)
  • Dev server starts with COOP/COEP headers on port 5173
  • Release workflow can version and publish via changesets

🤖 Generated with Claude Code

Summary by CodeRabbit

  • Chores
    • Migrated repository tooling from Bun/Biome to Vite+ (vp) and pnpm, updated scripts and packaging to ESM (.mjs/.d.mts)
    • Added PNPM workspace config and new Vite+ configuration for build/lint/format
  • CI
    • Updated CI workflows to use Node 24 and VP-based install/run commands
  • Documentation
    • Updated READMEs, CONTRIBUTING, examples, and workflow docs to reflect new commands and formatting changes

…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>
@cloudflare-workers-and-pages
Copy link

cloudflare-workers-and-pages bot commented Mar 25, 2026

Deploying convert-fidnii with  Cloudflare Pages  Cloudflare Pages

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

View logs

Copilot AI review requested due to automatic review settings March 25, 2026 20:39
@coderabbitai
Copy link

coderabbitai bot commented Mar 25, 2026

📝 Walkthrough

Walkthrough

The 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

Cohort / File(s) Summary
CI Workflows
\.github/workflows/ci.yml, \.github/workflows/release.yml
Replaced Bun/Node setup with voidzero-dev/setup-vp@v1 (Node 24) and migrated install/build/test/changeset commands from bun/bunx to vp/pnpm exec equivalents; updated Playwright install commands and preserved OS branches.
Workflow formatting & docs
\.github/workflows/code-simplifier.lock.yml, \.github/workflows/duplicate-code-detector.lock.yml, \.github/workflows/code-simplifier.md, \.github/workflows/duplicate-code-detector.md, \.github/workflows/shared/...
YAML cron indentation fixed; environment variable quoting standardized; whitespace/blank-line and markdown formatting adjustments; non-functional reformatting in workflow docs.
Root package & workspace
package.json, pnpm-workspace.yaml, \.gitignore, lefthook.yml
Switched package manager to pnpm, added pnpm-workspace.yaml, removed packageManager/workspaces from manifests, removed bun.lockb from .gitignore, and updated pre-commit/commit-msg hooks to vp/pnpm exec.
Build/lint config
biome.json (deleted), vite.config.ts (new), vite.config.ts (root)
Removed Biome config; added vite.config.ts (vite-plus) with lint (Oxlint), fmt (Oxfmt), staged checks, TypeScript rule overrides, and a new pack config for library packaging.
Docs & guides
README.md, CONTRIBUTING.md, AGENTS.md, .changeset/README.md, \.github/workflows/shared/reporting.md
Rewrote command examples and prose to reflect Vite+/vp/pnpm toolchain (vp, pnpm exec, vp check/fmt), adjusted markdown spacing and examples.
Examples: convert
examples/convert/package.json, examples/convert/README.md, examples/convert/index.html
Removed packageManager field, changed build script to vite build, bumped vite to ^8.0.0; README/dev commands switched to vp/pnpm; HTML doctype and markup formatting updated.
Examples: getting-started
examples/getting-started/package.json, examples/getting-started/README.md, examples/getting-started/index.html, examples/getting-started/playwright.config.ts
Bumped vite to ^8.0.0; dev/test commands updated to use vp/pnpm; Playwright webServer command switched to pnpm run dev; docs/code snippet formatting adjusted.
Fidnii package & config
fidnii/package.json, fidnii/vite.config.ts, fidnii/playwright.config.ts
Removed packageManager, changed entrypoints (.js.mjs, .d.ts.d.mts), replaced tsc build with vp pack, bumped vite and updated vite imports to vite-plus; Playwright command updated to pnpm run dev.
Fidnii source & docs
fidnii/src/ViewportBounds.ts, fidnii/README.md, fidnii/test-page/index.html, fidnii/CHANGELOG.md
Added type-only vec3 import and adjusted cast; example docs reformatted (semicolon removals); HTML doctype lowercased; minor changelog blank-line removals.
Misc formatting
examples/*, other HTML/docs`
Multiple HTML, CSS, and markdown formatting changes (doctype lowercasing, whitespace, attribute/markup reflow) across examples and docs; no behavioral code changes.

Estimated code review effort

🎯 4 (Complex) | ⏱️ ~60 minutes

Possibly related PRs

  • build: migrate from pnpm to bun #110: Prior tooling/workspace migration touching CI, package manifests, workflows, and hooks—strongly related to package-manager and CI/tooling changes in this PR.

Suggested reviewers

  • hanayik

Poem

🐰 Hop hop, the tooling has changed,
Bun to Vite+, the paths rearranged,
vp and pnpm now lead the way,
Docs and CI hopped into play,
A little rabbit cheers—hooray! 🥕

🚥 Pre-merge checks | ✅ 3
✅ Passed checks (3 passed)
Check name Status Explanation
Description Check ✅ Passed Check skipped - CodeRabbit’s high-level summary is enabled.
Title check ✅ Passed The title accurately describes the primary changeset: migrating the build toolchain from Bun + Biome to Vite+ with pnpm, Oxlint, Oxfmt, and tsdown.
Docstring Coverage ✅ Passed Docstring coverage is 100.00% which is sufficient. The required threshold is 80.00%.

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

✨ Finishing Touches
🧪 Generate unit tests (beta)
  • Create PR with unit tests
  • Commit unit tests in branch a115-migrate-from-bun

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

@thewtex thewtex changed the title Migrate from bun and biome to vite+ (vibe-kanban) build: migrate from Bun + Biome to Vite+ (pnpm, Oxlint, Oxfmt, tsdown) Mar 25, 2026
@greptile-apps
Copy link

greptile-apps bot commented Mar 25, 2026

Greptile Summary

This PR completes a toolchain migration from Bun + Biome to Vite+ (vp) + pnpm workspaces + Oxlint/Oxfmt. The change touches CI workflows, lock files, package manifests, linting/formatting configuration, pre-commit hooks, and all developer documentation across the monorepo.

Key changes:

  • All GitHub Actions workflows replace oven-sh/setup-bun@v2 with voidzero-dev/setup-vp@v1; all bun/bunx commands are replaced with vp/pnpm exec equivalents, and Node.js is upgraded from 22 → 24.
  • biome.json is deleted; linting (Oxlint) and formatting (Oxfmt) configuration is consolidated into the new root vite.config.ts.
  • bun.lock is removed and pnpm-lock.yaml is added; pnpm-workspace.yaml defines the monorepo structure.
  • vite in fidnii/ is aliased to npm:@voidzero-dev/vite-plus-core@latest via pnpm.overrides.
  • AGENTS.md, CONTRIBUTING.md, and README.md are all updated to reflect the new commands.

Issues found:

  • fidnii/vite.config.ts imports "vite-plus" which is not declared in fidnii/package.json's devDependencies — only in the root package.json. This phantom dependency resolves today via Node.js node_modules traversal, but would break under stricter pnpm isolation.
  • "vite-plus": "latest" and the pnpm.overrides entry for vite both use floating latest tags, which introduces non-reproducibility risk when the lockfile is regenerated.
  • release.yml retains a redundant actions/setup-node@v4 step immediately after setup-vp (both targeting Node 24), with no registry-url, making its purpose ambiguous.

Confidence Score: 3/5

  • Mostly safe migration but contains a phantom dependency in fidnii/vite.config.ts that could break under stricter pnpm isolation and unpinned latest toolchain versions.
  • The migration is comprehensive and consistent across CI, documentation, and configuration. However, the phantom "vite-plus" dependency in fidnii/vite.config.ts (not declared in fidnii/package.json) is a correctness risk that could cause vite dev to fail in the fidnii/ package under certain pnpm configurations. The use of latest for core toolchain packages also reduces build reproducibility. These issues prevent a higher confidence score despite the broad correctness of the migration.
  • fidnii/vite.config.ts and fidnii/package.json (phantom vite-plus dependency), package.json (unpinned latest versions), .github/workflows/release.yml (redundant Node setup).

Important Files Changed

Filename Overview
.github/workflows/ci.yml Consistently replaces all oven-sh/setup-bun@v2 + actions/setup-node@v4 pairs with voidzero-dev/setup-vp@v1, upgrades Node to 24, and replaces bun/bunx commands with vp/pnpm exec equivalents throughout all jobs.
.github/workflows/release.yml Replaces setup-bun with setup-vp, but retains a redundant actions/setup-node@v4 step immediately after (also Node 24) with no registry-url, making its purpose unclear; all bun/bunx commands correctly replaced.
package.json Switches package manager to pnpm@10.12.1, adds vite-plus: "latest" devDependency, and adds pnpm.overrides aliasing vite to npm:@voidzero-dev/vite-plus-core@latest; both use floating latest tags which may produce non-reproducible builds on lockfile regeneration.
fidnii/vite.config.ts Imports createLogger and defineConfig from "vite-plus", which is not declared in fidnii/package.json; this phantom dependency works via Node.js parent-directory node_modules lookup but could break under stricter pnpm isolation settings.
vite.config.ts New root-level Vite+ config replacing biome.json; correctly configures Oxlint (replacing Biome linting), Oxfmt (replacing Biome formatting), and staged-file pre-commit checking with consistent style settings.
fidnii/package.json Updates build script to vp pack, version bumped to 0.7.4, and vite devDependency upgraded from ^5.4.21 to ^8.0.0 (effectively aliased to @voidzero-dev/vite-plus-core via root override); vite-plus itself is absent from this package's deps despite being imported in the local vite.config.ts.
biome.json Deleted as part of the migration to Vite+/Oxlint/Oxfmt; all configuration has been migrated to the root vite.config.ts.
lefthook.yml Pre-commit hook updated from biome check --write to vp check --fix; commitlint hook now uses pnpm exec commitlint; changes are consistent with the toolchain migration.
fidnii/src/ViewportBounds.ts Import ordering adjusted to conform to Oxfmt style (external before internal, import type separated); no functional logic changes.
pnpm-workspace.yaml New file declaring the pnpm workspace packages (fidnii and examples/*); straightforward migration from bun's workspace configuration.
AGENTS.md Fully updated from bun/Biome to Vite+/pnpm commands; build, lint, format, type-check, test, and git hook documentation all correctly reflect the new toolchain.

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
Loading

Reviews (1): Last reviewed commit: "build: migrate from bun + biome to vite+..." | Re-trigger Greptile

Copy link
Contributor

Copilot AI left a comment

Choose a reason for hiding this comment

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

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-vp and replace bun/bunx commands with vp/pnpm exec.
  • Update the fidnii package build pipeline to vp 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@v1 already installs Node (and sets up caching). The additional actions/setup-node@v4 step 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.

Comment on lines +26 to +30
[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)
Copy link

Copilot AI Mar 25, 2026

Choose a reason for hiding this comment

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

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).

Copilot uses AI. Check for mistakes.

import { resolve } from "node:path"
import { createLogger, defineConfig } from "vite"
import { createLogger, defineConfig } from "vite-plus"
Copy link

Choose a reason for hiding this comment

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

P2 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>
Copy link

@coderabbitai coderabbitai bot left a comment

Choose a reason for hiding this comment

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

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 | 🟡 Minor

Fix 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 pinning vite-plus version for reproducibility.

Using "latest" for vite-plus and @voidzero-dev/vite-plus-core@latest in overrides may cause unexpected breakage when new versions are released. Consider pinning to a specific version once the tooling stabilizes.

The pnpm.overrides section correctly aliases vite to vite-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.ignorePatterns and fmt.ignorePatterns repeat 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

📥 Commits

Reviewing files that changed from the base of the PR and between 846ffc9 and 2f1029e.

⛔ Files ignored due to path filters (2)
  • bun.lock is excluded by !**/*.lock
  • pnpm-lock.yaml is 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
  • .gitignore
  • AGENTS.md
  • CONTRIBUTING.md
  • README.md
  • biome.json
  • examples/convert/README.md
  • examples/convert/index.html
  • examples/convert/package.json
  • examples/getting-started/README.md
  • examples/getting-started/index.html
  • examples/getting-started/package.json
  • examples/getting-started/playwright.config.ts
  • fidnii/CHANGELOG.md
  • fidnii/README.md
  • fidnii/package.json
  • fidnii/playwright.config.ts
  • fidnii/src/ViewportBounds.ts
  • fidnii/test-page/index.html
  • fidnii/vite.config.ts
  • lefthook.yml
  • package.json
  • pnpm-workspace.yaml
  • vite.config.ts
💤 Files with no reviewable changes (3)
  • .gitignore
  • biome.json
  • fidnii/CHANGELOG.md

"scripts": {
"dev": "vite",
"build": "tsc && vite build",
"build": "vite build",
Copy link

Choose a reason for hiding this comment

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

⚠️ Potential issue | 🟠 Major

🧩 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 || true

Repository: 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"
Copy link

Choose a reason for hiding this comment

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

⚠️ Potential issue | 🟠 Major

🧩 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:


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.

Comment on lines +64 to +71

// tsdown library packaging configuration
pack: {
entry: ["src/index.ts"],
format: ["esm"],
dts: true,
sourcemap: true,
},
Copy link

Choose a reason for hiding this comment

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

⚠️ Potential issue | 🔴 Critical

🧩 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:


🏁 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:


🏁 Script executed:

cat -n fidnii/vite.config.ts

Repository: 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.

Copy link

@coderabbitai coderabbitai bot left a comment

Choose a reason for hiding this comment

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

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

📥 Commits

Reviewing files that changed from the base of the PR and between 2f1029e and 70a8669.

📒 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

Comment on lines +25 to +28
- uses: voidzero-dev/setup-vp@v1
with:
node-version: "24"
cache: true
Copy link

Choose a reason for hiding this comment

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

⚠️ Potential issue | 🟠 Major

🧩 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}")
PY

Repository: 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.

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.

2 participants