-
Notifications
You must be signed in to change notification settings - Fork 50
Description
Description
The codebase has 46 instances of raw fmt.Println(), fmt.Printf() calls without explicit stderr/stdout routing, violating Unix conventions and making output behavior unpredictable in pipes and redirects.
Problem
Current Anti-Pattern:
// ❌ Raw println - goes to stdout by default
fmt.Println(console.FormatWarningMessage("Warning message"))Correct Pattern:
// ✅ Explicit stderr routing for diagnostic output
fmt.Fprintln(os.Stderr, console.FormatWarningMessage("Warning message"))
// ✅ Explicit stdout routing for structured data
fmt.Println(string(jsonBytes)) // JSON outputImpact:
- Diagnostic messages pollute stdout, breaking pipes and output redirection
- Inconsistent behavior across CLI commands
- Violates Unix principle: data to stdout, diagnostics to stderr
Files Affected
From Terminal Stylist Analysis (#12488):
pkg/workflow/stop_after.go- 10 instancespkg/workflow/mcp_config_custom.go- 1 instancepkg/workflow/engine_firewall_support.go- 3 instancespkg/campaign/command.go- 3 instances (JSON output)pkg/cli/tool_graph.go- 1 instance (mermaid graph)- Additional ~28 instances across other files
Suggested Changes
Step 1: Replace Diagnostic Output
Replace all diagnostic/status/warning/error messages with stderr:
// Before
fmt.Println(message)
// After
fmt.Fprintln(os.Stderr, message)Step 2: Preserve Structured Output
Keep stdout ONLY for structured data (JSON, graphs, hashes):
// JSON output - keep stdout
fmt.Println(string(jsonBytes))
// Mermaid graphs - keep stdout
fmt.Println(mermaidGraph)
// Hashes - keep stdout
fmt.Println(hash)Step 3: Add Linter Rule
Add golangci-lint rule to prevent future raw fmt.Print* calls:
# .golangci.yml
linters-settings:
forbidigo:
forbid:
- 'fmt\.Println.*# use fmt.Fprintln(os.Stderr, ...) for diagnostics'
- 'fmt\.Printf.*# use fmt.Fprintf(os.Stderr, ...) for diagnostics'
exclude-godoc-examples: trueStep 4: Document Convention
Update AGENTS.md with output routing guidelines:
**Output Routing Rules (Unix Conventions):**
- **Diagnostic output** (messages, warnings, errors) → `stderr`
- **Structured data** (JSON, hashes, graphs) → `stdout`
- **Rationale**: Allows users to pipe/redirect data without diagnostic noiseSuccess Criteria
- All 46 instances of raw
fmt.Print*reviewed and fixed - Diagnostic messages routed to stderr
- JSON/graph/hash output preserved on stdout
- Linter rule added to prevent regression
- Documentation updated in AGENTS.md
- All existing tests pass
- Output redirection tested manually (e.g.,
gh aw list | jq)
Testing
# Test that JSON output goes to stdout only
gh aw list --json > output.json 2> diagnostics.txt
# output.json should have JSON, diagnostics.txt should have status messages
# Test that errors go to stderr
gh aw compile invalid.md 2> errors.txt
# errors.txt should contain error messagesSource
Extracted from Terminal Stylist Analysis discussion #12488
Discussion finding: "46 instances of raw fmt.Print* calls without explicit stderr/stdout routing. This violates Unix conventions and makes output unpredictable in pipes."
Priority
Medium - Code consistency issue affecting CLI user experience and Unix convention compliance.
AI generated by Discussion Task Miner - Code Quality Improvement Agent
- expires on Feb 6, 2026, 9:14 AM UTC