feat(cli): Rsbuild template detection and scaffolding in arkenv init - #1809
Conversation
|
Run failed. View the logs →
|
🦋 Changeset detectedLatest commit: f15f377 The changes in this PR will be included in the next version bump. This PR includes changesets to release 1 package
Not sure what this means? Click here to learn what changesets are. Click here if you're a maintainer who wants to add another changeset to this PR |
|
@pullfrog review |
There was a problem hiding this comment.
ℹ️ Minor suggestions only — clean implementation, two rough edges worth a look.
Reviewed changes — adds Rsbuild as a first-class arkenv init target: framework detection via @rsbuild/core deps and rsbuild.config.* files, a magicast-based transformRsbuildConfig/bootstrapRsbuildConfig mutation pipeline, @arkenv/rsbuild-plugin dependency injection, PUBLIC_ default client prefix, an Rsbuild select option, executor wiring, docs, a changeset, and unit/integration tests across the scanner, transformer, workspace, planner, and executor.
- Framework detection — project scanner, adapter, legacy
Workspace, and prompt options all accept"rsbuild". - Config bootstrap — injects
arkenvRsbuildPlugin()intodefineConfig({...})and plain-object configs with idempotency incl. aliased imports, plus graceful failures for callback forms. - Scaffold strategy —
rsbuildStrategyadds@arkenv/rsbuild-plugin, usesPUBLIC_client prefix (matching the plugin's own default), and plans the simple schema file. - Executor + ports —
findRsbuildConfig/bootstrapRsbuildConfigwired throughWorkspacePortwith human-readable reporting. - Verification — all 170
arkenvpackage tests pass (detector, bootstrapper, workspace integration, planner, executor) andpnpm typecheckis clean.
ℹ️ TanStack Start projects can't reach the new Rsbuild detection
detectFramework returns "vite" for any project with @tanstack/* dependencies before the newly added @rsbuild/core / rsbuild.config.* checks run (packages/arkenv/src/adapters/node-project-scanner/utils/detector.ts:41-47). A TanStack Start app bundled with Rsbuild — exactly the audience @arkenv/rsbuild-plugin's own changeset calls out — will still be scaffolded with @arkenv/vite-plugin and told there's no Vite config. The repo's own TanStack example uses vite.config.ts, so the current ordering is defensible; it's just worth a decision on whether rsbuild.config.* presence should outrank the TanStack default now that the Rsbuild path exists. Not blocking.
Technical details
# TanStack Start ordering vs Rsbuild detection
## Affected sites
- packages/arkenv/src/adapters/node-project-scanner/utils/detector.ts:41-43 — `@tanstack/*` deps force-return `"vite"` before the rsbuild check at :47.
## Required outcome
- Decide whether TanStack Start apps built on Rsbuild (rsbuild.config.* present, no vite.config) should be detected as `rsbuild` and scaffolded with `@arkenv/rsbuild-plugin`.
## Open questions for the human
- Is `@arkenv/vite-plugin` functional in an Rsbuild-bundled TanStack Start app? If not, the current ordering produces a broken recommendation for that subset.DeepSeek Flash (free via Pullfrog for OSS) | 𝕏
|
…d of whole-file regex
@arkenv/agent-plugin
arkenv
@arkenv/build
@arkenv/bun-plugin
@arkenv/core
@arkenv/fumadocs-ui
@arkenv/nextjs
@arkenv/nuxt
@arkenv/rsbuild-plugin
@arkenv/standard
@arkenv/tanstack-addon
@arkenv/vite-plugin
commit: |
|
@pullfrog review |
There was a problem hiding this comment.
ℹ️ No blocking issues — the fix cleanly closes the unregistered-import gap from the prior review. One rough edge inline.
Reviewed changes — commit 1ec36d17 replaces the whole-file regex presence check in transformRsbuildConfig with a plugins-array AST scan and adds alias-aware injection, with two targeted tests.
- Plugin-presence AST check —
hasPluginnow scansconfig.pluginsfor function-calls / bare identifiers bound to a name imported from@arkenv/rsbuild-plugin, instead of regex-matching the entire file, so an unregistered import no longer short-circuits injection. - Alias-aware injection — when an unregistered import exists, the injected
plugin()call reuses the import's local (alias) binding and skips re-adding the import; the__ARK_PLUGIN__(:name)placeholder scheme resolves names post-generation. - Tests — added "injects plugin into plugins array even if import already exists but is unregistered" and the aliased variant, both of which fail against the previous implementation. All 43 bootstrapper tests pass locally.
DeepSeek Flash (free via Pullfrog for OSS) | 𝕏
There was a problem hiding this comment.
ℹ️ Minor suggestions inline. Two rough edges; nothing blocking.
Reviewed changes
- Rsbuild framework detection —
detector.tsandWorkspace.detectFrameworknow returnrsbuildfor@rsbuild/coredeps andrsbuild.config.*files; the detector, workspace, and scanner ports all gained the new union member. - Rsbuild config bootstrapping —
transformRsbuildConfiguses a magicast AST round-trip with a placeholder-then-regex pass to injectarkenvRsbuildPlugin(), with import-aware (alias-tolerant) idempotency and an explicit refusal for thedefineConfig(callback)form;findRsbuildConfig/bootstrapRsbuildConfigwere added to the workspace port. - Scaffold planning + strategy — a new
rsbuildstrategy (PUBLIC_client prefix,@arkenv/rsbuild-plugindependency, arktype peer), an interactive-prompt entry, and an executor bootstrap branch wired in. - Tests + docs + changeset — comprehensive new unit/integration coverage (transform shapes, idempotency including aliased imports, detection, planning, executor),
init.mdxupdated,arkenvminor changeset.
I ran the six touched suites (172 tests) after building the @repo/utils workspace dependency — all pass. I also probed shapes the suite doesn't cover directly: injection into a non-empty plugins array works and preserves existing entries, output of a bootstrap is idempotent under a second pass, and comments survive the magicast round-trip.
ℹ️ Nitpicks
- No test for a non-empty
pluginsarray — everypluginsfixture in the suite is[]or a single plugin. Injecting prepended and preserving existing entries (e.g.pluginReact()) is the most common real-world shape; I confirmed it works, so pinning it would be cheap insurance against the placeholder approach regressing. - Populated configs get re-indented — on a config with
server/tools/outputsections, the magicast round-trip re-indents nested blocks (valid output, but a noisy git diff). Inherited from the existing Vite/Nuxt bootstrappers, but worth knowing since Rsbuild configs are more commonly populated than fresh Vite ones.
DeepSeek Flash (free via Pullfrog for OSS) | 𝕏
|
Two findings from my review that should have been inline anchors but landed in the review body instead — anchored here for reference: 1. Rsbuild's documented config loader order is 2.
Neither blocks merge; the full summary is in the review.
|
There was a problem hiding this comment.
✅ No new issues found — the commit cleanly closes the remaining
existingImportgap from the prior review, with solid regression coverage.
Reviewed changes — commit f15f377d makes existingImport selection in transformRsbuildConfig plugin-aware and adds two regression tests.
- Plugin-binding preference —
existingImportnow filters@arkenv/rsbuild-pluginimports and prefers the binding whoseimportedisarkenvRsbuildPluginordefault, falling back to the first import only when no plugin binding exists. A config importingtype RsbuildTransformOptionsahead of the plugin no longer injects the type as the plugin call. - Type-before-plugin regression test — pins that
import { type RsbuildTransformOptions, arkenvRsbuildPlugin }injectsarkenvRsbuildPlugin()and neverRsbuildTransformOptions(); this fails against the prior implementation. - Non-empty plugins array coverage — new test asserts injection into
plugins: [pluginReact()]preserves the existing entry alongside the injected plugin, closing the coverage gap flagged in the prior review.
Verified: all 45 bootstrapper tests pass, node-workspace/scanner suites (111 tests) pass, and pnpm typecheck --filter arkenv is clean.
DeepSeek Flash (free via Pullfrog for OSS) | 𝕏

Fixes #1800
Summary
arkenv initvia@rsbuild/coredependencies andrsbuild.config.*files.@arkenv/rsbuild-plugindependency injection andrsbuild.config.*AST bootstrapping withmagicast.PUBLIC_for Rsbuild projects.arkenv.