[Opus 5.5]๐ my-appโ main*โโโโโโโโโโ42% ctx$0.84+120 -14โฑ 23m5h 37%7d 12%effort:highExplanatoryNORMALPR #42fix-login-bug14:05v2.1.300Tick to add, use the arrows to reorder.
Preview (sample data)
#!/usr/bin/env bash
# Claude Code status line
# Generated at https://www.claudecodeagents.com/tools/statusline-generator
# Needs jq. Claude Code pipes session JSON to stdin and shows what this prints.
input=$(cat)
j() { printf '%s' "$input" | jq -r "$1" 2>/dev/null; }
DIR=$(j '.workspace.current_dir // .cwd // empty'); DIR=${DIR:-$PWD}
SEP=" | "
COLOR=1
out=""
add() {
[ -z "$2" ] && return
local text="$2"
[ "$COLOR" = 1 ] && text=$(printf '\033[%sm%s\033[0m' "$1" "$2")
if [ -z "$out" ]; then out="$text"; else out="$out$SEP$text"; fi
}
# Model
V=$(j '.model.display_name // empty'); [ -n "$V" ] && V="[$V]"
add 36 "$V"
# Folder
V="๐ ${DIR##*/}"
add 34 "$V"
# Git branch (with * when dirty)
V=$(git -C "$DIR" branch --show-current 2>/dev/null); if [ -n "$V" ]; then [ -n "$(git -C "$DIR" status --porcelain 2>/dev/null | head -1)" ] && V="$V*"; V="โ $V"; fi
add 32 "$V"
# Context bar
P=$(j '(.context_window.used_percentage // 0) | floor'); F=$((P / 10)); V=""; for i in 1 2 3 4 5 6 7 8 9 10; do if [ "$i" -le "$F" ]; then V="$Vโ"; else V="$Vโ"; fi; done
add 33 "$V"
# Context used %
V="$(j '(.context_window.used_percentage // 0) | floor')% ctx"
add 33 "$V"
# Session cost
V=$(printf '$%.2f' "$(j '.cost.total_cost_usd // 0')")
add 35 "$V"
printf '%s\n' "$out"
chmod +x ~/.claude/statusline.sh. Requires jq.{
"statusLine": {
"type": "command",
"command": "~/.claude/statusline.sh"
}
}
Fields your script can read
Claude Code sends this JSON on stdin each time the status line updates. Read any field with jq -r '.field.name'.
model.id, model.display_nameCurrent model identifier and display namecwd, workspace.current_dirCurrent working directory. Both fields contain the same value; workspace.current_dir is preferred for consistency with workspace.project_dir.workspace.project_dirDirectory where Claude Code was launched, which may differ from cwd if the working directory changes during a sessionworkspace.added_dirsAdditional directories added via /add-dir or --add-dir. Empty array if none have been addedworkspace.git_worktreeGit worktree name when the current directory is inside a linked worktree created with git worktree add. Absent in the main working tree. Populated for any git worktree, unlike worktree.*, which is present only while the session is in a worktree sessionworkspace.repo.host, workspace.repo.owner, workspace.repo.nameRepository identity parsed from the origin remote, for example, "github.com", "anthropics", "claude-code". Absent outside a git repository or when no origin remote is configured. For a gitlab.com project nested in subgroups, owner is the full namespace path with slashes, such as "group/subgroup". Before v2.1.260, workspace.repo was absent for these projectscost.total_cost_usdEstimated session cost in USD, computed client-side at list price unless a modelPricing table is in effect. May differ from your actual bill. Resets to \$0 when /clear starts a new sessioncost.total_duration_msTotal wall-clock time the session has been running, in milliseconds. Accumulates across resumes and doesn't include time while the session isn't runningcost.total_api_duration_msTotal time spent waiting for API responses in millisecondscost.total_lines_added, cost.total_lines_removedLines of code changedcontext_window.total_input_tokens, context_window.total_output_tokensToken counts currently in the context window, from the most recent API response. Input includes cache reads and writescontext_window.context_window_sizeMaximum context window size in tokens. 200000 by default, or 1000000 for models with extended context.context_window.used_percentagePre-calculated percentage of context window usedcontext_window.remaining_percentagePre-calculated percentage of context window remainingcontext_window.current_usageToken counts from the last API call, described in context window fieldsexceeds_200k_tokensWhether the total token count (input, cache, and output tokens combined) from the most recent API response exceeds 200k. This is a fixed threshold regardless of actual context window size.fast_modeWhether fast mode is enabled for the sessioneffort.levelReasoning effort level set for the session (low, medium, high, xhigh, or max), not one that a skill, a subagent, or ultrathink set. If you set a level the model doesn't support, this shows the level Claude Code ran instead. A level you change shows here even before it starts. With a level in CLAUDE_CODE_EFFORT_LEVEL, this shows that level. Absent when the current model does not support the effort parameterthinking.enabledWhether extended thinking is enabled for the sessionrate_limits.five_hour.used_percentage, rate_limits.seven_day.used_percentagePercentage of the 5-hour or 7-day rate limit consumed, from 0 to 100rate_limits.five_hour.resets_at, rate_limits.seven_day.resets_atUnix epoch seconds when the 5-hour or 7-day rate limit window resetsrate_limits.spend_limit.used_percentage, rate_limits.spend_limit.resets_atBehind a Claude apps gateway, how much of your spend limit you have used and when its period resets. See spend limit fields. Requires Claude Code v2.1.251 or laterrate_limits.spend_limit.used_usd, rate_limits.spend_limit.limit_usd, rate_limits.spend_limit.periodYour estimated spend and your limit in US dollars, and the limit's period. These fields can be absent. See spend limit fields. Requires v2.1.284 or later on both Claude Code and the gatewayprompt_cacheThe session's prompt cache statistics for the main conversation: hit ratio, misses, and whether the cache is warm. See prompt cache fields for every field. Absent until the main conversation's first API response. Requires Claude Code v2.1.251 or latersession_idUnique session identifiersession_nameSession name. Uses the custom name set with the --name flag or /rename when one exists, otherwise the AI-generated session title. The default display name, such as my-app-3f, doesn't populate this field. Absent when the session has neither a custom name nor an AI-generated titleprompt_idUUID identifying the user prompt currently being processed. Matches the prompt.id attribute on OpenTelemetry events. Absent until the first user inputtranscript_pathPath to conversation transcript fileversionClaude Code versionoutput_style.nameName of the current output stylevim.modeCurrent vim mode (NORMAL, INSERT, VISUAL, or VISUAL LINE) when vim mode is enabledagent.nameAgent name when running with the --agent flag or agent settings configuredpr.number, pr.urlOpen pull request for the current branch. Mirrors the PR badge in the footer. In a repository with a GitLab remote, Claude Code fills these fields from the branch's open merge request instead, so pr.number is the merge request number. Merge request data requires Claude Code v2.1.234 or later. Absent when not in a git repository, until a pull request or merge request is found, or once it merges or closespr.review_stateReview status of the open PR: approved, pending, changes_requested, or draft. May be independently absent even when pr is presentpr.kindmr when pr describes a GitLab merge request. Absent for GitHub pull requests, so scripts written before this field keep working. For a merge request, Claude Code sets review_state to approved when GitLab reports it mergeable, pending for any other open state, and draft for a draft. Requires Claude Code v2.1.234 or laterworktree.nameName of the active worktree. Present only while the session is in a worktree sessionworktree.pathAbsolute path to the worktree directoryworktree.branchGit branch name for the worktree (for example, "worktree-my-feature"). Absent for hook-based worktreesworktree.original_cwdThe directory Claude was in before entering the worktreeworktree.original_branchGit branch checked out before entering the worktree. Absent for hook-based worktreesPrefer an off-the-shelf one? Browse community status lines in the mods directory.
Frequently asked questions
How do I customise the Claude Code status line?
Point the statusLine setting at a script: {"statusLine": {"type": "command", "command": "~/.claude/statusline.sh"}}. Claude Code runs it with session JSON on stdin and shows whatever it prints. Build the script above, or run /statusline and describe what you want.
Can the status line show context window usage?
Yes. The JSON includes context_window.used_percentage and remaining_percentage, so a script can print a percentage or a bar. Tick "Context used %" or "Context bar" above.
Can it show my Claude usage limits?
On Pro and Max plans the JSON includes rate_limits.five_hour.used_percentage and rate_limits.seven_day.used_percentage, plus when each window resets. The fields are absent when they do not apply, and the generated script then hides the segment.
Does the status line use tokens?
No. The script runs locally on your machine and does not call the API, so it costs nothing. It re-runs when a new message arrives, after /compact, when the permission mode changes and on an optional refreshInterval.
Why does my status line show strange characters?
Your terminal is not interpreting ANSI colour codes or does not have a font with the symbols. Untick ANSI colours, or swap the symbols in the script for plain text.
Sources: Status line docs. Claude Code Agents is an independent site, not affiliated with Anthropic.