Skip to content

chore: audit and fix base templates#58

Merged
ulises-jeremias merged 40 commits intomainfrom
chore/template-audit-fixes
Apr 20, 2026
Merged

chore: audit and fix base templates#58
ulises-jeremias merged 40 commits intomainfrom
chore/template-audit-fixes

Conversation

@ulises-jeremias
Copy link
Copy Markdown
Member

@ulises-jeremias ulises-jeremias commented Mar 13, 2026

Summary

  • audit base templates against real generated projects and real create-awesome-node-app runs
  • refresh starter UX for Next.js, React Vite, web-extension, and NestJS templates
  • fix template regressions across Next.js, web-extension, WebdriverIO, turborepo, and Next.js SaaS AI
  • harden combo-testing docs and workflow coverage

Validation

  • generated and exercised base templates with real command runs
  • confirmed react-vite-boilerplate, nestjs-boilerplate, nextjs-starter, web-extension-react-boilerplate, turborepo-boilerplate, and nextjs-saas-ai-starter
  • confirmed webdriverio-boilerplate through format, lint:fix, lint, and type-check; runtime test still depends on external WebDriver binary download in this environment

Summary by CodeRabbit

Release Notes

  • New Features

    • NextJS SaaS AI template now fully supported with configuration extensions
    • NestJS starter includes new health check endpoint with structured metadata responses
    • Redesigned starter landing pages with hero sections, quick-start checklists, and feature highlights
  • Improvements

    • Enhanced CI/CD workflow with comprehensive lint and type-check validation steps
    • Simplified CSS design token system for consistent theming across templates
    • Modernized TypeScript and ESLint configurations for improved compatibility
    • Updated template metadata and descriptions for clarity

Validate base templates with real create-awesome-node-app runs and fix the issues found across Next.js, NestJS, React Vite, web-extension, WebdriverIO, and turborepo templates.

Also harden combo testing docs/workflow and align generated files with current package/template conventions.

Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
@coderabbitai
Copy link
Copy Markdown

coderabbitai Bot commented Mar 13, 2026

Note

Reviews paused

It looks like this branch is under active development. To avoid overwhelming you with review comments due to an influx of new commits, CodeRabbit has automatically paused this review. You can configure this behavior by changing the reviews.auto_review.auto_pause_after_reviewed_commits setting.

Use the following commands to manage reviews:

  • @coderabbitai resume to resume automatic reviews.
  • @coderabbitai review to trigger a single review.

Use the checkboxes below for quick actions:

  • ▶️ Resume reviews
  • 🔍 Trigger review
📝 Walkthrough

Walkthrough

This PR updates multiple project templates and extensions by refactoring the NestJS starter's health endpoints, redesigning NextJS and React Vite starter landing pages with updated styling, adding nextjs-saas-ai template type support, broadening ESLint declaration file patterns, introducing legacy peer dependency handling across extensions, and updating various TypeScript, ESLint, and build configurations throughout the codebase.

Changes

Cohort / File(s) Summary
CI/CD and Workflow Updates
.github/workflows/test-combinations.yml, templates/nextjs-saas-ai-starter/.github/workflows/build.yml, TESTING.md
Updated CI workflows to add explicit npm install, lint, type-check steps; changed build invocation to use SKIP_ENV_VALIDATION=true and build:ci script; updated workflow documentation to reflect new step ordering.
Template Configuration
templates.json
Updated NextJS SaaS AI template type from "nextjs" to "nextjs-saas-ai" and extended three extensions (GitHub Setup, Husky + Lint Staged, Development Container) to support the new template type.
NestJS Starter Refactoring
templates/nestjs-starter/src/app.controller.ts, templates/nestjs-starter/src/app.controller.spec.ts, templates/nestjs-starter/src/app.service.ts, templates/nestjs-starter/src/app.module.ts, templates/nestjs-starter/src/health/health.controller.ts, templates/nestjs-starter/src/health/health.controller.spec.ts, templates/nestjs-starter/tsconfig.json
Refactored health endpoint from getHello() to structured getStatus() and introduced new getHealth() endpoint; added HealthController with test coverage; introduced AppStatusResponse and AppHealthResponse types; updated module to include HealthController; excluded tools/**/* from TypeScript compilation.
NextJS Starter Redesign
templates/nextjs-starter/[src]/app/globals.css, templates/nextjs-starter/[src]/app/layout.tsx, templates/nextjs-starter/[src]/app/page.tsx, templates/nextjs-starter/[src]/app/page.module.css, templates/nextjs-starter/package.json, templates/nextjs-starter/.eslintignore
Simplified CSS design tokens, updated metadata (title/description), rewired home page to render brand-focused hero with feature steps and checklist from data structures, added autoprefixer devDependency, expanded ESLint ignore patterns for tools directory.
NextJS SaaS AI Starter Updates
templates/nextjs-saas-ai-starter/package.json, templates/nextjs-saas-ai-starter/eslint.config.mjs
Added build:ci script with SKIP_ENV_VALIDATION=true; downgraded specific react-hooks ESLint rules to warnings.
React Vite Starter Redesign
templates/react-vite-starter/[src]/pages/Landing.css, templates/react-vite-starter/[src]/pages/Landing.tsx.template, templates/react-vite-starter/eslint.config.mjs.template, templates/react-vite-starter/tsconfig.json.template
Redesigned Landing page with new modular component structure and starterHighlights data; replaced Cracked component with full section markup; broadened ESLint ignore pattern for declaration files; expanded TypeScript exclude to include electron/**/*.
Turborepo Starter Updates
templates/turborepo-starter/apps/playground/src/stories/Button.tsx, templates/turborepo-starter/apps/playground/src/stories/Header.tsx, templates/turborepo-starter/package/index.js, templates/turborepo-starter/packages/eslint-config-react/package.json.template, templates/turborepo-starter/packages/ui/package.json.template, templates/turborepo-starter/packages/tsconfig/base.json, templates/turborepo-starter/packages/tsconfig/nest.json, templates/turborepo-starter/packages/ui/tsconfig.json
Exported ButtonProps and HeaderProps interfaces; replaced static ESLint config dependency with dynamic keyed dependency; added react-dom as dependency; added lib TypeScript option; removed baseUrl from nest.json; replaced tsconfig extends pattern in ui/tsconfig.json with explicit compiler options.
WebExtension React Vite Updates
templates/webextension-react-vite-starter/[src]/popup/Popup.tsx.template, templates/webextension-react-vite-starter/[src]/popup/Popup.css, templates/webextension-react-vite-starter/[src]/popup/index.css, templates/webextension-react-vite-starter/[src]/content/App.test.tsx, templates/webextension-react-vite-starter/.webext-config/reload/injections/view.ts, templates/webextension-react-vite-starter/eslint.config.mjs.template, templates/webextension-react-vite-starter/package/index.js, templates/webextension-react-vite-starter/tsconfig.json.template, templates/webextension-react-vite-starter/tsconfig.node.json
Redesigned popup UI with Browser polyfill and openOptions handler; added CSS variables for popup styling; removed content App test; converted terse reload condition to explicit block; broadened ESLint ignore pattern; updated build and type-check scripts; refactored tsconfig includes to use glob patterns; added extends to tsconfig.node.json with updated compiler options.
WDio Starter Updates
templates/wdio-starter/tsconfig.json, templates/wdio-starter/.eslintignore
Updated TypeScript target to es2022 with explicit lib configuration and skipLibCheck; added tools directory to ESLint ignore list.
Extension npm Legacy Peer Deps
extensions/react-semantic-ui/.npmrc, extensions/nestjs-openapi/.npmrc, extensions/react-hookstate/.npmrc, extensions/react-ionic/.npmrc, extensions/react-semantic-ui-less/.npmrc, extensions/react-ionic-capacitor/.npmrc
Added legacy-peer-deps=true configuration across six extensions to enable legacy peer dependency resolution.
Extension Configuration Updates
extensions/nextjs-auth/[src]/lib/auth.ts, extensions/all-husky-lint-staged/package.json, extensions/react-testing-library-with-jest/eslint.config.mjs.template, extensions/react-testing-library-with-jest/tsconfig.json.template, extensions/react-million/[src]/pages/Landing.tsx.template
Updated next-auth Session.user type augmentation to use DefaultSession; modified husky prepare script to use husky || true; removed ESLint and TypeScript config templates from react-testing-library-with-jest; removed Landing component from react-million template.

