On a fresh session Claude Code emits used_percentage=0 before any user
input, while current_usage already holds the real initial-context tokens
(system prompt, tools, memory files — ~9% on a 200k model). The HUD
was treating 0 as a valid native value and skipping the token-based
fallback, so the context bar stayed at 0% even though /context showed 9%.
Treat used_percentage=0 the same as null: fall through to the manual
calculation from current_usage. When tokens are present the bar now
reflects the true initial usage; when both are zero it still shows 0%.
Fixes#417
Adjust two test expectations to account for the trailing spaces
that paddedLabel() adds when aligning shorter labels (Usage, Weekly)
to the width of the longest label (Context = 7 chars).
When Context, Usage, and Weekly lines wrap to separate rows on narrow
terminals, their progress bars now align vertically. A shared
paddedLabel() helper pads each label with spaces to the maximum visual
width across the three labels, accounting for CJK double-width chars.
- Add src/render/lines/label-align.ts with paddedLabel() utility
- Update identity.ts and usage.ts to use paddedLabel()
- Add tests for English and Chinese label alignment
The output speed (`out: N tok/s`) only renders while stdin is actively
streaming and disappears once output ends. Placing it between git and
duration causes the surrounding elements (duration, cost) to reflow
horizontally every time speed appears or disappears — jarring visual
churn on every turn.
Moving speed to the end of the line (after cost, before customLine)
means the transient field only appends/disappears at the tail, leaving
all stable elements in place.
Applied to both renderProjectLine (expanded layout) and
renderSessionLine (compact layout) for consistency.
The macOS/Linux awk-based version sorting command uses '"'"' to nest
single quotes inside bash -c '...'. After JSON encoding/decoding in
settings.json, this quoting breaks on Windows Git Bash, causing a
silent syntax error that prevents the HUD statusline from starting.
Replace awk with sort -V (GNU version sort, included with Git for
Windows) in the Windows + Git Bash section, which avoids nested
single quotes entirely.
Fixes#326
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
When the Agent/Task tool is called without an explicit subagent_type
parameter, Claude Code's runtime defaults to the general-purpose agent
(per the Agent tool spec). The HUD only sees the transcript input and
previously fell back to the literal string 'unknown', which made
perfectly normal Agent launches look broken or untracked in the HUD's
agents line.
Flip the fallback to 'general-purpose' so the displayed label matches
the tool's actual runtime behavior.
Before: `✓ unknown: Build phase 2 agents`
After: `✓ general-purpose: Build phase 2 agents`
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>
Claude Code runs the statusLine command as a subprocess with piped
stdout/stderr, so process.stdout.columns is unavailable. Without an
explicit COLUMNS value, getTerminalWidth() falls back to the
UNKNOWN_TERMINAL_WIDTH constant and width-dependent layout (line
combining, wrapping) cannot use the real terminal dimensions.
Fix: inject COLUMNS into the generated statusLine command on all
platforms:
- macOS/Linux/WSL: `stty size </dev/tty` reads from the controlling
terminal (works even when stdout is piped)
- Windows PowerShell: `[Console]::WindowWidth` reads the console
buffer width
Both subtract 4 columns to account for Claude Code's PromptInputFooter
padding (paddingX={2}, i.e. 2 columns on each side).
Co-Authored-By: Claude Opus 4.6 (1M context) <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>
Replace the hardcoded Anthropic pricing table and estimateSessionCost()
logic with a direct read of stdin.cost.total_cost_usd — the native field
Claude Code provides after each API response.
- Add cost.* fields to StdinData type
- Extract costUsd in index.ts and pass through RenderContext
- Simplify renderCostEstimate to read ctx.costUsd directly
- Rename i18n key label.estimatedCost → label.cost
- Update label to "Cost ($USD)" / "耗油量(美元)" (zh)
- Remove dead estimateSessionCost, pricing table, and related helpers
- Update tests to use costUsd; add index.test.js coverage for the field
- Update README to reflect native field behavior
Closes#380
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
- git.ts: add LineDiff and TrackedFile interfaces; parse `git diff --numstat HEAD`
for per-file and total line diffs; build GitHub branch URL from remote
- project.ts: add renderGitFilesLine() — a dedicated HUD line that shows
modified/added/deleted files sorted by mtime, with per-file (+N -N) diffs,
OSC 8 clickable file links, max 6 files, overflow count, untracked count
- project.ts: add OSC 8 clickable hyperlink for project folder (file://) and
git branch (GitHub tree URL); show total [+N -N] on the project line
- render/index.ts: call renderGitFilesLine always-last in renderExpanded,
passing terminalWidth so the line can suppress itself on narrow terminals
- render/lines/index.ts: export renderGitFilesLine
Enabled via existing `gitStatus.showFileStats: true` config flag.