When all terminal width detection methods fail (stdout.columns,
stderr.columns, COLUMNS env), the renderer falls back to the
hardcoded UNKNOWN_TERMINAL_WIDTH (40). This new `maxWidth` config
option lets users replace that fallback with a value suited to
their device — useful on mobile clients, piped subprocesses, or
terminals where auto-detection is unreliable.
When the terminal reports a real width, maxWidth is ignored.
Closes#385, closes#404
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
getProviderLabel was string-matching `anthropic.claude-` in model IDs,
which false-positived on cross-region IDs like `us.anthropic.claude-sonnet-4-6`.
Now checks `CLAUDE_CODE_USE_BEDROCK=1` env var instead.
Fixes#466
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
When running as a CC statusLine subprocess, stdout/stderr are piped and
COLUMNS may not be set. getTerminalWidth() falls back to
UNKNOWN_TERMINAL_WIDTH (40), which is not a real measurement.
Previously, this fallback value was treated as real terminal width in two
places:
- canCombine in renderExpanded(): context + usage lines were always split
because combined width exceeded 40 columns
- wrapLineToWidth in render(): all output lines were forcefully wrapped
at 40 characters, breaking the layout
Fix: introduce a widthIsReal guard that checks whether the resolved width
is the UNKNOWN_TERMINAL_WIDTH sentinel. When width is unknown:
- canCombine defaults to true (combine lines optimistically)
- wrapLineToWidth is skipped (wrapWidth=0 → no-op)
The host process (Claude Code) handles final display layout, so wrapping
at an arbitrary fallback value is harmful rather than helpful.
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
* fix: detect terminal width via stderr when stdout is piped
When Claude Code runs the statusLine as a subprocess, stdout is captured
(piped), so process.stdout.columns is undefined. With no terminal width,
long lines aren't wrapped by the HUD — the terminal wraps them silently
instead. Claude Code counts \n characters to determine how many lines to
erase on the next render, so the physical line count diverges from what
Claude Code expects. Over successive renders the cursor drifts upward into
the scrollback buffer, causing the terminal to jump to the top on every
tool execution (https://github.com/jarrodwatts/claude-hud/issues/209).
Fix: fall back to process.stderr.columns before the COLUMNS env var.
When the statusLine subprocess is spawned, only stdout is redirected;
stderr remains connected to the real TTY and returns the correct width.
With accurate width, lines are properly wrapped in the HUD output and
Claude Code's line count stays consistent.
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
* chore: drop dist artifacts and cover stderr width
---------
Co-authored-by: Claude Sonnet 4.6 <noreply@anthropic.com>
Co-authored-by: Jarrod Watts <jarrod@cubelabs.xyz>