Estimated code review effort

🎯 4 (Complex) | ⏱️ ~55 minutes

Possibly related PRs

Poem

🐰 Our templates hop with vibrant flair,
New health checks and styles beyond compare,
NextJS gleams with redesigned grace,
Each extension finds its rightful place,
From workflows swift to configs clean,
The finest starter kit you've ever seen! ✨

🚥 Pre-merge checks | ✅ 2 | ❌ 1

❌ Failed checks (1 warning)

Check name Status Explanation Resolution
Docstring Coverage ⚠️ Warning Docstring coverage is 25.00% which is insufficient. The required threshold is 80.00%. Write docstrings for the functions missing them to satisfy the coverage threshold.
✅ Passed checks (2 passed)
Check name Status Explanation
Description Check ✅ Passed Check skipped - CodeRabbit’s high-level summary is enabled.
Title check ✅ Passed The title 'chore: audit and fix base templates' is concise, clear, and directly reflects the main objective of auditing and fixing templates across the codebase, which aligns with the comprehensive changes documented throughout the PR.

✏️ 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 chore/template-audit-fixes

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.

❤️ Share

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

Copy link
Copy Markdown

@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: 4

🧹 Nitpick comments (5)
templates/react-vite-starter/[src]/pages/Landing.css (1)

32-37: Consider adjusting line-height for title to avoid text clipping.

A line-height of 0.95 may clip descenders (letters like g, y, p) and cause accessibility issues with text readability, especially at larger font sizes. Consider using at least 1.1 for headings.

✨ Suggested adjustment
 .landing__title {
   margin: 0 0 0.75rem;
   font-size: clamp(2.4rem, 8vw, 4.25rem);
-  line-height: 0.95;
+  line-height: 1.1;
   letter-spacing: -0.05em;
 }
🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In `@templates/react-vite-starter/`[src]/pages/Landing.css around lines 32 - 37,
The .landing__title CSS rule currently sets line-height: 0.95 which can clip
descenders at large font sizes; update the .landing__title selector to use a
safer line-height (e.g., at least 1.1) to prevent clipping and improve
readability/ accessibility across viewport sizes while keeping the existing
font-size clamp and other properties unchanged.
templates/nestjs-starter/src/health/health.controller.ts (1)

8-11: Add a dedicated spec for the new /health controller path.

This endpoint is newly introduced but currently lacks direct controller-level test coverage; adding a focused spec will prevent regressions in starter templates.

🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In `@templates/nestjs-starter/src/health/health.controller.ts` around lines 8 -
11, Add a unit spec for the new /health controller by creating a
health.controller.spec.ts that imports HealthController and a mocked AppService;
set up a TestingModule that provides HealthController and a stub for
appService.getHealth(), then assert that controller.getHealth() returns the
expected AppHealthResponse shape/value. Specifically target the getHealth()
method on HealthController, mock AppService.getHealth() to return a known
AppHealthResponse, and verify the controller delegates to the service and
returns the mock result to prevent regressions in the starter template.
templates/webextension-react-vite-starter/[src]/popup/Popup.tsx.template (1)

6-10: Consider providing user feedback when openOptionsPage is unavailable.

The defensive check is good, but if openOptionsPage is undefined (which is rare but possible in some contexts), clicking the button silently does nothing. An optional improvement would be to provide feedback or disable the button when the API is unavailable.

