What happened?
Auggie renders muted TUI text using Ink's dimColor prop, which compiles to the SGR 2 ("faint") attribute. SGR 2 is a terminal attribute, not a color: the emulator blends the foreground toward the background. This has two consequences that make muted text unreadable on a dark background and impossible for a user to fix:
- It is not themeable. No palette entry addresses it, so neither the
ansi theme plus terminal palette overrides, nor any default-* theme, can brighten it.
- In xterm.js-based terminals it is capped at half the configured minimum contrast ratio. xterm.js deliberately enforces half the ratio for dim text (xtermjs/xterm.js#4672, fixing #4262;
IColorSet.halfContrastCache — "Maps original colors to colors that respect half of the minimum contrast ratio"). VS Code inherits this (microsoft/vscode#190371).
Measured against the v0.36.0 bundle (augment.mjs):
| Pattern |
Count |
Effect |
dimColor total |
181 |
— |
{dimColor: true} with no color prop |
117 |
Default foreground + SGR 2; bypasses the theme entirely |
color: theme.text.muted, dimColor: true |
27 |
Theme resolves text.muted correctly, then SGR 2 re-darkens it |
The second row is the more surprising one: those sites take an already-correct, deliberately-chosen theme color and push it back toward the background in the same render call. Under the ansi theme, text.muted resolves via cc.gray → "gray" → ANSI bright black, which a user can override — and dimColor then undoes that override.
A concrete example is the ask-user question prompt's context paragraph:
context && createElement(Text, {dimColor: true}, t.context)
No color prop at all, so it is pure default-foreground + SGR 2.
What did you expect to happen?
Muted text should resolve to the active theme's text.muted slot and nothing else, so that it is (a) controlled by the theme, and (b) subject to the terminal's full minimum contrast ratio rather than half of it.
The theme system already has the right slot — text.muted is defined in every theme. The issue is that dimColor is being used as the styling primitive for "muted" either instead of, or in addition to, that slot.
Steps to reproduce
- Use a dark terminal background (e.g. VS Code default
#1e1e1e).
- Set
"theme": "ansi" in ~/.augment/settings.json — the theme intended to honor the terminal palette.
- Override the terminal palette to brighten muted text, e.g. in VS Code
settings.json:
"workbench.colorCustomizations": { "terminal.ansiBrightBlack": "#b6c2ce" }
- Start
auggie and trigger any prompt that renders context text (e.g. a tool asking a clarifying question), or observe help/hint text.
- Observe: text rendered via
text.muted alone brightens as expected. Text rendered with dimColor does not.
Isolating the mechanism directly in the same terminal:
printf '%b\n' "normal \033[2mDIM (SGR 2)\033[0m | \033[90mANSI 90\033[0m"
ANSI 90 responds to the palette override; DIM does not.
Auggie version
0.36.0 (commit 7c61e5bb)
Request ID
N/A — this is a client-side rendering/theming defect, not a request-scoped failure. No request is involved and /request-id does not apply. (Flagging this because the field is marked required by the template; happy to supply one if there is something specific you would like captured.)
Environment details
Environment
- OS: Android 17 (Google Pixel 10 Pro) — client; GitHub Codespaces (Linux, Ubuntu devcontainer) — host
- Shell: bash
- Tool/CLI version: auggie 0.36.0 (commit 7c61e5bb), Node v22.22.2
- Terminal: VS Code for the Web (xterm.js), reached via DuckDuckGo for Android (Chromium-based) → github.com/codespaces
- Theme:
ansi, terminal background #1e1e1e
Anything else we need to know?
Why the available workaround is not sufficient.
Raising terminal.integrated.minimumContrastRatio is the only lever a user has, and the half-ratio rule caps what it can achieve:
| Setting |
Resulting dim floor |
Effect on normal text (bg #1e1e1e, max achievable 16.67:1) |
| 7 (raised from default 4.5) |
3.5:1 |
No help — below where dim text already sat |
| 14 |
7.0:1 |
Works, but washes all other colors toward white |
| 18+ |
9.0:1+ |
Clamp target exceeds what the background allows; every foreground collapses to pure #ffffff and color is lost entirely |
So the only setting that makes dim text readable does so by destroying the color fidelity of everything else. There is no value that fixes muted text and preserves the theme.
This is worse outside xterm.js. On a phone the practical alternative to the browser is gh codespace ssh from a terminal app, which has no minimum-contrast-ratio feature at all. On that path there is no workaround whatsoever — SGR 2 renders however the app blends it.
Accessibility framing. 7:1 is the ceiling this approach can reach for dim text, and that is only attainable by sacrificing color. Muted text that cannot reach WCAG AA (4.5:1) independently of a global contrast override is a genuine accessibility gap, and it is most acute on a small mobile screen in variable lighting.
Suggested fix, in rough order of value:
- Replace the 117 bare
{dimColor: true} sites with color={theme.text.muted}. Directly themeable, and gets the full contrast ratio rather than half.
- Drop
dimColor from the 27 color: text.muted, dimColor: true sites — the theme slot is already doing the work, and dimColor is actively fighting it. This subset alone is a small, low-risk change.
- Optionally darken
text.muted slightly per theme to preserve the intended visual hierarchy, now that it is a real color rather than a blend.
- Optionally expose a setting (e.g.
"dimText": false) for users whose terminals render SGR 2 harshly.
Happy to test a prerelease on this setup if useful.
Investigated and drafted by an Augment agent session, reviewed and submitted on my behalf. The bundle measurements above were taken from the installed augment.mjs for v0.36.0; the xterm.js behavior was confirmed against upstream source, not inferred.
What happened?
Auggie renders muted TUI text using Ink's
dimColorprop, which compiles to the SGR 2 ("faint") attribute. SGR 2 is a terminal attribute, not a color: the emulator blends the foreground toward the background. This has two consequences that make muted text unreadable on a dark background and impossible for a user to fix:ansitheme plus terminal palette overrides, nor anydefault-*theme, can brighten it.IColorSet.halfContrastCache— "Maps original colors to colors that respect half of the minimum contrast ratio"). VS Code inherits this (microsoft/vscode#190371).Measured against the v0.36.0 bundle (
augment.mjs):dimColortotal{dimColor: true}with nocolorpropcolor: theme.text.muted, dimColor: truetext.mutedcorrectly, then SGR 2 re-darkens itThe second row is the more surprising one: those sites take an already-correct, deliberately-chosen theme color and push it back toward the background in the same render call. Under the
ansitheme,text.mutedresolves viacc.gray→"gray"→ ANSI bright black, which a user can override — anddimColorthen undoes that override.A concrete example is the
ask-userquestion prompt's context paragraph:No
colorprop at all, so it is pure default-foreground + SGR 2.What did you expect to happen?
Muted text should resolve to the active theme's
text.mutedslot and nothing else, so that it is (a) controlled by the theme, and (b) subject to the terminal's full minimum contrast ratio rather than half of it.The theme system already has the right slot —
text.mutedis defined in every theme. The issue is thatdimColoris being used as the styling primitive for "muted" either instead of, or in addition to, that slot.Steps to reproduce
#1e1e1e)."theme": "ansi"in~/.augment/settings.json— the theme intended to honor the terminal palette.settings.json:auggieand trigger any prompt that renders context text (e.g. a tool asking a clarifying question), or observe help/hint text.text.mutedalone brightens as expected. Text rendered withdimColordoes not.Isolating the mechanism directly in the same terminal:
ANSI 90responds to the palette override;DIMdoes not.Auggie version
0.36.0 (commit 7c61e5bb)
Request ID
N/A — this is a client-side rendering/theming defect, not a request-scoped failure. No request is involved and
/request-iddoes not apply. (Flagging this because the field is marked required by the template; happy to supply one if there is something specific you would like captured.)Environment details
Environment
ansi, terminal background#1e1e1eAnything else we need to know?
Why the available workaround is not sufficient.
Raising
terminal.integrated.minimumContrastRatiois the only lever a user has, and the half-ratio rule caps what it can achieve:#1e1e1e, max achievable 16.67:1)#ffffffand color is lost entirelySo the only setting that makes dim text readable does so by destroying the color fidelity of everything else. There is no value that fixes muted text and preserves the theme.
This is worse outside xterm.js. On a phone the practical alternative to the browser is
gh codespace sshfrom a terminal app, which has no minimum-contrast-ratio feature at all. On that path there is no workaround whatsoever — SGR 2 renders however the app blends it.Accessibility framing. 7:1 is the ceiling this approach can reach for dim text, and that is only attainable by sacrificing color. Muted text that cannot reach WCAG AA (4.5:1) independently of a global contrast override is a genuine accessibility gap, and it is most acute on a small mobile screen in variable lighting.
Suggested fix, in rough order of value:
{dimColor: true}sites withcolor={theme.text.muted}. Directly themeable, and gets the full contrast ratio rather than half.dimColorfrom the 27color: text.muted, dimColor: truesites — the theme slot is already doing the work, anddimColoris actively fighting it. This subset alone is a small, low-risk change.text.mutedslightly per theme to preserve the intended visual hierarchy, now that it is a real color rather than a blend."dimText": false) for users whose terminals render SGR 2 harshly.Happy to test a prerelease on this setup if useful.
Investigated and drafted by an Augment agent session, reviewed and submitted on my behalf. The bundle measurements above were taken from the installed
augment.mjsfor v0.36.0; the xterm.js behavior was confirmed against upstream source, not inferred.