fix(create-nextly-app): make the plugin template scaffold work end to end - #308
fix(create-nextly-app): make the plugin template scaffold work end to end#308aqib-rx wants to merge 23 commits into
Conversation
|
Warning Review limit reached
Next review available in: 47 minutes Enable usage-based reviews in Billing to review now. Otherwise, wait until the next included review is available. How can I continue?After more reviews become available, a review can be triggered using the To avoid repeated limits, reduce automatic review volume by pausing incremental auto-reviews earlier, using label-based review opt-in, excluding WIP or generated PR titles, or requesting reviews manually when the PR is ready. If your team needs uninterrupted high-volume reviews, an organization admin can enable usage-based reviews. How do review limits work?CodeRabbit enforces per-developer PR review limits for each organization. Most developers receive the normal plan review availability. For paid Pro and Pro+ PR reviews, CodeRabbit uses adaptive limits for sustained high-volume activity. When a developer's recent PR review activity reaches the 95th percentile or higher among CodeRabbit users, additional reviews become available more gradually as earlier reviews age out of the rolling window. Please refer docs for additional details. Review details⚙️ Run configurationConfiguration used: Path: .coderabbit.yaml Review profile: CHILL Plan: Pro Plus Run ID: 📒 Files selected for processing (4)
📝 WalkthroughWalkthroughThe CLI discovers templates dynamically and supports bundled plugin scaffolding. Plugin creation now enforces fresh-project constraints, prepares environment files, generates semver-safe dependencies, seeds development admin access, wires the admin page, and validates generated output. ChangesPlugin scaffolding
Estimated code review effort: 3 (Moderate) | ~25 minutes Sequence Diagram(s)sequenceDiagram
participant CLI
participant createNextly
participant PluginTemplate
participant DevInstrumentation
participant NextlyServices
participant AdminPage
CLI->>createNextly: validate and scaffold plugin project
createNextly->>PluginTemplate: copy bundled template
PluginTemplate-->>createNextly: create dev/.env and restore .gitignore
DevInstrumentation->>NextlyServices: seed permissions and super admin
AdminPage->>AdminPage: render ErrorBoundary and QueryProvider around RootLayout
Suggested labels: Suggested reviewers: 🚥 Pre-merge checks | ✅ 5✅ Passed checks (5 passed)
✨ Finishing Touches📝 Generate docstrings
🧪 Generate unit tests (beta)
Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out. Comment |
@nextlyhq/adapter-drizzle
@nextlyhq/adapter-mysql
@nextlyhq/adapter-postgres
@nextlyhq/adapter-sqlite
@nextlyhq/admin
@nextlyhq/admin-css
@nextlyhq/blocks-engine
create-nextly-app
nextly
@nextlyhq/plugin-form-builder
@nextlyhq/plugin-page-builder
@nextlyhq/plugin-sdk
@nextlyhq/plugin-seo
@nextlyhq/storage-s3
@nextlyhq/storage-uploadthing
@nextlyhq/storage-vercel-blob
@nextlyhq/ui
commit: |
Greptile SummaryThe PR completes the plugin-template scaffolding flow and addresses the previously reported permission-seeding race.
Confidence Score: 5/5The PR appears safe to merge. No blocking failure remains in the fix for the previously reported Super Admin permission-seeding race.
|
| Filename | Overview |
|---|---|
| templates/plugin/dev/instrumentation.ts | Adds development-only user and permission seeding with a second reconciliation pass that safely covers the previously reported initialization race. |
| packages/create-nextly-app/src/create-nextly.ts | Adds plugin-specific project handling and selects bundled versus live templates according to explicit source overrides. |
| packages/create-nextly-app/src/utils/template.ts | Generates valid plugin peer ranges and materializes the embedded playground environment during scaffolding. |
| packages/create-nextly-app/src/lib/templates.ts | Centralizes bundled-template selection rules for blank and plugin scaffolds. |
| templates/plugin/src/plugin.test.ts | Updates the generated plugin test to the current harness lifecycle and Direct API signatures. |
Reviews (4): Last reviewed commit: "Merge remote-tracking branch 'origin/mai..." | Re-trigger Greptile
There was a problem hiding this comment.
Actionable comments posted: 3
🧹 Nitpick comments (2)
packages/create-nextly-app/src/utils/template.ts (1)
670-670: 📐 Maintainability & Code Quality | 🔵 Trivial | ⚡ Quick winDocument the registry-backed error output.
Add a short comment explaining that the registry keeps this message current as templates are added.
As per coding guidelines, “Every code change must include a comment explaining what the code does and why.”
🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the rest with a brief reason, keep changes minimal, and validate. In `@packages/create-nextly-app/src/utils/template.ts` at line 670, Add a concise comment next to the registry-backed “Template not found” error in the template lookup logic, explaining that getAvailableTemplateNames() keeps the listed templates current as new templates are added.Source: Coding guidelines
packages/create-nextly-app/src/cli.ts (1)
37-38: 📐 Maintainability & Code Quality | 🔵 Trivial | ⚡ Quick winKeep
--helpsynchronized with template validation.Line 37 hardcodes template names, while Lines 103-105 use the registry. Newly registered templates will be accepted but omitted from CLI help.
Proposed fix
+ // Keep CLI help aligned with registry-backed template validation. - .option("-t, --template <template>", "Project template (blank, blog, plugin)") + .option( + "-t, --template <template>", + `Project template (${getAvailableTemplateNames().join(", ")})` + )🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the rest with a brief reason, keep changes minimal, and validate. In `@packages/create-nextly-app/src/cli.ts` around lines 37 - 38, Update the Commander option definition for --template to derive its listed template names from the same registry used by the validation logic around lines 103-105, rather than hardcoding them. Ensure newly registered templates automatically appear in --help while preserving the existing option description and validation behavior.
🤖 Prompt for all review comments with AI agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.
Inline comments:
In `@packages/create-nextly-app/src/create-nextly.ts`:
- Around line 358-374: Update the bundled-template selection condition near
usesBundledPluginTemplate to include the blank project type only when
options.branch is main (or unset), so a non-main --branch always reaches
resolveTemplateSource(). Add a regression case covering --template blank with a
non-main branch and verify it resolves the requested branch rather than using
the bundled scaffold.
In `@templates/plugin/dev/instrumentation.ts`:
- Around line 16-28: Restrict the seeding guard in
templates/plugin/dev/instrumentation.ts (lines 16-28) to NODE_ENV ===
"development" or the established explicit local-playground flag, rather than
every non-production environment; keep seedPermissions and seedSuperAdmin
unchanged. In templates/plugin/README.md (lines 14-16), retain the existing
dev-only credential and auto-login documentation, with no direct content change
required unless needed to match the enforced guard.
In `@templates/plugin/src/plugin.test.ts`:
- Around line 22-31: Add a concise nearby comment around the create and findByID
calls explaining that the Direct API uses object-shaped arguments and that the
generated item ID is converted to a string for the lookup. Keep the test
behavior and API calls unchanged.
---
Nitpick comments:
In `@packages/create-nextly-app/src/cli.ts`:
- Around line 37-38: Update the Commander option definition for --template to
derive its listed template names from the same registry used by the validation
logic around lines 103-105, rather than hardcoding them. Ensure newly registered
templates automatically appear in --help while preserving the existing option
description and validation behavior.
In `@packages/create-nextly-app/src/utils/template.ts`:
- Line 670: Add a concise comment next to the registry-backed “Template not
found” error in the template lookup logic, explaining that
getAvailableTemplateNames() keeps the listed templates current as new templates
are added.
🪄 Autofix (Beta)
Fix all unresolved CodeRabbit comments on this PR:
- Push a commit to this branch (recommended)
- Create a new PR with the fixes
ℹ️ Review info
⚙️ Run configuration
Configuration used: Path: .coderabbit.yaml
Review profile: CHILL
Plan: Pro Plus
Run ID: a44cd578-2453-4d05-a5f2-ac6c7ca50688
⛔ Files ignored due to path filters (1)
.changeset/plugin-template-scaffold-fixes.mdis excluded by!.changeset/**
📒 Files selected for processing (9)
packages/create-nextly-app/src/__tests__/scaffold-plugin.test.tspackages/create-nextly-app/src/cli.tspackages/create-nextly-app/src/create-nextly.tspackages/create-nextly-app/src/utils/template.tstemplates/plugin/README.mdtemplates/plugin/dev/.env.exampletemplates/plugin/dev/instrumentation.tstemplates/plugin/dev/src/app/admin/[[...params]]/page.tsxtemplates/plugin/src/plugin.test.ts
There was a problem hiding this comment.
💡 Codex Review
Here are some automated review suggestions for this pull request.
Reviewed commit: e376185dba
ℹ️ About Codex in GitHub
Codex has been enabled to automatically review pull requests in this repo. Reviews are triggered when you
- Open a pull request for review
- Mark a draft as ready
- Comment "@codex review".
If Codex has suggestions, it will comment; otherwise it will react with 👍.
When you sign up for Codex through ChatGPT, Codex can also answer questions or update the PR, like "@codex address that feedback".
There was a problem hiding this comment.
💡 Codex Review
Here are some automated review suggestions for this pull request.
Reviewed commit: 5869983d1d
ℹ️ About Codex in GitHub
Codex has been enabled to automatically review pull requests in this repo. Reviews are triggered when you
- Open a pull request for review
- Mark a draft as ready
- Comment "@codex review".
If Codex has suggestions, it will comment; otherwise it will react with 👍.
When you sign up for Codex through ChatGPT, Codex can also answer questions or update the PR, like "@codex address that feedback".
There was a problem hiding this comment.
💡 Codex Review
Here are some automated review suggestions for this pull request.
Reviewed commit: ebc7d2c585
ℹ️ About Codex in GitHub
Codex has been enabled to automatically review pull requests in this repo. Reviews are triggered when you
- Open a pull request for review
- Mark a draft as ready
- Comment "@codex review".
If Codex has suggestions, it will comment; otherwise it will react with 👍.
When you sign up for Codex through ChatGPT, Codex can also answer questions or update the PR, like "@codex address that feedback".
…hannel drift Bundled templates now carry .gitignore under the publish-safe name gitignore: npm's packer strips dotted .gitignore files from tarballs, so published-CLI scaffolds silently lost their ignore rules — including for the materialized dev/.env. The build renames on copy and the scaffolder renames back. Plugin scaffolds resolve the Nextly family from the alpha train (the template ships inside the CLI, so its generated test and dev playground exercise current plugin-sdk/admin APIs the lagging latest tag may lack), with peer ranges still falling back to valid semver. Under --use-yalc the generator omits Nextly-family devDeps and the installer yalc-adds before the first install, so the local-package flow never fetches published Nextly packages it is about to replace.
There was a problem hiding this comment.
Actionable comments posted: 1
🧹 Nitpick comments (1)
packages/create-nextly-app/tsup.config.ts (1)
23-32: 🚀 Performance & Scalability | 🔵 Trivial | ⚡ Quick winMirror the
node_modules/.gitskip fromrestoreBundledGitignores.
restoreBundledGitignores(packages/create-nextly-app/src/utils/template.ts) explicitly skipsnode_modulesand.gitwhen recursing to renamegitignore. This packing-time counterpart doesn't, so if a bundled template directory happens to contain a localnode_modules(e.g., from testing thedev/playground before building the CLI), the walk needlessly recurses into it.♻️ Proposed fix
function renameGitignoresForPacking(dir: string): void { for (const entry of readdirSync(dir, { withFileTypes: true })) { const full = path.join(dir, entry.name); if (entry.isDirectory()) { + if (entry.name === "node_modules" || entry.name === ".git") continue; renameGitignoresForPacking(full); } else if (entry.name === ".gitignore") { renameSync(full, path.join(dir, "gitignore")); } } }🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the rest with a brief reason, keep changes minimal, and validate. In `@packages/create-nextly-app/tsup.config.ts` around lines 23 - 32, Update renameGitignoresForPacking to skip entries named node_modules or .git before recursing, matching the existing restoreBundledGitignores behavior; continue renaming .gitignore files and traversing other directories unchanged.
🤖 Prompt for all review comments with AI agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.
Inline comments:
In `@packages/create-nextly-app/src/__tests__/scaffold-plugin.test.ts`:
- Around line 81-91: Update the peerDependencies validation in
scaffold-plugin.test.ts to parse each complete spec as a valid semver range
rather than checking only its first character. Ensure invalid values such as
^latest, >=alpha, and 1not-a-version fail while legitimate peer range
expressions remain accepted.
---
Nitpick comments:
In `@packages/create-nextly-app/tsup.config.ts`:
- Around line 23-32: Update renameGitignoresForPacking to skip entries named
node_modules or .git before recursing, matching the existing
restoreBundledGitignores behavior; continue renaming .gitignore files and
traversing other directories unchanged.
🪄 Autofix (Beta)
Fix all unresolved CodeRabbit comments on this PR:
- Push a commit to this branch (recommended)
- Create a new PR with the fixes
ℹ️ Review info
⚙️ Run configuration
Configuration used: Path: .coderabbit.yaml
Review profile: CHILL
Plan: Pro Plus
Run ID: 4e6fc761-e088-4f69-bc95-fc79f3254e1e
⛔ Files ignored due to path filters (1)
.changeset/plugin-template-scaffold-fixes.mdis excluded by!.changeset/**
📒 Files selected for processing (5)
packages/create-nextly-app/src/__tests__/scaffold-plugin.test.tspackages/create-nextly-app/src/__tests__/template-channel.test.tspackages/create-nextly-app/src/installers/dependencies.tspackages/create-nextly-app/src/utils/template.tspackages/create-nextly-app/tsup.config.ts
… to the local store Yalc rewrites workspace:* inter-package ranges to *, and semver * never matches prereleases — so pnpm resolved the linked packages' nested copies of each other from the registry's last stable release (0.0.1) and the mixed versions crashed the scaffold's test harness at runtime (mapKeysToSqlColumns missing from the ancient adapter). The generated pnpm-workspace.yaml now carries an overrides map pinning every resolution of the yalc set to file:.yalc copies, and the installer shares the same package list so the two can never drift.
There was a problem hiding this comment.
💡 Codex Review
Here are some automated review suggestions for this pull request.
Reviewed commit: 1cd8634cd1
ℹ️ About Codex in GitHub
Codex has been enabled to automatically review pull requests in this repo. Reviews are triggered when you
- Open a pull request for review
- Mark a draft as ready
- Comment "@codex review".
If Codex has suggestions, it will comment; otherwise it will react with 👍.
When you sign up for Codex through ChatGPT, Codex can also answer questions or update the PR, like "@codex address that feedback".
….js app The plugin template always produces a standalone package, but a Next.js project at cwd routed the run into the install-into-this-project flow — which ignores the directory argument — so the guard cancelled even for an explicit target like 'create-nextly-app my-plugin -t plugin' run from inside an app repo. Plugin runs now always take the fresh-scaffold path (making that guard unreachable, so it is removed); non-empty targets are negotiated by the existing directory-conflict prompt, and non-plugin behavior in existing projects is unchanged. Also validates generated peer specs with an anchored full-range pattern instead of a first-character check, which waved through hybrids like '^latest'.
There was a problem hiding this comment.
Caution
Some comments are outside the diff and can’t be posted inline due to platform limitations.
⚠️ Outside diff range comments (2)
packages/create-nextly-app/src/utils/template.ts (2)
206-230: 🔒 Security & Privacy | 🟠 Major | ⚡ Quick winPreserve an existing
.gitignoreduring restoration.The overlay path can choose “ignore” and keep existing files, but
restoreBundledGitignoresunconditionally renamesgitignoreto.gitignore;fs.renamereplaces the destination contents, which can replace user-defined ignore rules and make secrets or generated files committable. Keep/merge the existing destination when present and only rename when.gitignoreis absent.🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the rest with a brief reason, keep changes minimal, and validate. In `@packages/create-nextly-app/src/utils/template.ts` around lines 206 - 230, Update restoreBundledGitignores so each gitignore restoration checks whether .gitignore already exists before renaming. Preserve the existing destination and avoid overwriting its contents; only rename gitignore when .gitignore is absent, while retaining the current recursive traversal and exclusions.
493-501: 🗄️ Data Integrity & Integration | 🟠 Major | ⚡ Quick winValidate the resolved dependency range instead of trusting the
^prefix.
resolveNextlyVersions()accepts the raw latest value and wraps it as"^${version}", but a malformed value like^not-a-versionwould still pass the currentstartsWith("^")guard and be written into generated{{nextlyRange}}. Reuse or add a small semver-range validator before returning the caret value, and keep the same validation surface for invalid/careted, exact/version-only, and prerelease inputs.🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the rest with a brief reason, keep changes minimal, and validate. In `@packages/create-nextly-app/src/utils/template.ts` around lines 493 - 501, Update resolvePluginNextlyRange to validate the resolved v as a valid semver range rather than accepting any value beginning with "^". Reuse an existing validator or add a small one that consistently handles invalid/caret, exact or version-only, and prerelease inputs; return ">=0.0.0" for invalid ranges while preserving valid caret ranges and the useYalc behavior.
🤖 Prompt for all review comments with AI agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.
Outside diff comments:
In `@packages/create-nextly-app/src/utils/template.ts`:
- Around line 206-230: Update restoreBundledGitignores so each gitignore
restoration checks whether .gitignore already exists before renaming. Preserve
the existing destination and avoid overwriting its contents; only rename
gitignore when .gitignore is absent, while retaining the current recursive
traversal and exclusions.
- Around line 493-501: Update resolvePluginNextlyRange to validate the resolved
v as a valid semver range rather than accepting any value beginning with "^".
Reuse an existing validator or add a small one that consistently handles
invalid/caret, exact or version-only, and prerelease inputs; return ">=0.0.0"
for invalid ranges while preserving valid caret ranges and the useYalc behavior.
ℹ️ Review info
⚙️ Run configuration
Configuration used: Path: .coderabbit.yaml
Review profile: CHILL
Plan: Pro Plus
Run ID: cbcf2f8a-9667-4b1a-ae4a-e7be4ee283ef
📒 Files selected for processing (4)
packages/create-nextly-app/src/__tests__/scaffold-plugin.test.tspackages/create-nextly-app/src/create-nextly.tspackages/create-nextly-app/src/installers/dependencies.tspackages/create-nextly-app/src/utils/template.ts
🚧 Files skipped from review as they are similar to previous changes (2)
- packages/create-nextly-app/src/installers/dependencies.ts
- packages/create-nextly-app/src/tests/scaffold-plugin.test.ts
…ry versions Restoring a bundled gitignore now merges into an existing .gitignore (overlay scaffolds can carry user rules at the destination; a rename replaced them, silently un-ignoring whatever they covered) — the template's rules are appended once, so user rules and the required dev/.env exclusion both hold. Registry dist-tag payloads are untrusted: fetchLatestVersion now wraps only complete semver versions (a malformed tag became an invalid "^not-a-version" install spec in every generated package.json), and the plugin compat range validates the full caret range before trusting it. The packing-time gitignore walk also skips node_modules and .git.
Summary
Selecting the Plugin template in
create-nextly-appfailed at every stage: the--template pluginflag was rejected outright, the interactive flow crashed with "App Router not detected" after the full dependency install, and even a hand-recovered scaffold failed its own test suite and could not boot its embedded dev playground. This PR fixes every reproduced defect across the CLI flow, the scaffolder, and the template content, plus the template-distribution gap that allowed them to ship unnoticed, and addresses all review findings from the first round.The result, verified end to end against the real npm registry:
create-nextly-app my-plugin --template plugin -y→ install completes → the scaffold's owntest/build/check-typespass →pnpm devboots the playground →/adminreturns 200, auto-logged-in as the seeded dev user, with the plugin'sExamplescollection live in the admin — zero manual steps.What the Plugin template is
A scaffold for a publishable npm package (not an app): the plugin library in
src/(adefinePlugin()factory contributing a collection, a permission, an admin menu entry, and a settings page), plus an embeddeddev/folder holding a minimal Nextly app on SQLite that registers the plugin so authors can exercise it in a real admin with hot-reload. Onlydist/ships (files: ["dist"]);dev/is never published. It wires tsup for building, vitest with thecreateTestNextlyin-memory harness from@nextlyhq/plugin-sdk/testing, and thenextly-pluginnpm keyword for discoverability.Fixes (original defects)
--template pluginrejected —cli.tshardcodedvalidTypes = ["blank", "blog"]while the interactive prompt offered Plugin. Validation (and the "template not found" error inutils/template.ts) now derives from the template registry viagetAvailableTemplateNames(), so the flag path, the prompt,--help, and error messages can no longer drift apart."App Router not detected" crash after install — after scaffolding, the CLI ran
detectProject()on the new directory, which requires a Next.js App Router layout. A plugin scaffold has library code atsrc/and its Next app atdev/src/app, so detection aborted — after minutes of dependency installation. Plugin scaffolds now detect only the package manager (the sole field downstream consumes for fresh scaffolds) and skip the app-shaped checks. Additionally, selecting the Plugin template inside an existing Next.js project now fails fast with a clear message: the fresh-scaffold path is skipped there, so proceeding would have installed app dependencies and generated app config without ever copying the plugin source.pnpm devaborted demandingDATABASE_URL— the template shipsdev/.env.examplebut nothing createddev/.env(the CLI intentionally skips app-style env generation for plugins). Without it the dialect defaulted to postgresql and the instrumentation hook killed the server. The scaffold now materializesdev/.envfrom the committed example (overwrite: falsepreserves a user's own file when scaffolding over an existing directory)./admin500 "No QueryClient set" — the playground's admin page mountedRootLayoutbare; the admin's data hooks resolve their QueryClient fromQueryProvider. Now wrapped inQueryProvider+ErrorBoundary, matching the base app template.Generated test suite failed out of the box —
plugin.test.tspassedcollections: plugin.contributes?.collectionsintocreateTestNextly(the harness already applies plugin schema contributions itself, so the collection registered twice → slug-collision "Schema configuration is invalid" at boot) and used the removed positional CRUD style (create("examples", {...}),findById). Rewritten to the current Direct API (create({ collection, data }),findByID({ collection, id })), validated against the published packages.Auto-login promise was false —
admin.devAutoLoginonly issues a session for a user that already exists; nothing seeded one, so the first/adminvisit dead-ended on the/admin/setupwizard. The playground's instrumentation hook now seeds the matching dev user via the publicnextly/database/seedersprimitives (idempotent; dev-only). Note: the seed usesgetService("adapter")becausegetNextly().adapteris undefined in the published packages.Template/package version skew — the CLI build already bundles the plugin template into the published package, but the runtime unconditionally downloaded templates from GitHub
main, so the bundled copy was dead code and a GitHub-main template could drift ahead of the npm packages the scaffold installs (exactly the API-drift class behind fix 5). Plugin (and blank) scaffolds now use the bundled copy by default; see the review-roundshouldUseBundledTemplate()refactor below for the override rules."latest"leaking into peerDependencies — surfaced during E2E verification: when a registry version lookup fails (offline, transient npm error) or under--use-yalc, the pluginpackage.jsongenerator fell back to the"latest"dist-tag. pnpm 11 rejects that inpeerDependencies(ERR_PNPM_INVALID_PEER_DEPENDENCY_SPECIFICATION) and then refuses to run any script in the scaffold, includingpnpm dev. Peers now fall back to an open semver range; regular/dev dependencies keep the dist-tag, where it is valid.Review-round fixes
createRegister()fires the runtime's permission seeding in the background (post-init tasks are not awaited), and the runtime's new-permission assignment silently no-ops while the super-admin role does not exist. The boot-time seed could therefore leave the role with an incomplete permission set — 403s precisely on the plugin's own collection. The seed now runs a second pass after the role exists; that pass re-lists all permissions and tops up any created in between. The runtime's assignment call runs after all of its inserts, so either it sees the role and assigns everything itself, or every insert it made is already visible to the second pass — the role converges to the complete set in every interleaving. Verified on a cold first boot by querying the SQLite database: all 32 assignable permissions (including all 5 of the plugin'sexamplespermissions) are on the role. The only unassigned rows are the deliberately hidden legacypermissionsresource (buildHiddenPermissionConditionsexcludes it from every assignable list) — identical to what the/admin/setupwizard produces.--branchhonored for bundled templates (CodeRabbit) — bundled-template selection now lives in a testedshouldUseBundledTemplate()helper: blank and plugin scaffold from the CLI-bundled copy by default, while--local-template,--use-yalc, or a non-main--branchforce live resolution. Previously an explicit--branchon the blank template was silently ignored. Covered by a unit-test matrix; functionally verified that--template blank --branch <x>now resolves the requested branch (clean 404 message for a nonexistent one) and the default remains offline.next dev(CodeRabbit) — the playground seed guard tightened fromNODE_ENV !== "production"toNODE_ENV === "development", so test runners (NODE_ENV=test) never seed credentials; matches the README's dev-only wording. Pinned by a scaffold assertion.@nextlyhq/plugin-sdkyalc-linked for plugin scaffolds (Codex) —--use-yalcplugin scaffolds previously linked nextly/admin/ui/adapters from the yalc store but installed the published plugin-sdk from npm, producing a mismatched local-dev scaffold. The SDK is now part of the yalc set for plugin scaffolds.@nextlyhq/admin-cssadded to the changeset (Codex) — lockstep completeness; the package is published and was missing from the bump list.--help's template list derives from the registry; comments added for the registry-backed error and the generated test's Direct API usage.Type of change
Every behavioral change branches on
projectType === "plugin"(previously a guaranteed crash, so there is no working behavior to break) — with two deliberate, argued exceptions: honoring an explicit non-main--branchfor the blank template (previously silently ignored, which contradicted the flag's documented purpose), and failing fast when the Plugin template is selected inside an existing Next.js project (previously produced a broken hybrid install).Related issues
None filed — the failure was reported directly (Plugin template selection fails during
create-nextly-appsetup).Changeset
.changeset/plugin-template-scaffold-fixes.md)Test plan
pnpm lint(clean,--max-warnings 0)pnpm check-types(clean)pnpm exec vitest runinpackages/create-nextly-app— 10 files, 116 tests, all passing (baseline was 113; +3 for theshouldUseBundledTemplatematrix)pnpm build(bundled templates re-copied)create-nextly-app <name> --template plugin -y→ scaffold + full install completepnpm test(1 passed),pnpm run build(tsup ESM + DTS),pnpm run check-types(clean)pnpm dev→/adminreturns 200;/admin/api/auth/sessionreturns the seededdev@nextly.localuser with zero manual steps (no setup wizard)examplespermissions--template blank --branch <nonexistent>attempts live resolution and reports a clear 404; default blank scaffold remains offline/bundledNew regression assertions in
scaffold-plugin.test.tspin the template content:dev/.envmaterialization,QueryProvider/ErrorBoundarywrapping, current-API test shape, two-pass seed,NODE_ENV === "development"guard, and no"latest"peers under the offline fallback (that test runs with the registry stubbed offline, exactly where the dist-tag used to leak in).Checklist
mainbranchdev/.env.exampleheader; CLI next-steps output)Notes for reviewers
seedSuperAdmintwice — the second pass is what makes the boot race-free against the runtime's background permission seeding (detailed argument in the inline comment intemplates/plugin/dev/instrumentation.ts). Please don't "simplify" it to a single call.permissions-resource rows in any Nextly database are by design (hidden legacy surface), not a gap in this PR — the setup wizard yields the same 32/36.latestdist-tag (alpha.37) currently lagsalpha(alpha.39) — a release-process question, not addressed here.templates/show unresolved-import diagnostics inside the monorepo IDE — expected, since template dependencies only exist after scaffolding; the scaffolded project type-checks clean.Summary by CodeRabbit
dev/.envfromdev/.env.exampleand provide dev-only auto-login for the admin..gitignorerename/restore behavior during packing and scaffolding.dev/.env.exampleguidance.