From c984b14b8f872eec51bad4ef92cbad76b4dcaa25 Mon Sep 17 00:00:00 2001 From: anirudhwarrier <12178754+anirudhwarrier@users.noreply.github.com> Date: Thu, 1 Oct 2026 00:00:12 +0400 Subject: [PATCH 1/3] feat(ui): allow routing stdout helpers to stderr Lets commands that emit machine-readable output keep stdout free of progress and status lines from shared flows. Co-Authored-By: Claude Sonnet 5.5 --- internal/ui/output.go | 43 +++++++++++++++------ internal/ui/output_test.go | 79 ++++++++++++++++++++++++++++++++++++++ 2 files changed, 110 insertions(+), 12 deletions(-) create mode 100644 internal/ui/output_test.go diff --git a/internal/ui/output.go b/internal/ui/output.go index 96f747bb..9fe2fcb9 100644 --- a/internal/ui/output.go +++ b/internal/ui/output.go @@ -2,7 +2,9 @@ package ui import ( "fmt" + "io" "os" + "sync/atomic" ) // verbose disables animated UI components (spinners) to avoid @@ -14,17 +16,34 @@ func SetVerbose(v bool) { verbose = v } +// stdoutToStderr is read on every write so tests that swap os.Stdout/os.Stderr keep working. +var stdoutToStderr atomic.Bool + +func stdout() io.Writer { + if stdoutToStderr.Load() { + return os.Stderr + } + return os.Stdout +} + +// RedirectStdoutToStderr sends the stdout helpers below to stderr so machine-readable +// output can be the only thing on stdout. Call the returned func to restore. +func RedirectStdoutToStderr() (restore func()) { + prev := stdoutToStderr.Swap(true) + return func() { stdoutToStderr.Store(prev) } +} + // Output helpers - use these for consistent styled output across commands. // These functions make it easy to migrate from raw fmt.Println calls. // Title prints a styled title/header (high visibility - Chainlink Blue) func Title(text string) { - fmt.Println(TitleStyle.Render(text)) + fmt.Fprintln(stdout(), TitleStyle.Render(text)) } // Success prints a success message with checkmark (Green) func Success(text string) { - fmt.Println(SuccessStyle.Render("✓ " + text)) + fmt.Fprintln(stdout(), SuccessStyle.Render("✓ "+text)) } // Error prints an error message to stderr (Orange - high contrast) @@ -67,7 +86,7 @@ func WarningWithSuggestions(text string, suggestions []string) { // Dim prints dimmed/secondary text (Gray - less important) func Dim(text string) { - fmt.Println(DimStyle.Render(" " + text)) + fmt.Fprintln(stdout(), DimStyle.Render(" "+text)) } // EnvContext prints a dim "Environment: