Customization & Output
Repl’s output pipeline is fully composable. The same command graph produces plain text for a CI log, syntax-highlighted JSON for a terminal, and Spectre.Console tables for a rich interactive session — all without touching handler code.
Output formats
Section titled “Output formats”Every command supports output format flags out of the box:
| Flag | Format |
|---|---|
| (none) | human — plain text / table |
--output:format=json (or --json) | JSON |
--output:format=xml | XML |
--output:format=yaml | YAML |
--output:format=markdown | Markdown table |
--output:format=spectre | Spectre.Console rendering |
Format selection order
Section titled “Format selection order”--output:formatflag on the command lineReplOptions.Output.DefaultFormat(configured at startup)human(built-in default)
Set the default format
Section titled “Set the default format”app.Options(o =>{ o.Output.DefaultFormat = "json"; // all commands default to JSON});Paged result rendering
Section titled “Paged result rendering”When a command returns a ReplPage<T> or an IReplPageSource<T>, the output format determines how the page is rendered:
| Format | Rendering |
|---|---|
human / spectre (interactive TTY) | Table + integrated pager; continues fetching source pages as the user scrolls |
human / spectre (redirected stdout) | Table for the first source page; pager suppressed; nextCursor hint printed |
json / xml / yaml / markdown | Explicit page envelope: { "$type": "page", "items": [...], "pageInfo": { ... } } |
| MCP structured content | { "$type": "page", ... } in StructuredContent; text fallback via PagedResultTextMode |
The pager activates only for human and spectre on an interactive TTY. Redirected output and machine formats always receive the raw first page — use --result:cursor to advance.
See Result-Flow Paging for the full source paging model, CLI options, and MCP surface.
ANSI capability levels
Section titled “ANSI capability levels”Repl detects the terminal’s color capability at startup and chooses rendering accordingly. Detected capability tiers (informational):
| Detected tier | Rendering |
|---|---|
| No ANSI | Plain text, no escape sequences |
| Basic | 16 ANSI colors |
| Extended | 256 colors |
| TrueColor | 24-bit color |
Detection chain (first match wins):
- Session override — a hosted session can force ANSI on or off (
TerminalSessionOverrides.AnsiSupported) - Explicit
OutputOptions.AnsiMode(Always/Never) NO_COLORenv var → disable ANSICLICOLOR_FORCE=1env var → force ANSI (even when stdout is redirected)TERM=dumb→ disable ANSI- Redirection check (piped stdout → no ANSI)
Override programmatically using AnsiMode:
app.Options(o =>{ o.Output.AnsiMode = AnsiMode.Always; // force ANSI on regardless of detection // or: Auto (default — let detection decide), Never (force off)});JSON colorization
Section titled “JSON colorization”In interactive mode with ANSI support, --json output is automatically syntax-highlighted (keys in one color, strings in another, numbers in a third). No configuration required.
Render width
Section titled “Render width”Repl uses the terminal width for table column sizing, word wrap, and layout decisions.
Resolution order:
OutputOptions.PreferredWidth(explicit override)COLUMNSenvironment variable- Detected console window width
- Telnet NAWS / DTTERM resize for hosted sessions
OutputOptions.FallbackWidth(default:120)
app.Configure<OutputOptions>(o =>{ o.PreferredWidth = 160; o.FallbackWidth = 80;});Custom output transformers
Section titled “Custom output transformers”Register a transformer for a new format name:
app.Options(o =>{ o.Output.AddTransformer("csv", new CsvOutputTransformer()); o.Output.AddAlias("spreadsheet", "csv"); // both --output:format=csv and --output:format=spreadsheet work});IOutputTransformer receives the handler’s return value and returns a formatted string:
public class CsvOutputTransformer : IOutputTransformer{ public string Name => "csv";
public ValueTask<string> TransformAsync(object? value, CancellationToken ct) { var csv = value is IEnumerable<object> rows ? ToCsv(rows) : value?.ToString() ?? ""; return ValueTask.FromResult(csv); }}Suppressing the banner
Section titled “Suppressing the banner”The startup banner (shown in interactive mode) can be suppressed:
myapp --no-logoOr globally:
app.Options(o =>{ o.Output.BannerEnabled = false; // or: o.Output.BannerFormats = ["human"] — show only in human format (default)});Spectre.Console integration
Section titled “Spectre.Console integration”Add Repl.Spectre and register:
app.UseSpectreConsole(); // enables rich prompts and renderables in one callReturning renderables
Section titled “Returning renderables”Return any IRenderable from a handler — Spectre renders it automatically:
app.Map("contacts table", (IContactStore store) =>{ var table = new Table() .BorderStyle(Style.Parse("grey")) .AddColumn("[bold]Id[/]") .AddColumn("[bold]Name[/]") .AddColumn("[bold]Email[/]");
foreach (var c in store.All()) table.AddRow(c.Id.ToString(), c.Name, c.Email);
return table;});Color palette and style
Section titled “Color palette and style”Use Spectre.Console’s full Markup and Style API anywhere an IRenderable is expected:
return new Markup("[green bold]Success![/] Contact added.");return new Panel(new Markup(content)) .BorderStyle(Style.Parse("blue")) .Header("[bold]Summary[/]");Available renderables
Section titled “Available renderables”| Type | Description |
|---|---|
Table | Grid with borders, alignment, and markup |
Panel | Box with optional header and border |
Tree | Hierarchical tree view |
BarChart | Horizontal bar chart |
BreakdownChart | Proportion chart |
Calendar | Monthly calendar with highlighted dates |
JsonText | Syntax-highlighted JSON |
FigletText | Large ASCII art text |
TextPath | Breadcrumb path rendering |
Markup | Inline styled text |
Grid / Columns | Free-form layout |
Rule | Horizontal divider |
Progress / Status | Live progress widgets |
Detecting Spectre capability
Section titled “Detecting Spectre capability”Spectre rendering follows the same ANSI detection chain as the rest of the framework — no configuration required:
- Colors are emitted only when the host detection allows ANSI; otherwise the color system degrades to
NoColorsand output stays plain text. - Unicode box-drawing degrades per output sink: full Unicode borders when the sink’s encoding carries them, Spectre’s square ASCII-safe fallback on a legacy OEM codepage, and ASCII transliteration (
+,-,|) when no box glyph survives (redirected consoles, CI logs, pipes). The active verdict is exposed asSpectreTerminalDetection.CurrentBoxDrawingSupportfor diagnostics. - CI logs are plain by default — Spectre’s built-in CI enrichers are disabled so they cannot override the host detection. Set
CLICOLOR_FORCE=1in the workflow to restore colored logs.
Outside a Repl container (bare AddSpectreConsole() without UseSpectreConsole()), the profile falls back to Spectre’s own detection.
Help output formatting
Section titled “Help output formatting”Help can also be rendered in structured formats:
myapp contacts --help # human-readablemyapp contacts --help --json # machine-readable JSONThe JSON format returns a structured ReplDocumentationModel — useful for tooling, documentation generators, and agents.
IAnsiConsole injection
Section titled “IAnsiConsole injection”Repl.Spectre registers Spectre’s IAnsiConsole in DI, bound to the current session’s output stream. Inject it directly when you need full Spectre control:
app.Map("demo", (IAnsiConsole console) =>{ console.Write(new FigletText("Repl").Color(Color.Blue)); console.MarkupLine("[bold green]Ready.[/]");});This is session-safe in hosted mode — each session gets its own IAnsiConsole bound to its output stream.