Status Line
The status line is a bar at the bottom of Claude Code that shows the output of a script you write.
The script gets session data as JSON on stdin, such as the model and the cost. It prints what to show on stdout.
It does not use API tokens.
Set it with the statusLine key of a user, project, local, or managed settings file. The key names the script.
To remove it, delete statusLine, or run /statusline delete.
Example
#!/bin/sh
input=$(cat)
model=$(echo "$input" | jq -r '.model.display_name')
used=$(echo "$input" | jq -r '.context_window.used_percentage // 0')
echo "$model | context ${used}%"
{
"$schema": "https://clawdipedia.cc/schemas/claude-code-settings.json",
"statusLine": {
"type": "command",
"command": "~/.claude/statusline.sh",
"padding": 1,
"refreshInterval": 30
}
}
The bar shows the model name and how full the context window is. The script also re-runs every 30 seconds.
Settings
Official page: Customize Your Status Line.
| Item | Status | What it does | How it works | Where to set it |
|---|---|---|---|---|
status | Documented: An official docs page names this item. | Kind of status line | Must be "command". Required | User, project, local, managed |
status | Documented: An official docs page names this item. | Script path or inline shell command | Runs in a shell. A change to it runs the new command at once, without the debounce | Same |
status | Documented: An official docs page names this item. | Extra horizontal space in characters | The default is 0. It adds to the built-in spacing | Same |
status | Documented: An official docs page names this item. | Re-runs the command every N seconds | The minimum is 1. The bundle uses Math. ms. It suits clocks and idle sessions | Same |
status | Documented: An official docs page names this item. | Hides the built-in -- text | Use it when the script prints vim. itself | Same |
subagent | Documented: An official docs page names this item. | Custom row for each subagent in the agent panel | It has the fields type ("command") and command. See the next section | Same |
/ | Documented: An official docs page names this item. | Writes a script in ~/. and the setting | It takes natural language. / removes it | Interactive |
| Workspace trust | Documented: An official docs page names this item. | The command waits for trust | -- logs Status line command skipped: | Project files |
CLAUDE_ | Documented: An official docs page names this item. | Status line commands do not load | Managed policy still applies | Env |
Two hook settings also act on the status line. disableAllHooks set outside managed settings leaves only a managed statusLine. With no managed statusLine, the status line is off. allowManagedHooksOnly shows only a managed statusLine. A custom one then disappears without a warning. Their rows are on Hooks, Plugins, and Skills Settings.
When the Script Runs
| Item | Status | What it does | How it works | Where to set it |
|---|---|---|---|---|
| Session start and resume | Documented: An official docs page names this item. | First run | Runs once | Each session |
New assistant message, / done, permission mode change, vim mode toggle | Documented: An official docs page names this item. | Re-runs the command | Claude Code debounces it at 300ms. A new trigger cancels a running script | Each session |
Rate-limit resets_ and cache expires_ | Documented: An official docs page names this item. | Re-runs at the earliest time | The time comes from the data the script last received | Each session |
| Model, fast mode, effort, thinking, and PR status change | Differs: The official docs and the program disagree. The row says how. | Also re-run the command | The bundle watches main, fast, effort, thinking, pr. The list in the docs does not name them | Each session |
Output Rules
- Each printed line is a row. ANSI colors and OSC 8 links work.
- The output shows only after exit code
0. A non-zero exit or empty output blanks the line. - Claude Code sets
COLUMNSandLINESbefore it runs thestatusLinescript.tput colsdoes not work. ThesubagentStatusLinecommand does not get them (checked in the interactive screen). It getscolumnsin its JSON. - Claude Code sets the variables
CLAUDECODEandCLAUDE_CODE_CHILD_SESSIONin the script process. See Environment Variables. claude --debuglogsstderrof each run and the exit code of the first run.- The line hides during the help menu and permission prompts. The command does not run while a permission or MCP input dialog is open (checked). Outside fullscreen, notifications share the row.
- On Windows, use forward slashes in
command.CLAUDE_CODE_POWERSHELL_RESPECT_EXECUTION_POLICYchanges the PowerShell policy flag.
Source for this list: the official Customize Your Status Line and Environment Variables pages.
Subagent Status Line
subagentStatusLine customizes each subagent row in the agent panel.
Its command runs once per refresh tick (a fixed 5 seconds, checked in the interactive screen). It gets all visible rows as one JSON object.
It prints one JSON line for each row it wants to override: {"id": "<task id>", "content": "<row body>"}.
A row without id keeps the default. An empty content hides the row.
The same trust, disableAllHooks, and allowManagedHooksOnly gates apply.
A plugin can ship a default subagentStatusLine in its settings.json.
The input fields are in the Subagent Task Fields table below.
JSON Fields
These fields arrive on stdin. A field marked "may be absent" is missing from the JSON when it has no value.
Always read optional fields with a default, for example jq -r '.vim.mode // empty'.
Session and Model Fields
| Field | Status | What it holds | Notes | Where |
|---|---|---|---|---|
session_ | Documented: An official docs page names this item. | Session id | String | Status line |
session_ | Documented: An official docs page names this item. | Custom name or AI title | May be absent. The default display name does not fill it | Status line |
prompt_ | Documented: An official docs page names this item. | UUID of the prompt in work | May be absent before the first input | Status line |
transcript_ | Documented: An official docs page names this item. | Transcript file path | String | Status line |
cwd | Documented: An official docs page names this item. | Working directory | Same value as workspace. | Status line |
version | Documented: An official docs page names this item. | Claude Code version | 2. here | Status line |
model., model. | Documented: An official docs page names this item. | Model id and name | Strings | Status line |
output_ | Documented: An official docs page names this item. | Active style name | default when none. See Output Styles | Status line |
fast_ | Documented: An official docs page names this item. | Fast mode on | Boolean | Status line |
effort. | Documented: An official docs page names this item. | low, medium, high, xhigh, max | May be absent when the model has no effort | Status line |
thinking. | Documented: An official docs page names this item. | Extended thinking on | Boolean | Status line |
vim. | Documented: An official docs page names this item. | NORMAL, INSERT, VISUAL, VISUAL LINE | May be absent. Present when vim mode is on | Status line |
agent. | Documented: An official docs page names this item. | Agent name | Present with -- or agent settings | Status line |
agent_ | Undocumented: Only the program shows this item. It can change without notice. | Agent type of the main thread | Present with -- or agent settings. The same value hooks get as agent_. The built-in statusline- agent's prompt calls it agent.. Read it at the top level as agent_ | Status line, subagent |
scratchpad_ | Gated: Works only behind a flag or a server gate. tengu_scratch, or the artifact tools | The session scratchpad folder | Present when the server flag tengu_ is on, or when the session may use the artifact tools | Status line, subagent |
remote. | Undocumented: Only the program shows this item. It can change without notice. | Id of a remote session | Present when the session is remote. The docs do not list remote | Status line |
Workspace Fields
| Field | Status | What it holds | Notes | Where |
|---|---|---|---|---|
workspace. | Documented: An official docs page names this item. | Current directory | Preferred over cwd | Status line |
workspace. | Documented: An official docs page names this item. | Launch directory | The bundle fills it from the original cwd | Status line |
workspace. | Documented: An official docs page names this item. | Directories from / or -- | It is an empty array if there are none | Status line |
workspace. | Documented: An official docs page names this item. | Linked worktree name | It is absent in the main tree | Status line |
workspace., ., . | Documented: An official docs page names this item. | Repository identity from origin | May be absent. GitLab subgroups give a slash path in owner | Status line |
worktree., ., ., ., . | Documented: An official docs page names this item. | Worktree session data | Only in a worktree session. branch and original_ may be absent for hook-based worktrees | Status line |
pr., pr. | Documented: An official docs page names this item. | Open PR or GitLab merge request | Claude Code removes it once the PR merges or closes | Status line |
pr. | Documented: An official docs page names this item. | approved, pending, changes_, draft | May be absent alone | Status line |
pr. | Documented: An official docs page names this item. | mr for a GitLab merge request | Absent for GitHub | Status line |
Cost, Context, and Limit Fields
| Field | Status | What it holds | Notes | Where |
|---|---|---|---|---|
cost. | Documented: An official docs page names this item. | Estimated cost | It is a client-side list price. It resets at / | Status line |
cost., cost. | Documented: An official docs page names this item. | Wall time and API wait time | Milliseconds | Status line |
cost., cost. | Documented: An official docs page names this item. | Lines changed | Numbers | Status line |
context_, . | Documented: An official docs page names this item. | Tokens in the window | It comes from the last response. It is 0 before that | Status line |
context_ | Documented: An official docs page names this item. | Window size | 200000 or 1000000 | Status line |
context_, . | Documented: An official docs page names this item. | Percent used and left | It counts input tokens only. It may be null early | Status line |
context_ | Documented: An official docs page names this item. | Per-category tokens | Keys input_, output_, cache_, cache_. null before the first call and after / | Status line |
exceeds_ | Documented: An official docs page names this item. | Last response is over 200k tokens | It is a fixed threshold | Status line |
rate_, . | Documented: An official docs page names this item. | used_ and resets_ | Claude.ai Pro and Max only. A window drops after its reset time | Status line |
rate_, . | Documented: An official docs page names this item. | Gateway spend limit | Needs 2. | Status line |
rate_, ., . | Documented: An official docs page names this item. | Spend in dollars and period daily, weekly, monthly | Needs 2.. Off with CLAUDE_ | Status line |
Prompt Cache Fields
The object prompt_cache appears after the first main-conversation response (needs 2.1.251). Subagent requests are not counted.
| Field | Status | What it holds | Notes | Where |
|---|---|---|---|---|
prompt_ | Documented: An official docs page names this item. | Cache is within its TTL | Boolean | Status line |
prompt_ | Documented: An official docs page names this item. | Any response reported cache tokens | false means caching is off or not reported | Status line |
prompt_ | Documented: An official docs page names this item. | Cache lifetime | "5m" or "1h" | Status line |
prompt_ | Documented: An official docs page names this item. | When the cache goes cold | Epoch seconds. null if no cache tokens | Status line |
prompt_, ., . | Documented: An official docs page names this item. | Request and miss counts | A miss is over 5% and at least 2,000 tokens re-processed | Status line |
prompt_ | Documented: An official docs page names this item. | Cache reads over all input tokens | The value is 0 to 1. It is null when counts are zero | Status line |
prompt_, . | Documented: An official docs page names this item. | Tokens written | Totals for the session and for misses | Status line |
prompt_ | Documented: An official docs page names this item. | Time of the last miss | Epoch seconds. null if none | Status line |
prompt_ | Documented: An official docs page names this item. | Likely cause | causes array (such as tools_, system_, ttl_, likely_), plus tools_, tools_, system_. Needs 2. | Status line |
prompt_ | Documented: An official docs page names this item. | Count per cause | Map | Status line |
prompt_ | Documented: An official docs page names this item. | Tokens a cold cache re-caches | null after a compaction until the next request | Status line |
Subagent Task Fields
The subagentStatusLine command gets session_id, transcript_path, cwd, prompt_id, agent_type and scratchpad_dir when they are set, columns, and a tasks array.
| Field | Status | What it holds | Notes | Where |
|---|---|---|---|---|
columns | Documented: An official docs page names this item. | Usable row width | Number | subagent |
tasks[]. | Documented: An official docs page names this item. | Task id | Echo it back as id | subagent |
tasks[]. | Documented: An official docs page names this item. | Address name | Optional | subagent |
tasks[]. | Documented: An official docs page names this item. | Kind of task | local_ | subagent |
tasks[]. | Documented: An official docs page names this item. | Subagent type | Same value as hook agent_. Needs 2. | subagent |
tasks[]. | Documented: An official docs page names this item. | State | running, completed, failed, killed | subagent |
tasks[]., tasks[]. | Documented: An official docs page names this item. | Short text | label is a progress summary. Otherwise it is description | subagent |
tasks[]. | Documented: An official docs page names this item. | Start time | Epoch milliseconds | subagent |
tasks[]., tasks[]. | Documented: An official docs page names this item. | Resolved model and its window | Optional | subagent |
tasks[]. | Documented: An official docs page names this item. | Configured effort | String or number. Needs 2. | subagent |
tasks[]., tasks[]. | Documented: An official docs page names this item. | Running tokens and up to 16 samples | Oldest first | subagent |
tasks[]. | Documented: An official docs page names this item. | Subagent working directory | This is the worktree of the subagent, if it has one | subagent |
How It Works
Checked in the interactive screen (2.1.305, local stub, fake key, clean environment). See Interactive Probes.
subagentStatusLineruns on a fixed 5-second tick while the agent panel has tasks. The tick is 4.99 to 5.02 seconds over 5 intervals, after a first interval of 4.69 seconds. It also runs for tasks that arecompleted. It is not debounced likestatusLine. No setting changes the 5 seconds. The first run came when the agent started.- Its command does not get
COLUMNSandLINES. Use thecolumnsfield (194 on a 200-column screen). Claude Code setsCLAUDECODEandCLAUDE_CODE_CHILD_SESSION. - Its input holds only
session_id,transcript_path,cwd,prompt_id,columns, andtasks, not the fullstatusLineobject. The agent panel drew a row override{"id": ..., "content": "..."}. - For
statusLine,transcript_pathis present from the first run, before any message.prompt_idis absent until the first prompt. Then it is the same UUID asprompt_idin hook input. After the first reply, the input also gainsprompt_cache.current_usageis no longernull. statusLineruns once at start and once after the first reply (not at prompt submit). Three mode changes gave one run, 0.33 seconds after the last one. This held both when sent 100 ms apart and when sent in one write. This fits the 300 ms debounce.refreshInterval: 3ran every 3.0 seconds (3.0 to 3.1 seconds over 14 intervals in a run with no other trigger).- Runs paused while a permission or MCP input dialog was on screen. A Bash permission dialog was on screen for 17.4 seconds. The gap between runs was 19.3 seconds.
padding: 1gave a one-space indent, and two printed lines showed as two rows under the prompt.- With no subagents,
subagentStatusLinedid not run. In a session left idle for 29.6 seconds its command had not run once. The first run came when a background agent started. - A test agent finished at once. The command kept its 5-second tick for 29.7 seconds after the agent started (7 runs, all with the tasks
completed). Then it did not run again for the next 29 seconds. The input listed three tasks, because the stub answers every request that has no tool result yet with the sameAgentcall.
Exact Fields
The exact fields are in https://clawdipedia.cc/schemas/claude-code-status-line.json. The program builds this payload in code, not with a validator, so the schema comes from that code. A field marked x-unverified has a type the code does not show. x-observed marks a field that a probe saw.
It lists every field of this release. Build on the fields it names. Look each one up there before you rely on it.
Related Pages
- Output Styles for the style behind
output_style.name. - Environment Variables
- Context and Compaction for what
context_windowcounts. - Request and Cache for what
prompt_cachemeasures.