💡 Optional: Add fallback feedback
 const openOptions = () => {
   if (Browser.runtime.openOptionsPage) {
     Browser.runtime.openOptionsPage();
+  } else {
+    console.warn('Options page API not available');
   }
 };

Alternatively, you could conditionally render the button only when the API is available.

🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In `@templates/webextension-react-vite-starter/`[src]/popup/Popup.tsx.template
around lines 6 - 10, The openOptions function currently checks
Browser.runtime.openOptionsPage but leaves the UI silent if it's unavailable;
update the Popup UI to either disable or hide the "Open options" button when
Browser.runtime.openOptionsPage is falsy, or provide immediate feedback (e.g.,
showToast/alert) inside openOptions when the API is missing; locate the
openOptions function and the button render in Popup (symbols: openOptions,
Browser.runtime.openOptionsPage, Popup component or the button element) and
implement a conditional render/disabled prop or a fallback notification so users
get explicit feedback instead of no-op behavior.
templates/webextension-react-vite-starter/[src]/popup/Popup.css (2)

84-86: Consider adding a focus state for keyboard accessibility.

The hover state is defined, but a :focus or :focus-visible state would improve keyboard navigation accessibility for the button.

💡 Optional: Add focus state
 .popup__button:hover {
   filter: brightness(1.05);
 }
+
+.popup__button:focus-visible {
+  outline: 2px solid var(--popup-accent);
+  outline-offset: 2px;
+}
🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In `@templates/webextension-react-vite-starter/`[src]/popup/Popup.css around lines
84 - 86, Add a keyboard focus state for the popup button to match the hover
affordance: update the .popup__button selector by adding a :focus and/or
:focus-visible rule (e.g., .popup__button:focus, .popup__button:focus-visible)
that applies an accessible visual treatment such as the same filter:
brightness(1.05) used on hover and a visible outline or box-shadow for keyboard
users; ensure the focus style is not removed by outline: none so it remains
perceivable.

70-82: Consider using CSS variables for button colors for theming consistency.

The button uses hardcoded color values while the rest of the stylesheet relies on CSS variables. For full theming support, these could be extracted to variables.

💡 Optional: Extract button colors to CSS variables

In index.css, add:

--popup-button-gradient-start: `#3b82f6`;
--popup-button-gradient-end: `#2563eb`;
--popup-button-text: `#eff6ff`;

Then in Popup.css:

 .popup__button {
   ...
-  background: linear-gradient(135deg, `#3b82f6`, `#2563eb`);
-  color: `#eff6ff`;
+  background: linear-gradient(135deg, var(--popup-button-gradient-start), var(--popup-button-gradient-end));
+  color: var(--popup-button-text);
   ...
 }
🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In `@templates/webextension-react-vite-starter/`[src]/popup/Popup.css around lines
70 - 82, The .popup__button rule uses hardcoded colors; extract those values
into CSS variables (e.g., --popup-button-gradient-start,
--popup-button-gradient-end, --popup-button-text) defined in your global
stylesheet (index.css) and replace the gradient and color declarations in
Popup.css to reference these variables so theming is consistent across the app.
🤖 Prompt for all review comments with AI agents
Verify each finding against the current code and only fix it if needed.

Inline comments:
In `@templates/nestjs-starter/src/app.controller.spec.ts`:
- Around line 15-16: The test suite label is stale: update the describe block
currently named 'getHello' to 'getStatus' so it matches the method under test
(getStatus) in app.controller.spec.ts; locate the describe('getHello', ...) and
rename it to describe('getStatus', ...) so test reports accurately reflect the
tested method.

In `@templates/nextjs-saas-ai-starter/cna.config.json`:
- Around line 2-15: The custom prompts "srcDir" and "projectImportPath" are
collected but not applied to generated files; update the template system to
substitute these values into template placeholders (e.g., replace hardcoded
"@/*" and "./src/*" in tsconfig.json and any import/path occurrences) or remove
the prompts. Concretely, wire the "srcDir" and "projectImportPath" variables
into the template rendering step so generated artifacts (tsconfig.json, import
aliases, documentation examples) use the provided values instead of defaults,
ensuring placeholders exist where "srcDir" and "projectImportPath" are
referenced and are replaced at generation time.

In `@templates/nextjs-saas-ai-starter/package.json`:
- Line 5: The "build" script currently sets SKIP_ENV_VALIDATION=true which
disables critical env checks for all developers; remove the SKIP_ENV_VALIDATION
setting from the "build" script so it runs as "NODE_ENV=production next build",
and add a new CI-only script (e.g., "build:ci") that sets
SKIP_ENV_VALIDATION=true for CI runs; update CI/deployment configs to call "npm
run build:ci" instead of "npm run build".

In `@templates/nextjs-starter/`[src]/app/page.module.css:
- Around line 90-91: Replace the fixed 50% column sizes at the tablet breakpoint
with fractional tracks so the grid and the 1rem gap fit inside the container;
specifically change the rule that sets "grid-template-columns: 50% 50%;" to use
fractional tracks like "grid-template-columns: repeat(2, minmax(0, 1fr));" (or
"1fr 1fr") so the grid uses available space correctly while keeping "gap: 1rem"
unchanged; update all occurrences that set two 50% columns (the tablet
breakpoint rules referenced) to this fractional form.

---

Nitpick comments:
In `@templates/nestjs-starter/src/health/health.controller.ts`:
- Around line 8-11: Add a unit spec for the new /health controller by creating a
health.controller.spec.ts that imports HealthController and a mocked AppService;
set up a TestingModule that provides HealthController and a stub for
appService.getHealth(), then assert that controller.getHealth() returns the
expected AppHealthResponse shape/value. Specifically target the getHealth()
method on HealthController, mock AppService.getHealth() to return a known
AppHealthResponse, and verify the controller delegates to the service and
returns the mock result to prevent regressions in the starter template.

