Skip to main content
Claude HUD is a statusline plugin that Claude Code invokes as a subprocess roughly every 300ms. Each invocation receives data, renders output, and exits — there is no persistent daemon.

Data flow

Claude Code → stdin JSON → parse → render lines → stdout → Claude Code displays
           ↘ transcript_path → parse JSONL → tools/agents/todos
Each render cycle:
  1. Claude Code passes session data as JSON on stdin.
  2. Claude HUD reads transcript_path from that JSON and parses the JSONL transcript for tool and agent activity.
  3. Config files and OAuth credentials are read for MCP/hooks counts and usage limits.
  4. All data is combined into a RenderContext and rendered to stdout.
  5. Claude Code displays every line Claude HUD prints.

Data sources

1. Stdin JSON

Claude Code passes a JSON object on stdin on every invocation. This data is authoritative — no estimation.
FieldDescription
model.display_nameCurrent model name (e.g. Opus)
context_window.current_usageToken counts: input_tokens, output_tokens, cache_creation_input_tokens, cache_read_input_tokens
context_window.context_window_sizeMaximum context window size
context_window.used_percentageNative usage percentage (Claude Code v2.1.6+)
context_window.remaining_percentageNative remaining percentage (Claude Code v2.1.6+)
transcript_pathAbsolute path to the session transcript file
cwdCurrent working directory
When used_percentage is present (Claude Code v2.1.6+), Claude HUD uses it directly. Otherwise it calculates (total_tokens / context_window_size) × 100.
Token counts are the sum of input_tokens, cache_creation_input_tokens, and cache_read_input_tokens. Output tokens are not counted against context usage.

2. Transcript JSONL

Claude Code writes each turn to a JSONL file at transcript_path. Claude HUD reads this file on every render cycle to extract tool and agent state. The parser (src/transcript.ts) processes each line as a JSON object and looks for tool_use and tool_result content blocks:
  • tool_use block — records the tool name, input, and start time. Creates a running entry.
  • tool_result block — matches against the tool_use by ID. Sets status to completed or error and records duration.
  • Running tools — any tool_use without a matching tool_result.
  • TodoWrite calls — the todos array in the input replaces the entire todo list.
  • Task calls — creates an agent entry with subagent_type, model, and description.
  • TaskCreate calls — appends a new todo item with subject/description and optional initial status.
  • TaskUpdate calls — updates an existing todo item’s status or content by task ID or numeric index.
The parser retains the most recent 20 tool entries and 10 agent entries per render cycle.

3. Config files

Read once per render cycle from ~/.claude/settings.json:
SourceWhat is read
settings.jsonmcpServersCount of configured MCP servers
settings.jsonhooksCount of configured hooks
CLAUDE.md filesCount of CLAUDE.md rule files found in the project hierarchy
These counts are shown in the environment line when display.showConfigCounts is true.

4. OAuth credentials and usage API

When display.showUsage is enabled (the default), Claude HUD reads your subscription usage from the Anthropic API. Credential sources (in priority order):
  1. macOS Keychain — Claude Code 2.x stores the current OAuth token here.
  2. ~/.claude/.credentials.json — fallback for older Claude Code versions and non-macOS platforms.
The credentials file contains claudeAiOauth.accessToken and claudeAiOauth.subscriptionType. Only Pro, Max, and Team subscriptions have usage limits to display; API users return null and no usage line is shown. API call:
GET https://api.anthropic.com/api/oauth/usage
Authorization: Bearer <accessToken>
anthropic-beta: oauth-2025-04-20
The response includes five_hour.utilization and seven_day.utilization as 0–100 percentages, plus resets_at timestamps. Caching: Because Claude HUD runs as a new process on every render, it uses a file-based cache at ~/.claude/plugins/claude-hud/.usage-cache.json.
ResultCache TTL
Successful response60 seconds (configurable via usage.cacheTtlSeconds)
Failed response15 seconds (configurable via usage.failureCacheTtlSeconds)
Rate-limited (429)Exponential backoff: 60s → 120s → 240s → 300s max
Skipped when:
  • ANTHROPIC_BASE_URL or ANTHROPIC_API_BASE_URL points to a non-Anthropic host (custom providers).
  • Model ID indicates AWS Bedrock (contains anthropic.claude-).

Context thresholds

The context bar color and behavior change as the context window fills:
UsageColorBehavior
< 70%GreenNormal display
70–85%YellowWarning color
> 85%RedToken breakdown shown (when display.showTokenBreakdown is true)

File structure

src/
├── index.ts           # Entry point
├── stdin.ts           # Parse Claude's JSON input
├── transcript.ts      # Parse transcript JSONL
├── config-reader.ts   # Read MCP/rules configs
├── config.ts          # Load/validate user config
├── git.ts             # Git status (branch, dirty, ahead/behind)
├── usage-api.ts       # Fetch usage from Anthropic API
├── types.ts           # TypeScript interfaces
└── render/
    ├── index.ts          # Main render coordinator
    ├── session-line.ts   # Compact mode: single line with all info
    ├── tools-line.ts     # Tool activity (opt-in)
    ├── agents-line.ts    # Agent status (opt-in)
    ├── todos-line.ts     # Todo progress (opt-in)
    ├── colors.ts         # ANSI color helpers
    └── lines/
        ├── project.ts       # Line 1: model bracket + project + git
        ├── identity.ts      # Line 2a: context bar
        ├── usage.ts         # Line 2b: usage bar
        └── environment.ts   # Config counts (opt-in)

Render coordinator

render/index.ts is the main coordinator. It selects the layout (expanded or compact), builds the list of output lines, optionally inserts a separator, then prints each line to stdout. In expanded mode, elementOrder controls which elements appear and in what order. When context and usage are adjacent in the order, they are joined on a single line with between them. In compact mode, session-line.ts renders everything onto one header line. Activity lines (tools, agents, todos) are appended after it. The coordinator also handles terminal-width wrapping: if a line exceeds the terminal width, it wraps at | or separator boundaries rather than mid-token.

Build docs developers (and LLMs) love