feat(init): detect agent/CI environments and skip interactive prompts#1264
feat(init): detect agent/CI environments and skip interactive prompts#1264
Conversation
Uses `std-env` v4's `isAgent`, `isCI`, and `hasTTY` to automatically detect when the CLI is run non-interactively (AI agents, CI pipelines, piped input) and apply sensible defaults instead of hanging on prompts. Adds two explicit flags for opt-in: - `--defaults` / `-y`: accept all defaults (like `npm init -y`) - `--no-interactive`: same, more explicit for scripting contexts When non-interactive mode is detected, the CLI: - Logs the reason (agent name, CI, no TTY, or flag) - Displays a full options reference — including all available templates fetched live — so agents can discover flags and re-run with custom settings - Auto-selects: template=minimal, dir=template's defaultDir, package manager=detected or npm, gitInit=false, modules=skipped - Fails fast (instead of hanging) when the target directory already exists, instructing the caller to pass `--force` All existing interactive behaviour is preserved when a TTY is present and none of the new flags are set. https://claude.ai/code/session_01LsDZBSg7peDmxh6QW33ag8
- Move detectCurrentPackageManager() before template load so package manager is known upfront - Compute all effective defaults (template, dir, pm, gitInit, install, modules) before any action is taken and display them together in a 'Proceeding with:' section at the bottom of the options note - Show all available templates with the default marked (← default) - Fix module examples to use @nuxt/content,@nuxt/ui,@nuxt/image - Remove scattered 'Auto-selected X' log lines — they are now covered by the single consolidated note - Simplify the non-interactive module-skip branch https://claude.ai/code/session_01LsDZBSg7peDmxh6QW33ag8
When running non-interactively (agent/CI/no-TTY) without a project directory, show the available options note then exit cleanly instead of proceeding with defaults. The agent reads the output, chooses the right flags, and re-runs with an explicit <dir>. nuxi init → shows options, exits (no project created) nuxi init my-app → creates my-app with defaults nuxi init my-app -t v3 → creates my-app with v3 template https://claude.ai/code/session_01LsDZBSg7peDmxh6QW33ag8
commit: |
📝 WalkthroughWalkthroughAdds Estimated code review effort🎯 3 (Moderate) | ⏱️ ~20 minutes 🚥 Pre-merge checks | ✅ 3✅ Passed checks (3 passed)
✏️ Tip: You can configure your own custom pre-merge checks in the settings. ✨ 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 |
There was a problem hiding this comment.
Actionable comments posted: 1
🧹 Nitpick comments (1)
packages/nuxi/src/commands/init.ts (1)
174-223: Consider centralizing resolved defaults to avoid drift between “note” and execution paths.Effective values are computed in the note block and then re-derived later for actual execution. A single
resolvedOptionsobject would reduce maintenance risk.Also applies to: 236-240, 271-276, 443-448, 465-469
🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed. In `@packages/nuxi/src/commands/init.ts` around lines 174 - 223, Create a single resolvedOptions object (e.g. { template, dir, packageManager, gitInit, install, modules, offline, force }) computed once in init.ts and replace the duplicated local computations (the variables effectiveTemplate, effectiveDir, effectivePM, effectiveGitInit, effectiveInstall, effectiveModules) so both the non-interactive "note" block and the later execution paths reuse the same resolvedOptions; update all referenced sites (the note block and the other duplicated ranges you flagged around lines 236-240, 271-276, 443-448, 465-469) to read from resolvedOptions to avoid drift and ensure consistent defaults across the codepaths.
🤖 Prompt for all review comments with AI agents
Verify each finding against the current code and only fix it if needed.
Inline comments:
In `@packages/nuxi/src/commands/init.ts`:
- Around line 130-135: The multiline boolean assignment for const
isNonInteractive (and the other multiline boolean expression further down) has
inconsistent indentation that breaks ESLint; reformat these expressions so
continuation lines are consistently indented — either align each boolean operand
under the first operand or wrap the RHS in parentheses and indent each
subsequent line one level (e.g., two spaces or one tab) so the operators (||)
and the operands line up consistently; update the lines that contain
isNonInteractive and the similar boolean block near the later expression to
match the project's multiline indentation style.
---
Nitpick comments:
In `@packages/nuxi/src/commands/init.ts`:
- Around line 174-223: Create a single resolvedOptions object (e.g. { template,
dir, packageManager, gitInit, install, modules, offline, force }) computed once
in init.ts and replace the duplicated local computations (the variables
effectiveTemplate, effectiveDir, effectivePM, effectiveGitInit,
effectiveInstall, effectiveModules) so both the non-interactive "note" block and
the later execution paths reuse the same resolvedOptions; update all referenced
sites (the note block and the other duplicated ranges you flagged around lines
236-240, 271-276, 443-448, 465-469) to read from resolvedOptions to avoid drift
and ensure consistent defaults across the codepaths.
🪄 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: Organization UI
Review profile: CHILL
Plan: Pro
Run ID: dfda46aa-f2f3-4a95-b0f4-36571b8806e5
📒 Files selected for processing (1)
packages/nuxi/src/commands/init.ts
…ndition The original condition (!template || !dir) already covers every case where templates need to be loaded for prompts or the options note. Adding isNonInteractive caused an unnecessary network fetch when an agent provided both --template and dir (only to populate a template list in the note that wasn't needed). The 'Proceeding with:' section in the note still works correctly without it. https://claude.ai/code/session_01LsDZBSg7peDmxh6QW33ag8
There was a problem hiding this comment.
Actionable comments posted: 1
🧹 Nitpick comments (1)
packages/nuxi/src/commands/init.ts (1)
188-189: Consider extracting the string 'false' coercion pattern.The
(ctx.args.gitInit as unknown) === 'false'pattern appears multiple times (here, line 465, line 487). A small helper liketoBool(value)could reduce duplication and clarify intent.♻️ Optional: Extract helper function
// Add near the top of the file or in a shared utils function parseBoolArg(value: unknown): boolean | undefined { if (value === 'false') return false if (value === 'true') return true return value as boolean | undefined }🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed. In `@packages/nuxi/src/commands/init.ts` around lines 188 - 189, The code duplicates a string-'false' coercion pattern when computing effectiveGitInit and effectiveInstall; extract a small helper (e.g., parseBoolArg or toBool) that accepts unknown and returns boolean | undefined by mapping 'false'->false, 'true'->true and otherwise returning the value as boolean | undefined, then replace the inline checks in effectiveGitInit and effectiveInstall (and any other occurrences like the ones noted around lines using ctx.args.gitInit / ctx.args.install) to call that helper to reduce duplication and clarify intent.
🤖 Prompt for all review comments with AI agents
Verify each finding against the current code and only fix it if needed.
Inline comments:
In `@packages/nuxi/src/commands/init.ts`:
- Around line 274-276: The if-branch that sets dir = defaultDir when
isNonInteractive is unreachable and should be removed; locate the conditional
using isNonInteractive and dir (the block "if (isNonInteractive) { dir =
defaultDir }") in the init command and delete that branch so the code flow
relies on the existing early-exit behavior around ctx.args.dir, or if you intend
non-interactive to auto-select a directory instead, adjust the earlier
early-exit logic that checks ctx.args.dir rather than keeping this unreachable
fallback.
---
Nitpick comments:
In `@packages/nuxi/src/commands/init.ts`:
- Around line 188-189: The code duplicates a string-'false' coercion pattern
when computing effectiveGitInit and effectiveInstall; extract a small helper
(e.g., parseBoolArg or toBool) that accepts unknown and returns boolean |
undefined by mapping 'false'->false, 'true'->true and otherwise returning the
value as boolean | undefined, then replace the inline checks in effectiveGitInit
and effectiveInstall (and any other occurrences like the ones noted around lines
using ctx.args.gitInit / ctx.args.install) to call that helper to reduce
duplication and clarify intent.
🪄 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: Organization UI
Review profile: CHILL
Plan: Pro
Run ID: 3ee15017-9503-4ce1-a8d1-f4ac2d4094fc
📒 Files selected for processing (1)
packages/nuxi/src/commands/init.ts
📦 Bundle Size Comparison📈 nuxi
📈 nuxt-cli
📈 create-nuxt
|
There was a problem hiding this comment.
🧹 Nitpick comments (1)
packages/nuxi/src/commands/init.ts (1)
188-189: Minor style inconsistency in type casting.Lines 188 and 460 handle the string
'false'from citty differently:
- Line 188:
(ctx.args.gitInit as unknown) === 'false'- Line 460:
ctx.args.gitInit === 'false' as unknownBoth work, but the inconsistency could cause confusion. Consider unifying the pattern.
🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed. In `@packages/nuxi/src/commands/init.ts` around lines 188 - 189, The code inconsistently casts ctx.args.gitInit to check for the string 'false' (used in effectiveGitInit) versus casting the comparison in another place; standardize the pattern by using the same explicit cast/location for the comparison across usages (e.g., always cast ctx.args.gitInit to unknown or string before comparing), update the check in the effectiveGitInit assignment to match the other occurrence so both use the same style, and ensure any related checks (like effectiveInstall) follow the same casting convention; specifically look for and update references to effectiveGitInit and ctx.args.gitInit to use the unified pattern.
🤖 Prompt for all review comments with AI agents
Verify each finding against the current code and only fix it if needed.
Nitpick comments:
In `@packages/nuxi/src/commands/init.ts`:
- Around line 188-189: The code inconsistently casts ctx.args.gitInit to check
for the string 'false' (used in effectiveGitInit) versus casting the comparison
in another place; standardize the pattern by using the same explicit
cast/location for the comparison across usages (e.g., always cast
ctx.args.gitInit to unknown or string before comparing), update the check in the
effectiveGitInit assignment to match the other occurrence so both use the same
style, and ensure any related checks (like effectiveInstall) follow the same
casting convention; specifically look for and update references to
effectiveGitInit and ctx.args.gitInit to use the unified pattern.
ℹ️ Review info
⚙️ Run configuration
Configuration used: Organization UI
Review profile: CHILL
Plan: Pro
Run ID: 4c6de8bf-3229-4e24-9d31-ef760881db95
📒 Files selected for processing (1)
packages/nuxi/src/commands/init.ts
|
Good to be reviewed @danielroe |
Uses
std-envv4'sisAgent,isCI, andhasTTYto automaticallydetect when the CLI is run non-interactively (AI agents, CI pipelines,
piped input) and apply sensible defaults instead of hanging on prompts.
Adds two explicit flags for opt-in:
--defaults/-y: accept all defaults (likenpm init -y)--no-interactive: same, more explicit for scripting contextsWhen non-interactive mode is detected, the CLI:
fetched live — so agents can discover flags and re-run with custom
settings
manager=detected or npm, gitInit=false, modules=skipped
exists, instructing the caller to pass
--forceAll existing interactive behaviour is preserved when a TTY is present
and none of the new flags are set.