Problem
When sentry init --yes output is piped or redirected (e.g., sentry init --yes | tee log.txt, or captured in CI), the output contains raw terminal control sequences that make it unreadable without heavy filtering.
The captured output includes:
- Cursor hide/show sequences (
\x1b[?25l, \x1b[?25h)
- Cursor movement codes (
\x1b[999D, \x1b[J)
- Spinner animation frames (braille characters redrawn in-place)
- ANSI color/SGR codes from picocolors
- Unicode box-drawing characters from clack's UI chrome
Example of what a CI log or pipe capture looks like:
[?25l◆ EXPERIMENTAL: This feature is experimental...
│[?25h[?25l◇ EXPERIMENTAL: This feature is experimental...
│
◇ Git working tree is clean.
│
● Scanning project...[999D[J● Connecting to wizard...[999D[J● Analyzing project structure[999D[J...
Instead of clean, readable output like:
Scanning project...
Connecting to wizard...
Analyzing project structure
Reading package.json...
Installing dependencies...
Done
Root cause
The init wizard uses @clack/prompts for its interactive UI (spinner, prompts, log messages). Clack writes raw escape sequences to stdout unconditionally — it doesn't check process.stdout.isTTY before emitting cursor movement, erase sequences, or spinner animations.
The rest of the CLI already handles this well: isPlainOutput() in src/lib/formatters/plain-detect.ts detects non-TTY contexts and gates all ANSI output, and the polling spinner in src/lib/polling.ts suppresses itself entirely when piped. But the init wizard's clack usage bypasses this system.
Expected behavior
Most modern CLIs (gh, docker, cargo) auto-detect non-TTY stdout and suppress decorations. When sentry init --yes is piped:
- No cursor movement or erase sequences
- No spinner animation (just plain status lines)
- No ANSI color codes
- Clean, grep-able output
The --yes flag already exists for non-interactive use, but the output it produces is designed for a terminal, not a log file.
Possible solution
A thin adapter module between the wizard code and @clack/prompts that checks isPlainOutput() (already exists and works) and routes to plain-text alternatives when stdout is not a TTY. The interactive prompts (select, confirm, etc.) would still pass through to real clack since they're only reached in TTY mode. This matches the pattern already used by src/lib/polling.ts.
Environment
- sentry-cli (Node/Bun CLI)
@clack/prompts v0.11.0 / @clack/core v0.5.0
- Affects any non-TTY context: pipes, redirects, CI log capture,
script sessions, IDE terminals that don't report as TTY
Problem
When
sentry init --yesoutput is piped or redirected (e.g.,sentry init --yes | tee log.txt, or captured in CI), the output contains raw terminal control sequences that make it unreadable without heavy filtering.The captured output includes:
\x1b[?25l,\x1b[?25h)\x1b[999D,\x1b[J)Example of what a CI log or pipe capture looks like:
Instead of clean, readable output like:
Root cause
The
initwizard uses@clack/promptsfor its interactive UI (spinner, prompts, log messages). Clack writes raw escape sequences to stdout unconditionally — it doesn't checkprocess.stdout.isTTYbefore emitting cursor movement, erase sequences, or spinner animations.The rest of the CLI already handles this well:
isPlainOutput()insrc/lib/formatters/plain-detect.tsdetects non-TTY contexts and gates all ANSI output, and the polling spinner insrc/lib/polling.tssuppresses itself entirely when piped. But the init wizard's clack usage bypasses this system.Expected behavior
Most modern CLIs (gh, docker, cargo) auto-detect non-TTY stdout and suppress decorations. When
sentry init --yesis piped:The
--yesflag already exists for non-interactive use, but the output it produces is designed for a terminal, not a log file.Possible solution
A thin adapter module between the wizard code and
@clack/promptsthat checksisPlainOutput()(already exists and works) and routes to plain-text alternatives when stdout is not a TTY. The interactive prompts (select,confirm, etc.) would still pass through to real clack since they're only reached in TTY mode. This matches the pattern already used bysrc/lib/polling.ts.Environment
@clack/promptsv0.11.0 /@clack/corev0.5.0scriptsessions, IDE terminals that don't report as TTY