Zero-Configuration Terminal Output: Write Once, Works Everywhere
Atmos now features intelligent terminal output that adapts to any environment automatically. Developers can write code assuming a full-featured terminal, and Atmos handles the rest - capability detection, color adaptation, and secret masking happen transparently. No more capability checking, manual color detection, or masking code. Just write clean, simple output code and it works everywhere.
The Problem with Traditional CLI Output
Most CLI tools force developers to make painful choices:
// Traditional approach - painful!
if isatty.IsTerminal(os.Stdout.Fd()) {
// Using Charm Bracelet's lipgloss for styling
successStyle := lipgloss.NewStyle().Foreground(lipgloss.Color("10"))
fmt.Println(successStyle.Render("Success!"))
} else {
fmt.Println("Success!") // Plain for pipes
}
// And don't forget to mask secrets!
if containsSecret(output) {
output = maskSecrets(output)
}
fmt.Println(output)
What Existing Solutions Don't Solve
While Charm Bracelet's Lip Gloss and similar libraries handle rendering beautifully (styled components, layouts, colors), they don't solve critical infrastructure CLI challenges:
- Secret Masking: No automatic redaction of sensitive data across all output channels
- Centralized I/O Control: Output scattered across stdout/stderr without unified masking
- Security-First Design: Secrets can leak through unmasked channels or error messages
- Atmos-Specific Requirements: Infrastructure tools handle AWS keys, API tokens, and sensitive configs that must never appear in logs
This leads to:
- 🚫 Duplicated capability checking throughout the codebase
- 🚫 Inconsistent output behavior across commands
- 🚫 Secrets accidentally leaked to logs (the primary driver for this work)
- 🚫 Broken pipelines when output assumptions change
- 🚫 Difficult testing (mocking TTY detection is painful)
The Atmos Solution: Write Once, Works Everywhere
Atmos's I/O system complements Charm Bracelet by adding the infrastructure-critical layer that rendering libraries don't provide: centralized I/O control with automatic secret masking. Lip Gloss handles the beautiful rendering; Atmos ensures that rendering never exposes sensitive data.
With Atmos's new I/O system, developers write code once:
// Atmos approach - simple!
ui.Success("Deployment complete!")
That's it. No capability checking, no color detection, no TTY handling. The system automatically:
🎨 Color Degradation
- TrueColor terminal (iTerm2, Windows Terminal): Full 24-bit colors
- 256-color terminal: 256-color palette
- 16-color terminal (basic xterm): ANSI colors
- No color (CI,
NO_COLOR=1, pipes): Plain text
📏 Width Adaptation
- Wide terminal (120+ cols): Uses full width with proper wrapping
- Narrow terminal (80 cols): Wraps at 80 characters
- Config override: Respects
atmos.yamlsettings.terminal.max_width - Unknown width: Sensible defaults
🔍 TTY Detection
- Interactive terminal: Full styling, colors, icons, formatting
- Piped (
atmos deploy | tee): Plain text automatically - Redirected (
atmos > file): Plain text automatically - CI environment: Detects CI and disables interactivity