In `@templates/react-vite-starter/`[src]/pages/Landing.css:
- Around line 32-37: The .landing__title CSS rule currently sets line-height:
0.95 which can clip descenders at large font sizes; update the .landing__title
selector to use a safer line-height (e.g., at least 1.1) to prevent clipping and
improve readability/ accessibility across viewport sizes while keeping the
existing font-size clamp and other properties unchanged.

In `@templates/webextension-react-vite-starter/`[src]/popup/Popup.css:
- Around line 84-86: Add a keyboard focus state for the popup button to match
the hover affordance: update the .popup__button selector by adding a :focus
and/or :focus-visible rule (e.g., .popup__button:focus,
.popup__button:focus-visible) that applies an accessible visual treatment such
as the same filter: brightness(1.05) used on hover and a visible outline or
box-shadow for keyboard users; ensure the focus style is not removed by outline:
none so it remains perceivable.
- Around line 70-82: The .popup__button rule uses hardcoded colors; extract
those values into CSS variables (e.g., --popup-button-gradient-start,
--popup-button-gradient-end, --popup-button-text) defined in your global
stylesheet (index.css) and replace the gradient and color declarations in
Popup.css to reference these variables so theming is consistent across the app.

In `@templates/webextension-react-vite-starter/`[src]/popup/Popup.tsx.template:
- Around line 6-10: The openOptions function currently checks
Browser.runtime.openOptionsPage but leaves the UI silent if it's unavailable;
update the Popup UI to either disable or hide the "Open options" button when
Browser.runtime.openOptionsPage is falsy, or provide immediate feedback (e.g.,
showToast/alert) inside openOptions when the API is missing; locate the
openOptions function and the button render in Popup (symbols: openOptions,
Browser.runtime.openOptionsPage, Popup component or the button element) and
implement a conditional render/disabled prop or a fallback notification so users
get explicit feedback instead of no-op behavior.

ℹ️ Review info
⚙️ Run configuration

Configuration used: defaults

Review profile: CHILL

Plan: Pro

Run ID: 003b57d7-d4e5-437d-b04c-07a936502632

📥 Commits

Reviewing files that changed from the base of the PR and between 5be2ebe and 396266f.

📒 Files selected for processing (36)
  • .github/workflows/test-combinations.yml
  • TESTING.md
  • templates.json
  • templates/nestjs-starter/src/app.controller.spec.ts
  • templates/nestjs-starter/src/app.controller.ts
  • templates/nestjs-starter/src/app.module.ts
  • templates/nestjs-starter/src/app.service.ts
  • templates/nestjs-starter/src/health/health.controller.ts
  • templates/nextjs-saas-ai-starter/cna.config.json
  • templates/nextjs-saas-ai-starter/package.json
  • templates/nextjs-starter/[src]/_feature-template_/README.md.template
  • templates/nextjs-starter/[src]/app/globals.css
  • templates/nextjs-starter/[src]/app/layout.tsx
  • templates/nextjs-starter/[src]/app/page.module.css
  • templates/nextjs-starter/[src]/app/page.tsx
  • templates/nextjs-starter/package.json
  • templates/react-vite-starter/[src]/pages/Landing.css
  • templates/react-vite-starter/[src]/pages/Landing.tsx.template
  • templates/turborepo-starter/apps/playground/src/stories/Button.tsx
  • templates/turborepo-starter/apps/playground/src/stories/Header.tsx
  • templates/turborepo-starter/package/index.js
  • templates/turborepo-starter/packages/eslint-config-react/package.json.template
  • templates/turborepo-starter/packages/ui/package.json.template
  • templates/wdio-starter/docs/RUNNING_TESTS.md.template
  • templates/wdio-starter/docs/TEST_CONFIGURATION.md.template
  • templates/wdio-starter/package/index.js
  • templates/wdio-starter/tsconfig.json
  • templates/webextension-react-vite-starter/.webext-config/reload/injections/view.ts
  • templates/webextension-react-vite-starter/[src]/content/App.test.tsx
  • templates/webextension-react-vite-starter/[src]/popup/Popup.css
  • templates/webextension-react-vite-starter/[src]/popup/Popup.tsx.template
  • templates/webextension-react-vite-starter/[src]/popup/index.css
  • templates/webextension-react-vite-starter/eslint.config.mjs.template
  • templates/webextension-react-vite-starter/package/index.js
  • templates/webextension-react-vite-starter/tsconfig.json.template
  • templates/webextension-react-vite-starter/tsconfig.node.json
💤 Files with no reviewable changes (1)
  • templates/webextension-react-vite-starter/[src]/content/App.test.tsx

