Skip to content
ConsoleMonster

Accessibility

Accessible output, reduced motion, high-contrast and colour-blind palettes, and meaning that never depends on colour alone.

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 wantSetWhat changes
Output a screen reader followsCONSOLEMONSTER_ACCESSIBLE=1Prompts 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 layoutCONSOLEMONSTER_MOTION=reducedSpinners show a static glyph and the screen redraws at most once a second; the final state is kept.
No colourNO_COLOR=1Colour goes, the layout and status words stay.
High contrastCONSOLEMONSTER_THEME=highcontrastThe high-contrast palette. On Windows it is chosen automatically when High Contrast is on and no theme is set.
Colour-blind safeCONSOLEMONSTER_THEME=colorblindA 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.

NO_COLOR=1 PowerShell 7.6
CONSOLEMONSTER_MODE=plain PowerShell 7.6
PowerShellformat-consoletable.ps1
# 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 }
) -ShowTotals
Full 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 }
) -ShowTotals
NO_COLOR=1 keeps the layout and the status words; CONSOLEMONSTER_MODE=plain also switches to ASCII.

High contrast

Dark Theme.Dark
HighContrast Theme.HighContrast
PowerShellsummary.ps1
$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
Full 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
C#Program.cs
// 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" });
C# fluentProgram.cs
// 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();
The same summary in 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:

CI=true, NO_COLOR=1 PowerShell 7100 columnsWindows
PowerShellprofile.ps1
# 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 { "  $_" }
Stream narration: one line per change, no redraws, no colour.

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.

Edit this page on GitHub