Problem statement
When using gocli-based tools in scripts, CI pipelines, or alongside tools like jq, there is no standard way to get structured output. Every tool that wants JSON output today must implement its own ad-hoc formatting, bypassing the Ui abstraction entirely. This means the composable Ui layer — the whole point of the abstraction — gets abandoned the moment a caller needs machine-readable output.
Proposed solution
Add a JsonUi implementation of the Ui interface that serializes each write call as a JSON object to stdout, and wire a top-level --output flag on CLI to activate it.
// JsonUi wraps any Ui and emits newline-delimited JSON to the writer.
type JsonUi struct {
Writer io.Writer
}
// Each Ui method emits: {"level":"output","message":"..."}
func (u *JsonUi) Output(msg string) error {
return u.write("output", msg)
}
func (u *JsonUi) Info(msg string) { u.write("info", msg) }
func (u *JsonUi) Warn(msg string) { u.write("warn", msg) }
func (u *JsonUi) Error(msg string) { u.write("error", msg) }
// CLI wires it via the existing OutputFormat field:
cli := &CLI{
Args: os.Args[1:],
OutputFormat: OutputFormatJSON, // new constant
Commands: commands,
}
Alternatives considered
No response
Would this be a breaking change?
No — fully backward compatible
Additional context
No response
Problem statement
When using gocli-based tools in scripts, CI pipelines, or alongside tools like jq, there is no standard way to get structured output. Every tool that wants JSON output today must implement its own ad-hoc formatting, bypassing the Ui abstraction entirely. This means the composable Ui layer — the whole point of the abstraction — gets abandoned the moment a caller needs machine-readable output.
Proposed solution
Alternatives considered
No response
Would this be a breaking change?
No — fully backward compatible
Additional context
No response