ConsoleMonster's output works for people who use a screen reader, need high contrast, can't tell red from green or find motion distracting. Each of these is a setting you turn on once, for the whole session; nothing in your script changes.
| You want | Set | What changes |
|---|---|---|
| Output a screen reader follows | CONSOLEMONSTER_ACCESSIBLE=1 | Prompts ask numbered questions, apps, menus and grids show static or numbered views, live sessions narrate on new lines instead of redrawing, status symbols always show and motion is reduced. |
| Less movement, same layout | CONSOLEMONSTER_MOTION=reduced | Spinners show a static glyph and the screen redraws at most once a second; the final state is kept. |
| No colour | NO_COLOR=1 | Colour goes, the layout and status words stay. |
| High contrast | CONSOLEMONSTER_THEME=highcontrast | The high-contrast palette. On Windows it is chosen automatically when High Contrast is on and no theme is set. |
| Colour-blind safe | CONSOLEMONSTER_THEME=colorblind | A palette that keeps pass, warning and failure apart without relying on red and green. |
Meaning never depends on colour
Every status carries a symbol or a word as well as a colour: in tables, status lists, trees, gauges, bars, calendars, flows and diagrams. Focus is shown with a pointer, reverse video or brackets, so you can see where you are with every colour removed. Without colour, chart series get their own marks and the legend shows them.
Build artifacts ╭─────────────────────────────┬─────────┬──────────┬────────┬──────────────────────────────────────╮ │ Name │ Size │ Built in │ Signed │ Path │ ├─ Module · 2 ────────────────┼─────────┼──────────┼────────┼──────────────────────────────────────┤ │ ConsoleMonster-2.0.0.zip │ 2.77 MB │ 12 s │ ✓ yes │ D:\Builds\ConsoleM…Monster-2.0.0.zip │ │ Docs.zip │ 50.1 KB │ 1.2 s │ – no │ D:\Builds\ConsoleM…r\Packed\Docs.zip │ │ Subtotal │ 2.82 MB │ 13 s │ │ │ ├─ NuGet · 2 ─────────────────┼─────────┼──────────┼────────┼──────────────────────────────────────┤ │ ConsoleMonster.2.0.0.nupkg │ 1.41 MB │ 48 s │ ✓ yes │ D:\Builds\ConsoleM…nster.2.0.0.nupkg │ │ ConsoleMonster.2.0.0.snupkg │ 393 KB │ 3.1 s │ ✓ yes │ D:\Builds\ConsoleM…ster.2.0.0.snupkg │ │ Subtotal │ 1.8 MB │ 51 s │ │ │ ├─────────────────────────────┼─────────┼──────────┼────────┼──────────────────────────────────────┤ │ Total │ 4.62 MB │ 1 m 04 s │ │ │ ╰─────────────────────────────┴─────────┴──────────┴────────┴──────────────────────────────────────╯
Build artifacts +-----------------------------+---------+----------+--------+--------------------------------------+ | Name | Size | Built in | Signed | Path | +- Module - 2 ----------------+---------+----------+--------+--------------------------------------+ | ConsoleMonster-2.0.0.zip | 2.77 MB | 12 s | yes | D:\Builds\Console...onster-2.0.0.zip | | Docs.zip | 50.1 KB | 1.2 s | no | D:\Builds\Console...\Packed\Docs.zip | | Subtotal | 2.82 MB | 13 s | | | +- NuGet - 2 -----------------+---------+----------+--------+--------------------------------------+ | ConsoleMonster.2.0.0.nupkg | 1.41 MB | 48 s | yes | D:\Builds\Console...ster.2.0.0.nupkg | | ConsoleMonster.2.0.0.snupkg | 393 KB | 3.1 s | yes | D:\Builds\Console...ter.2.0.0.snupkg | | Subtotal | 1.8 MB | 51 s | | | +-----------------------------+---------+----------+--------+--------------------------------------+ | Total | 4.62 MB | 1 m 04 s | | | +-----------------------------+---------+----------+--------+--------------------------------------+
# Build artifacts as a module build reports them.
$artifacts = @(
[pscustomobject] @{ Name = 'ConsoleMonster.2.0.0.nupkg'; Kind = 'NuGet'; Length = 1482113
Time = [timespan]::FromSeconds(48.2); Signed = $true
Path = 'D:\Builds\ConsoleMonster\Packed\ConsoleMonster.2.0.0.nupkg' }
[pscustomobject] @{ Name = 'ConsoleMonster.2.0.0.snupkg'; Kind = 'NuGet'; Length = 402331
Time = [timespan]::FromSeconds(3.1); Signed = $true
Path = 'D:\Builds\ConsoleMonster\Packed\ConsoleMonster.2.0.0.snupkg' }
# … 6 more lines in the full program
)
$artifacts | Show-ConsoleTable -Title '[bold]Build artifacts[/]' -GroupBy Kind -Property @(
@{ Name = 'Name'; Key = $true; Overflow = 'Never' }
@{ Name = 'Length'; Header = 'Size'; Presenter = 'Bytes'; Priority = 9; Aggregate = 'Sum' }
@{ Name = 'Time'; Header = 'Built in'; Presenter = 'Duration'; Priority = 6; Aggregate = 'Sum' }
@{ Name = 'Signed'; Presenter = 'Boolean'; Priority = 5 }
@{ Name = 'Path'; Overflow = 'TruncateMiddle'; Priority = 1; MinWidth = 20 }
) -ShowTotalsFull program
Import-Module ConsoleMonster
# Build artifacts as a module build reports them.
$artifacts = @(
[pscustomobject] @{ Name = 'ConsoleMonster.2.0.0.nupkg'; Kind = 'NuGet'; Length = 1482113
Time = [timespan]::FromSeconds(48.2); Signed = $true
Path = 'D:\Builds\ConsoleMonster\Packed\ConsoleMonster.2.0.0.nupkg' }
[pscustomobject] @{ Name = 'ConsoleMonster.2.0.0.snupkg'; Kind = 'NuGet'; Length = 402331
Time = [timespan]::FromSeconds(3.1); Signed = $true
Path = 'D:\Builds\ConsoleMonster\Packed\ConsoleMonster.2.0.0.snupkg' }
[pscustomobject] @{ Name = 'ConsoleMonster-2.0.0.zip'; Kind = 'Module'; Length = 2904576
Time = [timespan]::FromSeconds(11.7); Signed = $true
Path = 'D:\Builds\ConsoleMonster\Packed\ConsoleMonster-2.0.0.zip' }
[pscustomobject] @{ Name = 'Docs.zip'; Kind = 'Module'; Length = 51302
Time = [timespan]::FromSeconds(1.2); Signed = $false
Path = 'D:\Builds\ConsoleMonster\Packed\Docs.zip' }
)
$artifacts | Show-ConsoleTable -Title '[bold]Build artifacts[/]' -GroupBy Kind -Property @(
@{ Name = 'Name'; Key = $true; Overflow = 'Never' }
@{ Name = 'Length'; Header = 'Size'; Presenter = 'Bytes'; Priority = 9; Aggregate = 'Sum' }
@{ Name = 'Time'; Header = 'Built in'; Presenter = 'Duration'; Priority = 6; Aggregate = 'Sum' }
@{ Name = 'Signed'; Presenter = 'Boolean'; Priority = 5 }
@{ Name = 'Path'; Overflow = 'TruncateMiddle'; Priority = 1; MinWidth = 20 }
) -ShowTotalsNO_COLOR=1 keeps the layout and the status words; CONSOLEMONSTER_MODE=plain also switches to ASCII.High contrast
╭─ Nightly checks ─────── lab01.contoso.com ─╮ │ ✓ Discover 2.1s › ✓ Collect 14s │ │ ⠋ Evaluate 64% │ │ ███████████████████████████████████▓▓▓▓▒▒░ │ │ █ ✓ Passed 412 82% │ │ ▓ ▴ Warnings 51 10% │ │ ▒ ✗ Failed 23 5% │ │ ░ – Skipped 14 3% │ │ rules/s ▃▃▃▃▄▄▄▄▅▅▅▆▅▆▇▆▇▇▇█ 57/s │ ╰────────────────────────────────────────────╯
╭─ Nightly checks ─────── lab01.contoso.com ─╮ │ ✓ Discover 2.1s › ✓ Collect 14s │ │ ⠋ Evaluate 64% │ │ ███████████████████████████████████▓▓▓▓▒▒░ │ │ █ ✓ Passed 412 82% │ │ ▓ ▴ Warnings 51 10% │ │ ▒ ✗ Failed 23 5% │ │ ░ – Skipped 14 3% │ │ rules/s ▃▃▃▃▄▄▄▄▅▅▅▆▅▆▇▆▇▇▇█ 57/s │ ╰────────────────────────────────────────────╯
$rate = 18, 21, 19, 24, 27, 26, 31, 29, 34, 38, 36, 41, 39, 44, 47, 45, 50, 48, 53, 57
New-ConsolePanel -Title '[bold]Nightly checks[/]' -HeaderRight 'lab01.contoso.com' -Content {
New-ConsoleRows -Content {
New-ConsoleStatusList -Layout Strip -WidgetId phases -Content {
[pscustomobject] @{ Key = 'Discover'; Label = 'Discover'; Status = 'Pass'
Detail = '2.1s' }
[pscustomobject] @{ Key = 'Collect'; Label = 'Collect'; Status = 'Pass'
Detail = '14s' }
[pscustomobject] @{ Key = 'Evaluate'; Label = 'Evaluate'; Status = 'Running'
Detail = '64%' }
}
New-ConsoleChart -Type Stacked -Content {
[pscustomobject] @{ Label = 'Passed'; Value = 412; Role = 'Pass' }
[pscustomobject] @{ Label = 'Warnings'; Value = 51; Role = 'Warn' }
[pscustomobject] @{ Label = 'Failed'; Value = 23; Role = 'Fail' }
[pscustomobject] @{ Label = 'Skipped'; Value = 14; Role = 'Skip' }
}
New-ConsoleChart -Type Sparkline -Title 'rules/s' -Unit '/s' -InputObject $rate
}
} | Show-ConsoleFull program
Import-Module ConsoleMonster
$rate = 18, 21, 19, 24, 27, 26, 31, 29, 34, 38, 36, 41, 39, 44, 47, 45, 50, 48, 53, 57
New-ConsolePanel -Title '[bold]Nightly checks[/]' -HeaderRight 'lab01.contoso.com' -Content {
New-ConsoleRows -Content {
New-ConsoleStatusList -Layout Strip -WidgetId phases -Content {
[pscustomobject] @{ Key = 'Discover'; Label = 'Discover'; Status = 'Pass'
Detail = '2.1s' }
[pscustomobject] @{ Key = 'Collect'; Label = 'Collect'; Status = 'Pass'
Detail = '14s' }
[pscustomobject] @{ Key = 'Evaluate'; Label = 'Evaluate'; Status = 'Running'
Detail = '64%' }
}
New-ConsoleChart -Type Stacked -Content {
[pscustomobject] @{ Label = 'Passed'; Value = 412; Role = 'Pass' }
[pscustomobject] @{ Label = 'Warnings'; Value = 51; Role = 'Warn' }
[pscustomobject] @{ Label = 'Failed'; Value = 23; Role = 'Fail' }
[pscustomobject] @{ Label = 'Skipped'; Value = 14; Role = 'Skip' }
}
New-ConsoleChart -Type Sparkline -Title 'rules/s' -Unit '/s' -InputObject $rate
}
} | Show-Console// One assessment summary: phases, results as a stacked bar and the rule rate as a sparkline, in a panel.
double[] rate = { 18, 21, 19, 24, 27, 26, 31, 29, 34, 38, 36, 41, 39, 44, 47, 45, 50, 48, 53, 57 };
Terminal.Write(new Panel(
new Rows()
.Add(new Phases()
.Set("Discover", StatusKind.Pass, default, "2.1s")
.Set("Collect", StatusKind.Pass, default, "14s")
.Set("Evaluate", StatusKind.Running, default, "64%"))
.Add(new StackedBar()
.Add("Passed", 412, ThemeToken.Pass)
.Add("Warnings", 51, ThemeToken.Warn)
.Add("Failed", 23, ThemeToken.Fail)
.Add("Skipped", 14, ThemeToken.Skip))
.Add(new Sparkline() { Title = "rules/s", Unit = "/s" }.AddRange(rate)),
"[bold]Nightly checks[/]") { HeaderRight = "lab01.contoso.com" });Full program
using ConsoleMonster;
using ConsoleMonster.Layout;
using ConsoleMonster.Styling;
using ConsoleMonster.Widgets;
// One assessment summary: phases, results as a stacked bar and the rule rate as a sparkline, in a panel.
double[] rate = { 18, 21, 19, 24, 27, 26, 31, 29, 34, 38, 36, 41, 39, 44, 47, 45, 50, 48, 53, 57 };
Terminal.Write(new Panel(
new Rows()
.Add(new Phases()
.Set("Discover", StatusKind.Pass, default, "2.1s")
.Set("Collect", StatusKind.Pass, default, "14s")
.Set("Evaluate", StatusKind.Running, default, "64%"))
.Add(new StackedBar()
.Add("Passed", 412, ThemeToken.Pass)
.Add("Warnings", 51, ThemeToken.Warn)
.Add("Failed", 23, ThemeToken.Fail)
.Add("Skipped", 14, ThemeToken.Skip))
.Add(new Sparkline() { Title = "rules/s", Unit = "/s" }.AddRange(rate)),
"[bold]Nightly checks[/]") { HeaderRight = "lab01.contoso.com" });// One assessment summary: phases, results as a stacked bar and the rule rate as a sparkline, in a panel.
double[] rate = { 18, 21, 19, 24, 27, 26, 31, 29, 34, 38, 36, 41, 39, 44, 47, 45, 50, 48, 53, 57 };
Ui.Panel().Title("[bold]Nightly checks[/]").HeaderRight("lab01.contoso.com").Content(c =>
{
c.Rows(r => r.Add(Ui.Phases()
.Set("Discover", StatusKind.Pass, default, "2.1s")
.Set("Collect", StatusKind.Pass, default, "14s")
.Set("Evaluate", StatusKind.Running, default, "64%"))
.Add(((StackedBar)Ui.Chart()
.Type(ChartType.Stacked)
.Build()).Add("Passed", 412, ThemeToken.Pass)
.Add("Warnings", 51, ThemeToken.Warn)
.Add("Failed", 23, ThemeToken.Fail)
.Add("Skipped", 14, ThemeToken.Skip))
.Add(((Sparkline)Ui.Chart()
.Type(ChartType.Sparkline)
.Title("rules/s")
.Unit("/s")
.Build()).AddRange(rate)));
}).Show();
Full program
using ConsoleMonster;
using ConsoleMonster.Layout;
using ConsoleMonster.Styling;
using ConsoleMonster.Widgets;
// One assessment summary: phases, results as a stacked bar and the rule rate as a sparkline, in a panel.
double[] rate = { 18, 21, 19, 24, 27, 26, 31, 29, 34, 38, 36, 41, 39, 44, 47, 45, 50, 48, 53, 57 };
Ui.Panel().Title("[bold]Nightly checks[/]").HeaderRight("lab01.contoso.com").Content(c =>
{
c.Rows(r => r.Add(Ui.Phases()
.Set("Discover", StatusKind.Pass, default, "2.1s")
.Set("Collect", StatusKind.Pass, default, "14s")
.Set("Evaluate", StatusKind.Running, default, "64%"))
.Add(((StackedBar)Ui.Chart()
.Type(ChartType.Stacked)
.Build()).Add("Passed", 412, ThemeToken.Pass)
.Add("Warnings", 51, ThemeToken.Warn)
.Add("Failed", 23, ThemeToken.Fail)
.Add("Skipped", 14, ThemeToken.Skip))
.Add(((Sparkline)Ui.Chart()
.Type(ChartType.Sparkline)
.Title("rules/s")
.Unit("/s")
.Build()).AddRange(rate)));
}).Show();
Theme.Dark and Theme.HighContrast.In code, Theme.HighContrast and Theme.ColorBlindSafe are the same palettes, and a theme file can start from either.
Accessible output
CONSOLEMONSTER_ACCESSIBLE=1 is meant for the whole session, for example in a PowerShell profile. A single prompt can ask for it with -Mode Accessible, and in C# InteractiveOptions.Default.Mode = InteractionMode.Accessible applies it everywhere. Explicit requests for rich or live output don't override it.
Live sessions in accessible mode write one line per change, the same narration they use in CI logs and redirected output:
This console Mode Stream ColorDepth – None Glyphs Basic Width 100 Height 40 ThemePreference Dark FontFace Consolas accessible: False reduced motion: False CONSOLEMONSTER_EMOJI_WIDTH: 2 CONSOLEMONSTER_AMBIGUOUS_WIDTH: 1 hyperlinks: False (terminal/CONSOLEMONSTER_HYPERLINKS; requires interactive VT, never redirected o r CI) mode: Stream (CI environment) colour: None (NO_COLOR) glyphs: Basic (stream/CI) VT: supported kind: Conhost width profile: emoji=2, ambiguous=1, zwj=Joined, flag=2, text=1 (environment) probe widths: False theme preference: Dark (CONSOLEMONSTER_THEME) culture: en-US (CONSOLEMONSTER_CULTURE) size: 100x40 (visible window or defaults) images: None (CI output gets the placeholder; terminal: HalfBlock, no image protocol advertised)
# What ConsoleMonster detected about this console, and why.
$capability = Get-ConsoleCapability
$capability |
Show-Console -View List -Title 'This console' -Property Mode, ColorDepth, Glyphs, Width, Height,
ThemePreference, FontFace
$capability.Decisions | ForEach-Object { " $_" }Full program
Import-Module ConsoleMonster
# What ConsoleMonster detected about this console, and why.
$capability = Get-ConsoleCapability
$capability |
Show-Console -View List -Title 'This console' -Property Mode, ColorDepth, Glyphs, Width, Height,
ThemePreference, FontFace
$capability.Decisions | ForEach-Object { " $_" }Reduced motion
CONSOLEMONSTER_MOTION=reduced is for people who want the normal dashboard without the movement. LiveSessionOptions.ReducedMotion and ConsoleAppOptions.ReducedMotion set it in code, and -ReducedMotion on Show-ConsoleApp, Invoke-ConsoleDashboard, Use-ConsoleProgress, Start-ConsoleRun, Invoke-ConsoleRun and Watch-Console sets it for one call. Accessible mode always implies it.
Next
Environment overrides lists every variable, and themes shows the palettes and theme files.