feat(nextjs): Add --non-interactive flag for headless CLI operation#1183
feat(nextjs): Add --non-interactive flag for headless CLI operation#1183
Conversation
Add support for fully headless/automated Sentry setup without browser authentication. This enables CI/CD pipelines and AI agents to scaffold Sentry configuration with environment variable placeholders. New CLI flags: - --skip-auth: Skip authentication, use env var placeholders - --tracing: Enable performance monitoring - --replay: Enable Session Replay - --logs: Enable Sentry Logs - --tunnel-route: Enable tunnel route - --mcp-cursor/vscode/claude/opencode/jetbrains: Add MCP configs In skip-auth mode: - Config files use process.env.SENTRY_DSN / NEXT_PUBLIC_SENTRY_DSN - next.config uses process.env.SENTRY_ORG / SENTRY_PROJECT - Creates .env.example documenting required variables - MCP configs use base URL without project scope - Skips example page, CI setup, and turbopack warning
Semver Impact of This PR🟡 Minor (new features) 📋 Changelog PreviewThis is how your changes will appear in the changelog. New Features ✨Cloudflare
Mcp
Other
Bug Fixes 🐛
Build / dependencies / internal 🔧Deps
Test
Other
Other
🤖 This preview updates automatically when you update the PR. |
There was a problem hiding this comment.
Thanks for opening this PR! I think adding a non-blocking execution flow makes sense. Both for agents as well as humans :) However, I would ask that we take one of these two routes but not mix things up:
- We add a
--agentModeCLI flag which fully automates every step to make it non-blocking. It can work in conjuction with other high-level CLI flags like--tracingfor high-level options but it can be used to skip over multiple steps or change wizard behaviour however otherwise necessary - We add specific flags for each step. For example
--auth=false(or--skip-auth) controls authentication and the related code injection steps requiring dsns, project/org data etc (like right now). But in addition,--example-page=falseskips the example page,--tunnelRoutedecides whether to set tunnelRoute,--setup-cifor (not) skipping CI setup, etc.
I would personally prefer 2 because this allows to make the wizard non-blocking for non-agentic use, too. For example, we could use it in docs to customize the wizard code snippet more based on the selected features on the setup page. Same in the in-product onboarding.
I just want to avoid that a flag like --skip-auth does more than its name implies.
Likewise, I'd slightly prefer "enable" naming over "skip". So users set --example-page=false instead of --skip-example-page. This more resembles the default behaviour of the wizard in the interactive mode. Though happy to hear counter arguments here :)
WDYT?
src/nextjs/nextjs-wizard.ts
Outdated
|
|
||
| // Determine tunnel route setting | ||
| let tunnelRoute: boolean; | ||
| if (skipAuth) { |
There was a problem hiding this comment.
m: is there a reason we only apply the --tunnelRoute argument on if --skip-auth is set? I'd tend towards treating these flags independently of each other
src/nextjs/nextjs-wizard.ts
Outdated
| let shouldCreateExamplePage = false; | ||
| if (!skipAuth) { | ||
| shouldCreateExamplePage = await askShouldCreateExamplePage(); |
There was a problem hiding this comment.
m: I'd rather have this be its own flag. Nothing about --skip-auth suggests that it skips example page creation.
Instead, I suggest we do something like this:
const shouldCreateExamplePage = options.examplePage ?? await askShouldCreateExamplePage();
src/nextjs/nextjs-wizard.ts
Outdated
| // Skip turbopack warning in skip-auth mode | ||
| if (!skipAuth) { |
There was a problem hiding this comment.
m: I don't think we should skip this but rather just log the warning instead if the clack.select prompt that halts the wizard execution. My thinking is that this might even be valuable information for agents.
src/nextjs/nextjs-wizard.ts
Outdated
| // Skip CI setup in skip-auth mode | ||
| if (!skipAuth) { |
There was a problem hiding this comment.
m: same here. I think a log message that users/agents need to configure CI after the wizard finished instead of the prompt, is better than entirely skipping this step, no?
|
Also, please add an e2e test that covers the agentic setup flow so that we have a good picture of what kind of file output we expect from this flow. |
|
Oh yea, speaking of |
Address PR review feedback:
1. Revert CHANGELOG.md - use PR description instead
2. Simplify to single NEXT_PUBLIC_SENTRY_DSN env var (works for both
server and client)
3. Consolidate MCP flags into single --mcp array option:
--mcp cursor,vscode or --mcp cursor --mcp vscode
4. Make all flags work independently (not tied to --skip-auth):
- --tracing, --replay, --logs: use flag if set, prompt otherwise
- --tunnel-route: use flag if set, prompt otherwise
- --example-page: use flag if set, prompt otherwise (defaults to
false in skip-auth mode)
5. Turbopack warning: log as warning in skip-auth mode instead of skip
6. CI setup: show helpful log message in skip-auth mode instead of skip
Lms24
left a comment
There was a problem hiding this comment.
Thanks for making the changes! After thinking about this for a while, I think something like a --non-interactive or --headless flag, would make sense and could even replace --skip-auth. My thinking here:
--skip-authdoes not imply that prompts/warnings/steps requiring input are skipped--headless/--non-interactive(feel free to suggest other names) suggest skipping prompts and as a consequence authentication (at least to a point I guess xD)
WDYT?
- Add [NextJS only] prefix to all new CLI flag descriptions - Change chalk.dim to chalk.cyan for env vars in outro message - Update help-message.test.ts with new flag descriptions - Add checkFileDoesNotExist/checkFileDoesNotContain to eslint assertion functions - Fix and expand e2e tests for non-interactive mode: - Fix .env.example assertion (empty placeholders, not 'your-auth-token') - Fix config file checks (instrumentation-client.ts, not sentry.client.config.ts) - Add assertions for env var usage in config files - Add test suite for MCP configuration with base URL - Add test suite for minimal mode (no feature flags)
- Fix help-message test snapshot for mcp flag line wrapping - Add package-lock.json creation in non-interactive tests to auto-detect npm - Fix tunnel route to default to false in non-interactive mode (avoid prompt)
- Remove special case for 'all flags provided' - Build featuresToPrompt array first, then check length - Only log features when some were provided via CLI
The package-lock.json we create for npm detection shows as untracked, causing the git dirty check prompt which hangs in non-interactive mode.
In non-interactive mode, features not provided via CLI flags should default to false instead of prompting the user. This was causing the wizard to hang waiting for input in headless environments.
OpenCode uses opencode.json at project root, not .opencode/mcp.json
The npm install timeout needs to be on the 'Adding MCP configurations' expectation since that's the first output after npm install completes.
There was a problem hiding this comment.
Cursor Bugbot has reviewed your changes and found 2 potential issues.
Bugbot Autofix is OFF. To automatically fix reported issues with Cloud Agents, enable Autofix in the Cursor dashboard.
|
|
||
| Sentry.init({ | ||
| dsn: "${dsn}",${integrationsOptions}${performanceOptions}${logsOptions}${replayOptions} | ||
| dsn: ${dsnValue},${integrationsOptions}${performanceOptions}${logsOptions}${replayOptions} |
There was a problem hiding this comment.
Copy-paste snippet missing useEnvVars parameter propagation
Medium Severity
The getInstrumentationClientHookCopyPasteSnippet function doesn't accept or propagate the new useEnvVars parameter when calling getInstrumentationClientFileContents. In non-interactive mode when an instrumentation-client file already exists (or creation fails), the copy-paste instructions will incorrectly show dsn: "" instead of dsn: process.env.NEXT_PUBLIC_SENTRY_DSN. The callers in nextjs-wizard.ts at lines 926 and 942 also need to pass useEnvVars to this function.
Additional Locations (2)
| }, | ||
| spotlight, | ||
| options, | ||
| useEnvVars, |
There was a problem hiding this comment.
Wizard hangs in non-interactive mode on existing files
High Severity
Multiple interactive prompts in the wizard are not guarded by nonInteractive checks. When a project has existing _error pages, global-error pages, instrumentation files, or root layout files, the wizard calls clack.confirm or showCopyPasteInstructions which block waiting for user input. In non-interactive mode, this causes the wizard to hang indefinitely. The affected prompts include: underscore error page confirmation (lines 265, 293), global error page confirmation (line 365), root layout instructions (line 414), and instrumentation hook instructions (lines 827, 836, 924, 935).
Additional Locations (2)
Lms24
left a comment
There was a problem hiding this comment.
I think this is fine and --non-interactive sounds like a good choice. Thanks for making the hanges!
All good from my end! Before we merge this, I'd be curious on the new sentry CLI's perspective, given it's also designed for agentic use (cc @betegon). Ideally, we can scope the individual arguments to the respective wizard flows, similarly to what I sketched out in #1200, once the new CLI calls the wizard. Anyway, not a blocker to merge this into the current wizard from my PoV.
| // Create package-lock.json so npm is auto-detected (avoids package manager prompt) | ||
| createPackageLockForNpm(projectDir); |
There was a problem hiding this comment.
we should be able to bypass package manager selection with the --inon-interactive flag. Otherwise the non-interactive mode might hang here. Probably fine to fall back to npm here in case the detection fails.


Summary
Adds support for fully headless/automated Sentry setup without browser authentication. This enables CI/CD pipelines and AI agents to scaffold Sentry configuration with environment variable placeholders that can be populated later.
New CLI Flags
--skip-auth--tracing--replay--logs--tunnel-route--mcp-cursor--mcp-vscode--mcp-claude--mcp-opencode--mcp-jetbrainsExample Usage
Behavior in
--skip-authModeprocess.env.SENTRY_DSN/process.env.NEXT_PUBLIC_SENTRY_DSNnext.config.jsusesprocess.env.SENTRY_ORGandprocess.env.SENTRY_PROJECT.env.exampledocumenting all required environment variablesmcp.sentry.dev/mcp) without project scopefalse(must be explicitly enabled)Generated
.env.example# Sentry Configuration SENTRY_DSN= NEXT_PUBLIC_SENTRY_DSN= SENTRY_ORG= SENTRY_PROJECT= SENTRY_AUTH_TOKEN=Use Cases
Testing
yarn buildpassesyarn lintpassesyarn testpasses--skip-authflag in test Next.js project