Comment on lines +15 to +16
describe('getHello', () => {
it('should return "Hello World!"', () => {
it('should return starter status metadata', () => {
Copy link
Copy Markdown

Choose a reason for hiding this comment

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

⚠️ Potential issue | 🟡 Minor

Rename stale spec suite label to match the method under test.

The suite still says getHello while the test now targets getStatus, which makes test reporting confusing.

Suggested patch
-  describe('getHello', () => {
+  describe('getStatus', () => {
📝 Committable suggestion

‼️ IMPORTANT
Carefully review the code before committing. Ensure that it accurately replaces the highlighted code, contains no missing lines, and has no issues with indentation. Thoroughly test & benchmark the code to ensure it meets the requirements.

Suggested change
describe('getHello', () => {
it('should return "Hello World!"', () => {
it('should return starter status metadata', () => {
describe('getStatus', () => {
it('should return starter status metadata', () => {
🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In `@templates/nestjs-starter/src/app.controller.spec.ts` around lines 15 - 16,
The test suite label is stale: update the describe block currently named
'getHello' to 'getStatus' so it matches the method under test (getStatus) in
app.controller.spec.ts; locate the describe('getHello', ...) and rename it to
describe('getStatus', ...) so test reports accurately reflect the tested method.

Comment on lines +2 to +15
"customOptions": [
{
"name": "srcDir",
"type": "text",
"message": "Subdirectory to put all source content (e.g., `src`, `app`). Leave blank to use the root directory.",
"initial": "src"
},
{
"name": "projectImportPath",
"type": "text",
"message": "Import alias to use for the project, e.g., `@/`",
"initial": "@/"
}
]
Copy link
Copy Markdown

Choose a reason for hiding this comment

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

⚠️ Potential issue | 🟠 Major

Custom options are currently not wired into generated output.

These prompts collect srcDir and projectImportPath, but key config still appears hardcoded (e.g., templates/nextjs-saas-ai-starter/tsconfig.json uses @/* and ./src/*). That makes non-default answers ineffective and misleading for users.

Suggested direction

Either:

  • wire these options into template placeholders across affected files (tsconfig, imports/docs), or
  • remove these prompts until the substitutions are implemented end-to-end.
🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In `@templates/nextjs-saas-ai-starter/cna.config.json` around lines 2 - 15, The
custom prompts "srcDir" and "projectImportPath" are collected but not applied to
generated files; update the template system to substitute these values into
template placeholders (e.g., replace hardcoded "@/*" and "./src/*" in
tsconfig.json and any import/path occurrences) or remove the prompts.
Concretely, wire the "srcDir" and "projectImportPath" variables into the
template rendering step so generated artifacts (tsconfig.json, import aliases,
documentation examples) use the provided values instead of defaults, ensuring
placeholders exist where "srcDir" and "projectImportPath" are referenced and are
replaced at generation time.

"scripts": {
"dev": "next dev --turbopack --hostname 0.0.0.0 --port 3000",
"build": "NODE_ENV=production next build",
"build": "SKIP_ENV_VALIDATION=true NODE_ENV=production next build",
Copy link
Copy Markdown

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
# Verify that the build script currently forces env-skip
rg -n '"build"\s*:\s*".*SKIP_ENV_VALIDATION' templates/nextjs-saas-ai-starter/package.json

# Verify env validation is actually gated by SKIP_ENV_VALIDATION
rg -n 'skipValidation|SKIP_ENV_VALIDATION' templates/nextjs-saas-ai-starter/src/shared/lib/env.ts

Repository: Create-Node-App/cna-templates

Length of output: 203


🏁 Script executed:

#!/bin/bash
# Check all build-related scripts in package.json
rg -A 2 -B 2 '"build' templates/nextjs-saas-ai-starter/package.json

# Check if there's any existing CI-specific script
rg -n 'ci|CI' templates/nextjs-saas-ai-starter/package.json

Repository: Create-Node-App/cna-templates

Length of output: 585


Remove env validation bypass from the default production build.

The build script at line 5 unconditionally disables environment validation with SKIP_ENV_VALIDATION=true, which means every developer running npm run build skips critical env checks. This defeats the purpose of validation and allows misconfigured environments to reach production undetected.

Move the bypass to a CI-specific script:

Proposed script split
-    "build": "SKIP_ENV_VALIDATION=true NODE_ENV=production next build",
+    "build": "NODE_ENV=production next build",
+    "build:ci": "SKIP_ENV_VALIDATION=true NODE_ENV=production next build",

Update CI/deployment pipelines to call npm run build:ci instead.

📝 Committable suggestion

‼️ IMPORTANT
Carefully review the code before committing. Ensure that it accurately replaces the highlighted code, contains no missing lines, and has no issues with indentation. Thoroughly test & benchmark the code to ensure it meets the requirements.

Suggested change
"build": "SKIP_ENV_VALIDATION=true NODE_ENV=production next build",
"build": "NODE_ENV=production next build",
"build:ci": "SKIP_ENV_VALIDATION=true NODE_ENV=production next build",
🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In `@templates/nextjs-saas-ai-starter/package.json` at line 5, The "build" script
currently sets SKIP_ENV_VALIDATION=true which disables critical env checks for
all developers; remove the SKIP_ENV_VALIDATION setting from the "build" script
so it runs as "NODE_ENV=production next build", and add a new CI-only script
(e.g., "build:ci") that sets SKIP_ENV_VALIDATION=true for CI runs; update
CI/deployment configs to call "npm run build:ci" instead of "npm run build".

Comment on lines +90 to +91
grid-template-columns: repeat(3, minmax(0, 1fr));
gap: 1rem;
Copy link
Copy Markdown

Choose a reason for hiding this comment

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

⚠️ Potential issue | 🟡 Minor

Use fractional tracks at the tablet breakpoint.

Lines 190-191 set two 50% columns while Line 91 keeps a 1rem gap, so the grid becomes wider than its container between 701px and 1120px. Since templates/nextjs-starter/[src]/app/globals.css Line 31 hides horizontal overflow, the right edge of the second column gets clipped instead of fitting cleanly.

🛠️ Proposed fix
 `@media` (min-width: 701px) and (max-width: 1120px) {
   .grid {
-    grid-template-columns: repeat(2, 50%);
+    grid-template-columns: repeat(2, minmax(0, 1fr));
   }
 }

Also applies to: 189-191

🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In `@templates/nextjs-starter/`[src]/app/page.module.css around lines 90 - 91,
Replace the fixed 50% column sizes at the tablet breakpoint with fractional
tracks so the grid and the 1rem gap fit inside the container; specifically
change the rule that sets "grid-template-columns: 50% 50%;" to use fractional
tracks like "grid-template-columns: repeat(2, minmax(0, 1fr));" (or "1fr 1fr")
so the grid uses available space correctly while keeping "gap: 1rem" unchanged;
update all occurrences that set two 50% columns (the tablet breakpoint rules
referenced) to this fractional form.

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

This PR audits and refreshes multiple base templates to better match real create-awesome-node-app generated projects, improves starter UX for several templates (Next.js / React Vite / WebExtension / NestJS), and strengthens combination testing docs/workflow coverage.

Changes:

  • Refreshes starter UIs/styles for Next.js, React+Vite, and WebExtension popup experiences.
  • Adds/adjusts template build + type-check behavior (notably WebExtension TS checks) and updates WDIO + Turborepo template configuration/deps.
  • Expands combination-testing workflow to install deps and run lint + type-check in CI.

Reviewed changes

Copilot reviewed 32 out of 36 changed files in this pull request and generated 3 comments.

Show a summary per file
File Description
templates/webextension-react-vite-starter/tsconfig.node.json Adjust node TS config resolution + includes for webext tooling files.
templates/webextension-react-vite-starter/tsconfig.json.template Simplifies TS config includes/excludes and removes project references.
templates/webextension-react-vite-starter/package/index.js Updates build/type-check scripts to validate both app + node-side TS configs.
templates/webextension-react-vite-starter/eslint.config.mjs.template Broadens ignore glob for declaration files.
templates/webextension-react-vite-starter/[src]/popup/index.css Updates popup base styling and CSS variables.
templates/webextension-react-vite-starter/[src]/popup/Popup.tsx.template Redesigns popup UI and adds “open options” behavior.
templates/webextension-react-vite-starter/[src]/popup/Popup.css Replaces legacy App styles with new popup surface/layout styles.
templates/webextension-react-vite-starter/[src]/content/App.test.tsx Removes the content view test.
templates/webextension-react-vite-starter/.webext-config/reload/injections/view.ts Refactors visibility reload logic for readability.
templates/wdio-starter/tsconfig.json Modernizes TS target/libs and enables skipLibCheck.
templates/wdio-starter/package/index.js Introduces package.json generator for WDIO template (scripts + dev deps).
templates/wdio-starter/docs/TEST_CONFIGURATION.md.template Adds WDIO configuration documentation.
templates/wdio-starter/docs/RUNNING_TESTS.md.template Adds WDIO “running tests” documentation and CI examples.
templates/turborepo-starter/packages/ui/package.json.template Adds missing react-dom dependency to UI package.
templates/turborepo-starter/packages/eslint-config-react/package.json.template Updates React ESLint config deps to use react + hooks plugins.
templates/turborepo-starter/package/index.js Adjusts root devDependency version for eslint-config-base.
templates/turborepo-starter/apps/playground/src/stories/Header.tsx Exports HeaderProps interface.
templates/turborepo-starter/apps/playground/src/stories/Button.tsx Exports ButtonProps interface.
templates/react-vite-starter/[src]/pages/Landing.tsx.template Replaces animation-based landing with structured starter content.
templates/react-vite-starter/[src]/pages/Landing.css Replaces landing page styling with a new layout/theme.
templates/nextjs-starter/package.json Adds autoprefixer to devDependencies.
templates/nextjs-starter/[src]/app/page.tsx Replaces default Next.js landing page with CNA-branded quick-start UI.
templates/nextjs-starter/[src]/app/page.module.css Updates styles to support the redesigned landing page.
templates/nextjs-starter/[src]/app/layout.tsx Updates metadata title/description to match new starter branding.
templates/nextjs-starter/[src]/app/globals.css Simplifies CSS variables and updates background styling.
templates/nextjs-starter/[src]/feature-template/README.md.template Adds feature folder template documentation for feature-based architecture.
templates/nextjs-saas-ai-starter/package.json Updates build to skip env validation during build.
templates/nextjs-saas-ai-starter/cna.config.json Adds custom options for srcDir and projectImportPath.
templates/nestjs-starter/src/health/health.controller.ts Adds a /health endpoint controller.
templates/nestjs-starter/src/app.service.ts Replaces hello response with structured status + health responses.
templates/nestjs-starter/src/app.module.ts Registers the new HealthController.
templates/nestjs-starter/src/app.controller.ts Changes root endpoint to return status metadata.
templates/nestjs-starter/src/app.controller.spec.ts Updates test assertions for new status response.
templates.json Changes NextJS SaaS AI template type and extends extension compatibility lists.
TESTING.md Updates combo-testing documentation to include lint + type-check steps.
.github/workflows/test-combinations.yml Runs CNA in CI mode, installs deps, and executes lint + type-check in matrix tests.

💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.

Comment on lines 2 to 7
"compilerOptions": {
"composite": true,
"module": "ESNext",
"moduleResolution": "Node",
"moduleResolution": "Bundler",
"allowSyntheticDefaultImports": true,
"resolveJsonModule": true
Comment on lines 18 to 22
"devDependencies": {
"@changesets/cli": "^2.25.0",
"eslint-config-base": "*",
"eslint-config-base": "0.0.0",
"prettier": "^2.7.1",
"turbo": "^1.5.5"
@@ -13,9 +13,18 @@ describe('AppController', () => {
});

describe('getHello', () => {
Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
Copy link
Copy Markdown

@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

🧹 Nitpick comments (2)
templates/turborepo-starter/package/index.js (1)

2-2: Normalize setup.scope before composing the package name (Line 2).

This works for @my-org/, but a common input like @my-org would generate an invalid dependency name. Consider normalizing/trimming once before concatenation.

Proposed hardening
-  const eslintConfigBaseName = `${setup.scope || ''}eslint-config-base`;
+  const normalizedScope = (setup.scope || '').trim().replace(/\/?$/, '/');
+  const eslintConfigBaseName = `${normalizedScope === '/' ? '' : normalizedScope}eslint-config-base`;
🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In `@templates/turborepo-starter/package/index.js` at line 2, The package name
assembly uses setup.scope directly when building eslintConfigBaseName which
breaks for inputs like "@my-org" (missing trailing slash); normalize setup.scope
first by trimming whitespace and ensuring it either is empty or ends with a
single "/" (e.g., compute a local normalizedScope from setup.scope, trimming and
appending "/" if not present) and then use normalizedScope when building
eslintConfigBaseName so the resulting dependency name is always valid; reference
setup.scope and eslintConfigBaseName to locate the change.
templates/nextjs-starter/[src]/app/page.module.css (1)

44-44: Consider extracting repeated shadow color to a CSS variable.

The shadow color rgba(15, 23, 42, 0.08) appears in multiple places. Extracting it to a CSS variable (e.g., --shadow-color) in globals.css would improve maintainability if the shadow styling needs to change.

Also applies to: 99-99, 128-128

🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In `@templates/nextjs-starter/`[src]/app/page.module.css at line 44, The CSS
repeatedly uses the same shadow color rgba(15, 23, 42, 0.08); extract it into a
CSS variable (e.g., --shadow-color) defined in globals.css and replace the
hardcoded color in page.module.css (and the other occurrences noted) with
box-shadow using that variable; update any selectors that currently use
"box-shadow: 0 20px 45px rgba(15, 23, 42, 0.08)" to reference
var(--shadow-color) so future changes are centralized.
🤖 Prompt for all review comments with AI agents
Verify each finding against the current code and only fix it if needed.

Inline comments:
In `@templates/webextension-react-vite-starter/tsconfig.node.json`:
- Line 10: tsconfig.node.json's "include" currently lists manifest.ts and
vite.config.ts which don't exist in the template; update the include array in
tsconfig.node.json to either reference the actual template filenames
(manifest.ts.template and vite.config.ts.template) or remove those two entries
so only existing paths like .webext-config/**/*.ts remain; ensure the include
change targets the "include" array in tsconfig.node.json and mentions the
symbols manifest.ts, vite.config.ts, manifest.ts.template and
vite.config.ts.template so the right files are adjusted.

---

Nitpick comments:
In `@templates/nextjs-starter/`[src]/app/page.module.css:
- Line 44: The CSS repeatedly uses the same shadow color rgba(15, 23, 42, 0.08);
extract it into a CSS variable (e.g., --shadow-color) defined in globals.css and
replace the hardcoded color in page.module.css (and the other occurrences noted)
with box-shadow using that variable; update any selectors that currently use
"box-shadow: 0 20px 45px rgba(15, 23, 42, 0.08)" to reference
var(--shadow-color) so future changes are centralized.

In `@templates/turborepo-starter/package/index.js`:
- Line 2: The package name assembly uses setup.scope directly when building
eslintConfigBaseName which breaks for inputs like "@my-org" (missing trailing
slash); normalize setup.scope first by trimming whitespace and ensuring it
either is empty or ends with a single "/" (e.g., compute a local normalizedScope
from setup.scope, trimming and appending "/" if not present) and then use
normalizedScope when building eslintConfigBaseName so the resulting dependency
name is always valid; reference setup.scope and eslintConfigBaseName to locate
the change.

ℹ️ Review info
⚙️ Run configuration

Configuration used: defaults

Review profile: CHILL

Plan: Pro

Run ID: ea98f0af-815f-4e80-98ed-eefcb9984957

📥 Commits

Reviewing files that changed from the base of the PR and between 396266f and 21c6ee2.

📒 Files selected for processing (11)
  • templates/nestjs-starter/src/app.controller.spec.ts
  • templates/nestjs-starter/src/health/health.controller.spec.ts
  • templates/nextjs-saas-ai-starter/.github/workflows/build.yml
  • templates/nextjs-saas-ai-starter/package.json
  • templates/nextjs-starter/[src]/app/page.module.css
  • templates/react-vite-starter/[src]/pages/Landing.css
  • templates/turborepo-starter/package/index.js
  • templates/webextension-react-vite-starter/[src]/popup/Popup.css
  • templates/webextension-react-vite-starter/[src]/popup/Popup.tsx.template
  • templates/webextension-react-vite-starter/[src]/popup/index.css
  • templates/webextension-react-vite-starter/tsconfig.node.json

"vite.config.ts",
"package.json"
]
"include": [".webext-config/**/*.ts", "manifest.ts", "vite.config.ts"]
Copy link
Copy Markdown

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
# Read-only verification: confirm tsconfig.node include targets exist.
fd -H '^\.webext-config$' -t d
fd '^manifest\.ts$'
fd '^vite\.config\.ts$'

Repository: Create-Node-App/cna-templates

Length of output: 130


🏁 Script executed:

fd -H -t f 'manifest\.ts|vite\.config\.ts' templates/webextension-react-vite-starter/
ls -la templates/webextension-react-vite-starter/ | head -20

Repository: Create-Node-App/cna-templates

Length of output: 1501


🏁 Script executed:

cat -n templates/webextension-react-vite-starter/tsconfig.node.json

Repository: Create-Node-App/cna-templates

Length of output: 414


Update include paths to match actual template files or remove non-existent references.

The .webext-config/**/*.ts include exists, but manifest.ts and vite.config.ts do not exist in the template—only manifest.ts.template and vite.config.ts.template are present. Either update the include to reference the .template files or remove these entries if they are generated during project setup and should not be type-checked at template validation time.

🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In `@templates/webextension-react-vite-starter/tsconfig.node.json` at line 10,
tsconfig.node.json's "include" currently lists manifest.ts and vite.config.ts
which don't exist in the template; update the include array in
tsconfig.node.json to either reference the actual template filenames
(manifest.ts.template and vite.config.ts.template) or remove those two entries
so only existing paths like .webext-config/**/*.ts remain; ensure the include
change targets the "include" array in tsconfig.node.json and mentions the
symbols manifest.ts, vite.config.ts, manifest.ts.template and
vite.config.ts.template so the right files are adjusted.

- Add .npmrc with legacy-peer-deps=true to react-semantic-ui extension
  to fix ERESOLVE with react@19 + semantic-ui-react@2 peer deps
- Add exclude field to wdio-starter tsconfig.json to prevent tsc
  from picking up tools/danger/dangerfile.ts (missing danger dep)
- Use SKIP_ENV_VALIDATION=true for npm run build in CI to prevent
  nextjs-saas-ai-starter from requiring DATABASE_URL during build
- Remove tsconfig.json.template and eslint.config.mjs.template from
  react-testing-library-with-jest extension: these files raced with
  base template writes (Promise.all in loaders.ts) producing corrupted
  output, and the extension configs overwrote framework-specific
  settings (Next.js plugins, webextension module settings). Base
  template configs are authoritative and already correct.
- nestjs-starter/tsconfig.json: exclude ./tools/**/* to prevent TSC
  from picking up dangerfile.ts (danger module not in devDeps)
- nextjs-auth/[src]/lib/auth.ts: fix circular type in Session augment;
  use DefaultSession['user'] instead of Session['user'] (TS2502)
- turborepo-starter/packages/tsconfig/base.json: add ignoreDeprecations
  '6.0' to suppress TS5101/TS5107 for baseUrl + moduleResolution=node
- react-vite-starter/tsconfig.node.json: add electron/**/*.ts to
  include so ESLint can parse electron files with the correct tsconfig
- react-vite-starter/eslint.config.mjs.template: widen d.ts ignore
  from '*.d.ts' to '**/*.d.ts' so nested declaration files are excluded
- webextension-react-vite-starter/tsconfig.node.json: add DOM and
  DOM.Iterable to lib so .webext-config/reload/injections/view.ts can
  reference browser DOM APIs
- nextjs-saas-ai-starter/eslint.config.mjs: downgrade react-hooks v7
  strict rules (set-state-in-effect, immutability, refs) from error to
  warn to unblock build while code is updated incrementally
Copy link
Copy Markdown

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

🧹 Nitpick comments (1)
.github/workflows/test-combinations.yml (1)

121-126: Run non-mutating validation before auto-fix commands.

lint, type-check, and build currently run after format and lint:fix, so CI can pass on files that were modified after generation rather than validating the project exactly as users receive it. Move the new validation checks before mutating commands, and keep format/lint:fix only as command-smoke tests if needed.

♻️ Proposed ordering
           npm install
-          npm run format --if-present
-          npm run lint:fix --if-present
           npm run lint --if-present
           npm run type-check --if-present
           SKIP_ENV_VALIDATION=true npm run build --if-present
+          npm run format --if-present
+          npm run lint:fix --if-present

Based on learnings, validation should report lint status, type checking, and build results after template changes.

🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In @.github/workflows/test-combinations.yml around lines 121 - 126, The CI step
ordering runs mutating commands (npm run format, npm run lint:fix) before
validation, so tests can pass on modified sources; reorder the workflow steps so
non-mutating validations (npm run lint, npm run type-check,
SKIP_ENV_VALIDATION=true npm run build) execute before any mutating commands,
leaving npm run format and npm run lint:fix only as optional smoke tests
afterwards; update the sequence that currently contains the tokens "npm run
format", "npm run lint:fix", "npm run lint", "npm run type-check", and
"SKIP_ENV_VALIDATION=true npm run build" to place lint/type-check/build before
format/lint:fix.
🤖 Prompt for all review comments with AI agents
Verify each finding against the current code and only fix it if needed.

Nitpick comments:
In @.github/workflows/test-combinations.yml:
- Around line 121-126: The CI step ordering runs mutating commands (npm run
format, npm run lint:fix) before validation, so tests can pass on modified
sources; reorder the workflow steps so non-mutating validations (npm run lint,
npm run type-check, SKIP_ENV_VALIDATION=true npm run build) execute before any
mutating commands, leaving npm run format and npm run lint:fix only as optional
smoke tests afterwards; update the sequence that currently contains the tokens
"npm run format", "npm run lint:fix", "npm run lint", "npm run type-check", and
"SKIP_ENV_VALIDATION=true npm run build" to place lint/type-check/build before
format/lint:fix.

ℹ️ Review info
⚙️ Run configuration

Configuration used: defaults

Review profile: CHILL

Plan: Pro

Run ID: e0f20080-15b5-47f1-8202-1a5de3577785

📥 Commits

Reviewing files that changed from the base of the PR and between 21c6ee2 and d9e07f3.

📒 Files selected for processing (12)
  • .github/workflows/test-combinations.yml
  • extensions/nextjs-auth/[src]/lib/auth.ts
  • extensions/react-semantic-ui/.npmrc
  • extensions/react-testing-library-with-jest/eslint.config.mjs.template
  • extensions/react-testing-library-with-jest/tsconfig.json.template
  • templates/nestjs-starter/tsconfig.json
  • templates/nextjs-saas-ai-starter/eslint.config.mjs
  • templates/react-vite-starter/eslint.config.mjs.template
  • templates/react-vite-starter/tsconfig.node.json
  • templates/turborepo-starter/packages/tsconfig/base.json
  • templates/wdio-starter/tsconfig.json
  • templates/webextension-react-vite-starter/tsconfig.node.json
💤 Files with no reviewable changes (2)
  • extensions/react-testing-library-with-jest/eslint.config.mjs.template
  • extensions/react-testing-library-with-jest/tsconfig.json.template
✅ Files skipped from review due to trivial changes (6)
  • extensions/react-semantic-ui/.npmrc
  • templates/react-vite-starter/tsconfig.node.json
  • templates/nestjs-starter/tsconfig.json
  • templates/react-vite-starter/eslint.config.mjs.template
  • templates/turborepo-starter/packages/tsconfig/base.json
  • templates/webextension-react-vite-starter/tsconfig.node.json
🚧 Files skipped from review as they are similar to previous changes (1)
  • templates/wdio-starter/tsconfig.json

…js-openapi peer-deps, react-million template conflict
@ulises-jeremias ulises-jeremias merged commit 60b34c5 into main Apr 20, 2026
7 of 8 checks passed
@ulises-jeremias ulises-jeremias deleted the chore/template-audit-fixes branch April 20, 2026 01:40
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