A progressive tutorial for Claude Code users. The first half is beginner-friendly, explaining exactly "what to press and what to expect" at each step; the second half equips intermediate users with technical principles, hook protocols, payload schemas, caching mechanisms, Custom Commands, Powerline integration, and troubleshooting. By the end, you will upgrade from merely "knowing how to use it" to "knowing how to modify, tune, and connect external data."
Table of Contents
- I. What is ccstatusline
- II. Technical Principles: Claude Code's statusLine Hook
- III. Installation
- IV. TUI Operations Quick Reference
- V. 12-Step Beginner Tutorial
- VI. All Available Widgets Overview
- VII. Complete settings.json Field Breakdown
- VIII. Advanced Usage
- IX. Custom Commands: Integrating External Scripts
- X. Powerline Beautification
- XI. Performance & Caching Mechanisms
- XII. Debugging & Troubleshooting
- XIII. Q&A Quick Reference
- XIV. Backup & Multi-Machine Synchronization
I. What is ccstatusline
ccstatusline is an open-source status line formatter created by Matthew Breedlove (@sirmalloc), specifically designed for the Claude Code CLI. Its core concept is:
- Claude Code supports a
statusLinecommand hook insettings.json, which sends the current session's JSON information to your command via stdin; ccstatuslinereceives this JSON, renders one or more lines of status text based on your preset "widgets," and returns it to Claude Code via stdout to be displayed at the bottom status bar.
Key features:
- 40+ Built-in Widgets: Model name, total tokens, Git branch/changes, session duration, session cost, 5-hour block timer, weekly usage, memory usage, custom text, etc.
- Multi-line Layout: Originally capped at 3 lines, the line limit has been removed since v2.0.11.
- Powerline Style: Arrow separators, start/end caps, auto-alignment.
- TUI Configuration Interface: An interactive terminal UI based on React/Ink, allowing instant previews as you configure.
- Zero-Config Ready: Run
npx ccstatuslinedirectly. All changes are made through the TUI, requiring no manual JSON editing. - Cross-Platform: macOS / Linux / Windows / WSL; compatible with both Node and Bun.

II. Technical Principles: Claude Code's statusLine Hook
Before understanding ccstatusline, it is essential to understand how it is "invoked." This section is highly recommended for intermediate users; beginners can skip it for now and return later.
2.1 Hook Registration: Claude Code Side
Claude Code reads ~/.claude/settings.json and identifies the statusLine field:
{
"statusLine": {
"type": "command",
"command": "ccstatusline",
"padding": 0,
"refreshInterval": 10
}
}
Field definitions:
| Field | Type | Description |
|------|------|------|
| `type` | `"command"` | The only supported type, indicating execution via a child process. |
| `command` | string | The shell command; can be `ccstatusline`, `npx -y ccstatusline@latest`, or `bunx -y ccstatusline@latest`. |
| `padding` | number | Number of blank columns on the left, default is 0. |
| `refreshInterval` | 1–60 (seconds) | Refresh interval, supported only in Claude Code ≥ 2.1.97. |
### 2.2 Invocation Lifecycle
Every time Claude Code needs to refresh the status line (triggered by an event or timer), it will:
1. Spawn a child process to execute your `command`;
2. Pipe the current session's JSON data into it via **stdin**;
3. Wait for the child process's **stdout** text output to display as the status line content;
4. Terminate the child process.
The `main()` entry function of `ccstatusline` checks `process.stdin.isTTY`:
- **Not a TTY** (data is piped in) → Parses JSON, renders the status line.
- **Is a TTY** (you run `ccstatusline` directly in the terminal) → Launches the TUI configuration interface.
This is why the same binary functions as both a hook and a configuration tool.
### 2.3 Payload Schema: What Claude Code Transmits
Derived from the `StatusJSONSchema` in the `ccstatusline` source code, this is the complete JSON structure transmitted by Claude Code via stdin:
```typescript
{
hook_event_name?: string; // Trigger event name (e.g., "UserPromptSubmit")
session_id?: string; // Session ID
transcript_path?: string; // Path to the session's JSONL transcript file
cwd?: string; // Current working directory
version?: string; // Claude Code version
model?: string | { // Model information
id?: string;
display_name?: string;
};
workspace?: {
current_dir?: string;
project_dir?: string;
};
output_style?: { name?: string }; // Output style name (e.g., "concise")
effort?: { level?: string }; // Thinking effort (low/medium/high/xhigh)
vim?: { mode?: string }; // Vim mode (normal/insert, etc.)
cost?: { // Session cost
total_cost_usd?: number;
total_duration_ms?: number;
total_api_duration_ms?: number;
total_lines_added?: number;
total_lines_removed?: number;
};
context_window?: { // Context window
context_window_size?: number;
total_input_tokens?: number;
total_output_tokens?: number;
current_usage?: number | {
input_tokens?: number;
output_tokens?: number;
cache_creation_input_tokens?: number;
cache_read_input_tokens?: number;
};
used_percentage?: number;
remaining_percentage?: number;
};
worktree?: { // Git worktree information
name?: string;
path?: string;
branch?: string;
original_cwd?: string;
original_branch?: string;
};
rate_limits?: { // Rate limit buckets
five_hour?: { used_percentage?: number; resets_at?: number };
seven_day?: { used_percentage?: number; resets_at?: number };
seven_day_sonnet?: { used_percentage?: number; resets_at?: number };
seven_day_opus?: { used_percentage?: number; resets_at?: number };
};
}
💡 This is a
looseObject, meaning Claude Code might transmit more fields, andccstatuslinewill not throw an error because of them.
2.4 Where Additional Information Comes From
Some information displayed by ccstatusline is not present in the payload above. It actively fetches data from these sources:
| Data | Source |
|---|---|
| Historical token rates, session duration | Parses the JSONL pointed to by transcript_path |
| Block timer (5-hour block) | Parses JSONL + caches to ~/.cache/ccstatusline/block-timer-cache/ |
| Git information | Invokes git subcommands + caches to ~/.cache/ccstatusline/git-cache/ |
| Weekly / Session usage | Directly calls the Anthropic usage API |
| Claude account email | Reads ~/.claude.json |
| System memory | Calls OS APIs |
2.5 Rendering Flow
Once renderMultipleLines(data) is entered, the process roughly follows:
- Loads
~/.config/ccstatusline/settings.json; - Asynchronously and in parallel collects token metrics, speed metrics, and session duration (if related widgets are enabled in the config);
- Iterates over
lines, rendering widgets sequentially for each line:- Each widget instance retrieves values from the payload + external data sources;
- Applies colors, padding, raw mode, and bold styling;
- Appends separators;
- Processes flex separators (expanding to fill the terminal width);
- Applies Powerline decorations (if enabled);
- Outputs to stdout.
The entire process typically completes within tens to hundreds of milliseconds. The Git cache (5-second TTL) and Block Timer cache (invalidated per 5-hour block) are critical for performance.
III. Installation
3.1 Prerequisites
- Node.js ≥ 14
- Claude Code CLI installed and logged in
- (Optional) A terminal supporting Powerline fonts (iTerm2, Windows Terminal, Alacritty, etc.)
3.2 Three Installation Methods
ccstatusline does not mandate a global installation. It is a lightweight tool that can be launched directly via npx/bunx:
Method A: Temporary Execution (Fastest Onboarding)
# Using npm
npx -y ccstatusline@latest
# Or using bun (faster)
bunx -y ccstatusline@latest
Executing this will directly enter the TUI configuration interface.
Method B: Pinned Global Installation (Recommended for Long-term Use)
Enter the TUI and select Pinned global install. It will:
- Install the current
ccstatuslineversion globally on your machine via npm/bun; - Write
"command": "ccstatusline"(without@latest) into Claude Code'ssettings.json.
This ensures Claude Code always uses the specific version you confirmed. To open the configuration interface again later, simply run:
ccstatusline
Method C: Auto-follow Latest Version
During TUI installation, you can choose to write the command as npx -y ccstatusline@latest. Every time Claude Code triggers a status line render, it will run an npx resolution (incurs a cold start delay, but guarantees the latest version).
3.3 Upgrading and Uninstalling
- Upgrading a Pinned version: Select Uninstall in the TUI, re-enter the TUI, and select Pinned global install; local
settings.jsonconfigurations will not be cleared by the uninstall process. - Complete removal: Select Uninstall in the TUI + run
npm uninstall -g ccstatusline.
IV. TUI Operations Quick Reference
Entering ccstatusline presents a keyboard-driven menu:
| Area | Function |
|---|---|
| Lines | Configure multi-line status bars: add/remove lines, add widgets to each line |
| Global Overrides | Global styling: bold, minimalist mode, color levels, separator color inheritance |
| Powerline Setup | Enable Powerline, configure separators, start/end caps, auto-alignment |
| Flex Separator | How flex separators expand when widgets on a line do not fill the terminal width |
| Install / Uninstall | Write statusLine to or remove it from Claude Code settings |
| Refresh Interval | Set the frequency at which Claude Code pulls the status line |
Once inside a specific line:
a: Add widget (features a selector with search/fuzzy match/initialism match, since v2.2.8)k: Clone (clones the current widget; assigns a new color in Powerline mode)- Arrow keys: Move cursor; rearrange widgets when in move mode
w: Enter widget editor (detailed settings for each widget)u: Toggle between "Used / Left" (for percentage widgets like Context %, Session Usage, etc.)h: Hide (e.g., Git widget hides "no git" when not in a repository)d: Delete current widgetq/Esc: Quit / Return
General: Menu/list navigation supports wrap-around (v2.2.10+).
V. 12-Step Beginner Tutorial
Step 0: Verify Prerequisites
In your terminal:
claude --version # Ensure you can see the Claude Code version number
node -v # ≥ v14 (v18+ recommended)
Step 1: First Launch
npx -y ccstatusline@latest
Press Enter, wait a few seconds for the download, and you will enter the TUI main menu.
Step 2: See the Default Status Line
Enter the Lines menu. There is a Preview area at the bottom rendering in real-time. Upon first entry, there are usually a few default widgets (e.g., Model, Git Branch).
Small text at the bottom hints at available shortcuts; remember to glance at it frequently.
Step 3: Install to Claude Code
- Press
Escto return to the main menu → Move to Install → PressEnter; - Select Pinned global install (Recommended);
- Once you see ✅, press
qto quit; - Verify:
cat ~/.claude/settings.json | grep -A 3 statusLine
You should see:
"statusLine": {
"type": "command",
"command": "ccstatusline"
}
- Restart Claude Code, and the status line will appear. 🎉
Step 4: Understand Widgets
The status line is composed of widgets. Typical widgets include:
| Widget Name | Appearance |
|---|---|
model |
Model: Opus 4.7 |
context-length |
Ctx: 12345 |
git-branch |
main |
session-cost |
Cost: $0.12 |
separator |
| (Manual separator) |
custom-text |
Any text you want to write |
Step 5: Add a Widget
Return to the TUI (ccstatusline) → Lines → Line 1:
- Press
a(add); - Type
costto filter outSession Cost; - Press
Enterto select; the Preview will immediately showCost: $0.00; - To add a separator: Press
aagain → searchseparator→ select.
Don't like the position? Hover over the widget, press m to enter move mode, use arrow keys to shift it, and press Enter to confirm.
Step 6: Apply Colors
Hover over Model → Press w to enter the widget editor → Find Color → Press Enter and select cyan. The preview instantly turns cyan.
Three color tiers:
- Basic 16 Colors (
cyan/yellow/magenta) — Best compatibility, recommended for beginners. - 256 Colors (Numbers 0–255) — Supported by most terminals.
- Truecolor (
#a1b2c3) — Modern terminals, richest colors.
If you only use basic colors, you don't need to touch the colorLevel setting.
Step 7: Add a Second Line
Press Esc to return to Lines → Press a to add a new line → Enter Line 2 → Add widgets.
Beginner two-line template:
Line 1: Model | Ctx | Git Branch | Git Changes
Line 2: Session Cost | Session Clock | Block Timer
Step 8: "Surprise" Widgets Worth Adding
| Widget | What it tells you |
|---|---|
block-timer |
Time used in the current 5-hour quota block |
weekly-usage |
Percentage of weekly quota used |
context-percentage-usable |
Usable percentage of the context window (prevents context overflow in long chats) |
free-memory |
System memory usage |
tokens-total |
Cumulative tokens for this session |
Step 9: Custom Text
Press a → Search custom → Select Custom Text → Press w to edit → Enter text (supports emojis) → Press Ctrl+S to save.
Step 10: Adaptive Width (Understand First, Tune Later)
- Flex Separator: Inserts a flex separator between two widgets, automatically expanding to fill remaining space;
- Compact Threshold (Default 60): When terminal width is below this value, widgets supporting compact display will automatically shorten.
Beginners can leave this at default.
Step 11: Test and Understand Saving
ccstatusline auto-saves. Every change updates ~/.config/ccstatusline/settings.json immediately.
How to test:
- Press
qto quit the TUI; - Close and reopen Claude Code (or trigger a status line refresh);
- Check if the bottom reflects your new configuration.
Refreshing too slow? Main menu → Refresh Interval → Set to 5 seconds (requires Claude Code ≥ 2.1.97).
Step 12: Backup
# Configuration file location
~/.config/ccstatusline/settings.json
Place it in your dotfiles or cloud drive. On a new machine, copy it back and run the TUI Install once to restore.
VI. All Available Widgets Overview
Categorized list (v2.2.19):
6.1 Sessions & Models
model— Model display name (automatically strips the(1M context)suffix)model-display— Alias for the abovesession-id— Session IDsession-name— Session name set via/renamesession-clock— Session running durationsession-cost— Cumulative session cost (USD)session-usage— 5-hour block usage percentage for this session (includes short bar mode)claude-account-email— Login email read from~/.claude.jsoncompaction-counter— Context compaction count (includes hide-when-zero)thinking-effort— Thinking effort (low/medium/high/xhigh)voice-status— Voice Input statusvim-mode— Vim modeoutput-style— Current output style
6.2 Context & Tokens
context-length— Current context token countcontext-percentage— Context usage percentagecontext-percentage-usable— Usable percentage (with(u)indicator, pressuto toggle used/left)context-bar— Context progress barcontext-window— Full model window sizetokens-input/tokens-output/tokens-total— Input / Output / Total tokenstokens-cache-creation/tokens-cache-read— Cache write / read tokensinput-speed/output-speed/total-speed— Three token rates (rolling window 0–120s adjustable)
6.3 Quotas & Rate Limits
block-timer— Time used in the 5-hour block (includes progress bar / short bar)reset-timer— Time remaining until next quota reset (can display exact timestamp, supports timezone/locale)weekly-usage— 7-day total usage percentageweekly-usage-sonnet/weekly-usage-opus— 7-day usage per modelweekly-reset-timer— Time remaining until 7-day quota resetextra-usage-utilization/extra-usage-remaining— Monthly pay-as-you-go overage usage
6.4 Git
git-branch— Branch name (can render as clickable GitHub/GitLab link)git-changes— Change statisticsgit-insertions/git-deletions— Insertions only / Deletions onlygit-status— Short statusgit-staged/git-unstaged/git-untracked— Various file countsgit-staged-files/git-unstaged-files/git-untracked-files— Detailed file countsgit-clean-status— Clean / Dirty flaggit-conflicts— Conflicting file countgit-ahead-behind— Local vs. remote ahead/behindgit-sha— Current commit SHAgit-origin-owner/git-origin-repo/git-origin-ownerrepo— Origin repository infogit-upstream-owner/git-upstream-repo/git-upstream-ownerrepo— Upstream repositorygit-is-fork— Is fork flaggit-pr— PR/MR corresponding to the current branch (includes status, title, clickable link)git-root-dir— Repository root directory name (can generatevscode:///cursor://clickable links)git-worktree-mode/git-worktree-name/git-worktree-branch/git-worktree-original-branch
6.5 System & Others
free-memory— System memory usage (Mem: 8.5G/16.0G)current-working-directory— CWD (supports path truncation,~abbreviation, fish-style abbreviation)custom-text— Arbitrary text (includes emojis)custom-symbol— Single character / iconcustom-command— Executes arbitrary shell commands and displays stdoutlink— OSC8 clickable linkskills— List of currently available skills (last/count/list modes)separator— Manual separatorflex-separator— Adaptive separatortime/date— Current time / datetruncate— Truncation marker
Press a and input keywords, acronyms, or use fuzzy matching to find them.
VII. Complete settings.json Field Breakdown
Using this real configuration as an example (the one used in this article):
{
"version": 3,
"lines": [
[
{ "id": "1", "type": "model", "color": "cyan" },
{ "id": "2", "type": "separator" },
{ "id": "3", "type": "context-length", "color": "brightBlack" },
{ "id": "4", "type": "separator" },
{ "id": "5", "type": "git-branch", "color": "magenta" },
{ "id": "6", "type": "separator" },
{ "id": "7", "type": "git-changes", "color": "yellow" }
],
[
{ "type": "reset-timer" },
{ "type": "context-percentage-usable" },
{ "type": "block-timer" },
{ "type": "weekly-usage" },
{ "type": "session-usage" },
{ "type": "tokens-total" },
{ "type": "total-speed" }
],
[
{ "type": "free-memory" },
{ "type": "custom-text" },
{ "type": "model" },
{ "type": "session-clock" },
{ "type": "session-cost" }
],
[]
],
"flexMode": "full-minus-40",
"compactThreshold": 60,
"colorLevel": 2,
"inheritSeparatorColors": false,
"globalBold": false,
"gitCacheTtlSeconds": 5,
"minimalistMode": false,
"powerline": {
"enabled": false,
"separators": [""],
"separatorInvertBackground": [false],
"startCaps": [],
"endCaps": [],
"autoAlign": false,
"continueThemeAcrossLines": false
}
}
Top-Level Fields
| Field | Meaning |
|---|---|
version |
Configuration schema version, currently 3 |
lines |
2D array: outer elements represent lines, inner elements are widget arrays per line |
flexMode |
Flex separator strategy: full / full-minus-40 / full-until-compact, etc. |
compactThreshold |
Enters compact mode when terminal width is below this value |
colorLevel |
0 Off / 1 16 Colors / 2 256 Colors / 3 Truecolor |
inheritSeparatorColors |
Whether separators inherit colors from adjacent widgets |
globalBold |
Whether all widgets are bolded |
gitCacheTtlSeconds |
Git command cache TTL (v2.2.16+) |
minimalistMode |
Global minimalist mode (forces all widgets into raw mode) |
powerline |
Powerline sub-configuration |
Common Widget Fields
| Field | Meaning |
|---|---|
id |
Auto-generated UUID or incremental number |
type |
Widget type, see Section VI |
color |
Foreground color (basic name / number / hex) |
bgColor |
Background color (commonly used in Powerline mode) |
bold |
Bold text |
rawValue |
Displays only the value, without the label prefix |
merge |
Whether to merge with the left widget (no separation) |
padding |
Internal padding |
Widget-Specific Fields
A few examples:
// Custom Text
{ "type": "custom-text", "text": "📦 my-project" }
// Custom Command
{
"type": "custom-command",
"commandPath": "/usr/local/bin/my-status.sh",
"preserveColors": true,
"timeoutMs": 1000
}
// Git Branch with link
{ "type": "git-branch", "linkMode": "github" }
// Reset Timer with timestamp
{
"type": "reset-timer",
"displayMode": "timestamp",
"use24Hour": true,
"timezone": "Asia/Shanghai",
"locale": "zh-CN"
}
// Speed widget with rolling window
{ "type": "total-speed", "windowSeconds": 30 }
VIII. Advanced Usage
8.1 Toggling "Used / Left" for Widgets
For percentage widgets like Context %, Context % (usable), Session Usage, Weekly Usage, press u in the editor to toggle between used and left.
- Used mode:
Ctx Used: 35% - Left mode:
Ctx Left: 65%
8.2 Short / Long Progress Bars
Block Timer, Block Reset Timer, Weekly Reset Timer, Context Bar, Session Usage, and Weekly Usage all support:
- Numeric mode (
Block: 3hr 45m) - Long progress bar (32 characters)
- Short progress bar (16 characters, compact)
8.3 Timestamp Display
Reset Timer / Weekly Reset Timer can be switched from "time remaining" to "exact reset time":
- 12 / 24-hour format
- Custom IANA timezone (
Asia/Shanghai,America/New_York) - Custom locale
8.4 Clickable Links
Git Branch: When link mode is enabled, renders ashttps://github.com/owner/repo/tree/branchGit Root Dir: Can generatevscode://orcursor://protocol linksLinkwidget: Arbitrary OSC8 links, clickable in supported terminals
8.5 Hiding Empty Values
Many widgets support hide-when-empty / hide-when-zero:
- Git widgets default to
no gitwhen not in a repository; presshto hide. Compaction Countercan be hidden when the count is zero.
8.6 Minimalist Mode
Main menu → Global Overrides → Enable Minimalist Mode.
Forces all widgets into raw mode: Cost: $0.12 → $0.12, Model: Opus 4.7 → Opus 4.7.
IX. Custom Commands: Integrating External Scripts
This is the "escape hatch" of ccstatusline—if built-in widgets aren't enough, write a script to fill the gap.
9.1 Working Mechanism
On every status line refresh, ccstatusline uses the shell to execute your specified command, taking the first line of stdout (or all of it, depending on implementation) as the display text. The command must be fast and idempotent.
9.2 How to Add
- TUI → Lines → Select a line →
a→ Searchcustom command→ Select; - Press
wto edit:- Command Path: Absolute path to the script
- Preserve Colors: Retain ANSI color codes (otherwise overridden by global colors)
- Timeout: Abort after timeout (500–1000ms recommended)
9.3 Example Scripts
Show current PR count (requires gh):
#!/usr/bin/env bash
n=$(gh pr list --author "@me" --json number | jq length 2>/dev/null)
echo "PRs: ${n:-0}"
Show CI status:
#!/usr/bin/env bash
status=$(gh run list --branch "$(git branch --show-current 2>/dev/null)" \
--limit 1 --json conclusion -q '.[0].conclusion' 2>/dev/null)
case "$status" in
success) echo -e "\033[32mCI:✓\033[0m" ;;
failure) echo -e "\033[31mCI:✗\033[0m" ;;
*) echo "CI:?" ;;
esac
Show weather:
#!/usr/bin/env bash
curl -s "wttr.in/Beijing?format=%c+%t" --max-time 1
⚠️ Custom Commands execute on every refresh. Increase
refreshIntervalor add caching to your script (file writing + mtime checks); otherwise, it will slow down the status line and consume resources.
9.4 ANSI Color Escapes
If preserveColors: true, \033[3Xm color codes output by the script will be preserved exactly; otherwise, they will be overridden by ccstatusline's global colors.
X. Powerline Beautification
10.1 Prerequisites
- Terminal font must be a Nerd Font (Recommended: FiraCode Nerd Font, JetBrainsMono Nerd Font)
- Terminal must have truecolor enabled (mostly standard nowadays)
ccstatusline provides an automated Powerline font installation process, requiring user consent.
10.2 Enable Steps
- TUI → Powerline Setup → Enable;
- Select separators (default is ``);
- Add startCaps / endCaps to wrap the entire line in a "capsule" (optional);
- Auto-Align: Aligns multi-line widgets into columns like a report (v2.0.8+);
- Continue theme across lines: Maintains continuous Powerline colors across multiple lines (v2.2.8+).
10.3 Custom Separators
Supports direct input of 4–6 digit Unicode hex (v2.1.9+), allowing any Powerline character:
E0B0Solid right arrowE0B1Hollow right arrowE0B2Solid left arrowE0B4Rounded headE0BCSlash
10.4 Built-in Themes
Powerline Setup → Built-in Themes provides several presets. Enter, copy, and modify colors as needed.
XI. Performance & Caching Mechanisms
Key performance optimizations in ccstatusline:
11.1 Git Cache (v2.2.16+)
- Path:
~/.cache/ccstatusline/git-cache/ - TTL:
gitCacheTtlSeconds(default 5s) - Invalidation signal: Detects mtime changes in
.git/HEADand.git/index - Git commands uniformly append
--no-optional-locksto avoid competing forindex.lockwith parallel commands likegit status.
11.2 Block Timer Cache (v2.0.28+)
- Path:
~/.cache/ccstatusline/block-timer-cache/ - Files separated by configuration hash
- Automatically invalidates when the 5-hour block expires
- Significantly reduces full JSONL parsing
11.3 Token Deduplication (v2.2.12+)
Duplicate entries in streaming JSONL are deduplicated, preventing artificially inflated token counts during high-frequency refreshes.
11.4 Subagent Awareness
Token speed calculations include subagent activities, ensuring displayed speeds reflect the true concurrent workload.
11.5 Terminal Width Detection
- Defaults to querying via TTY
- May fail under nested PTY / tmux → Manually override using an environment variable:
export CCSTATUSLINE_WIDTH=200
11.6 Hidden Subprocesses (Windows)
All helper subprocesses are set with windowsHide, preventing extra windows from popping up on Windows.
XII. Debugging & Troubleshooting
12.1 Manually Running the Hook Flow
Simulate Claude Code's invocation:
echo '{
"session_id": "test",
"model": {"display_name": "Opus 4.7"},
"cwd": "/tmp",
"transcript_path": "/tmp/none.jsonl",
"cost": {"total_cost_usd": 0.12},
"context_window": {
"context_window_size": 200000,
"current_usage": 35000,
"used_percentage": 17.5
}
}' | ccstatusline
You should directly see the rendered status line string (with ANSI colors).
12.2 Using a Custom Configuration File
ccstatusline --config /tmp/test-settings.json
Allows maintaining multiple configuration sets for experimentation.
12.3 Hook Mode
echo '<payload>' | ccstatusline --hook
Explicitly forces the hook branch, avoiding ambiguity caused by isTTY checks.
12.4 Common Errors Reference
| Error Message | Cause |
|---|---|
Invalid status JSON format |
stdin received invalid JSON |
No input received |
No content read from stdin; command might have been executed directly |
| Status line is completely blank | Incorrect command path or permissions |
EACCES |
Binary file is not executable → chmod +x |
12.5 Force Reset
# Backup
cp ~/.config/ccstatusline/settings.json ~/ccstatusline-backup.json
# Delete config; it will rebuild with defaults on next launch
rm ~/.config/ccstatusline/settings.json
ccstatusline
XIII. Q&A Quick Reference
Q1: Should I choose Pinned or npx for the first run? For long-term use, choose Pinned global install so remote version changes won't affect behavior; if you just want to test it, choose npx.
Q2: The status line never appears at the bottom of Claude Code? Check sequentially:
statusLinefield exists in~/.claude/settings.json;which ccstatuslinecan locate the binary;- Restart Claude Code;
- Set
Refresh Intervallower (5–10 seconds).
Q3: Git info always shows no git?
Claude Code's session CWD is not inside a Git repository. The cwd field comes from the directory where Claude Code was launched and does not follow the files you edit. Launch Claude Code inside the repository.
Q4: Powerline characters turn into squares/question marks? Your terminal font does not support Powerline. Install a Nerd Font, or disable it in Powerline Setup.
Q5: Status line gets truncated when the terminal is narrow?
- Reduce the number of widgets
- Enable
compactThreshold(default 60) and select widgets that support short modes - Move secondary information to a second line
Q6: Terminal width detection is inaccurate (nested PTY / tmux)?
export CCSTATUSLINE_WIDTH=200
Q7: Need a proxy to access the Anthropic usage API?
export HTTPS_PROXY=http://your-proxy:port
Usage-related widgets will read this variable (v2.2.2+).
Q8: Claude Code config directory is not in the default location?
export CLAUDE_CONFIG_DIR=/custom/path/to/.claude
ccstatusline and all widgets will use this variable.
Q9: Should I Uninstall before upgrading ccstatusline?
If you are currently using npx -y ccstatusline@latest, it is recommended to TUI Uninstall first before switching to Pinned to avoid behavioral drift. Local settings will not be cleared by the uninstall process.
Q10: Status line is lagging?
- Increase
refreshInterval(e.g., 15 seconds) - Reduce the number of Custom Commands, add caching to scripts
- Ensure Git cache is enabled (
gitCacheTtlSeconds: 5or higher) - Block Timer cache takes effect automatically, no configuration needed
Q11: Session Cost isn't refreshing?
Requires Claude Code ≥ 1.0.85; when resuming historical sessions via /resume, it might not update (a limitation on Claude Code's side).
Q12: Can I use it in WSL?
Absolutely. See docs/WINDOWS.md for detailed Windows instructions.
Q13: Can I use different configs for different Claude Code projects?
By default, they share ~/.config/ccstatusline/settings.json. You can use --config to specify different files, but you need to modify the command in Claude Code's settings:
"command": "ccstatusline --config ~/.config/ccstatusline/project-a.json"
Q14: Can I use multiple hooks simultaneously (statusLine + others)?
Yes, statusLine is just one of Claude Code's many hooks, independent of PreToolUse, UserPromptSubmit, etc. See Claude Code documentation for details.
Q15: Status line text has ANSI colors but the terminal doesn't display them?
- Check that
colorLevelis not0 - Ensure the terminal supports truecolor (
tput colors≥ 256) - SSH connections might drop colors; verify
$TERM(e.g.,xterm-256color)
Q16: How to completely uninstall?
# Run Uninstall in TUI (removes statusLine from settings.json)
ccstatusline
# Then
npm uninstall -g ccstatusline
rm -rf ~/.config/ccstatusline
rm -rf ~/.cache/ccstatusline
Q17: Can it be used for tools other than Claude Code?
ccstatusline is a generic stdin→stdout status line renderer. As long as you can construct a valid JSON payload and pipe it in, theoretically any tool can integrate it. Of course, the field conventions are based on Claude Code.
Q18: Can I contribute new widgets?
Yes. The project is under the MIT license, repository at github.com/sirmalloc/ccstatusline. Adding a new widget requires: implementing the Widget interface, registering it to the widget map, adding a TUI editor, and writing tests.
Q19: How to debug for local development?
git clone https://github.com/sirmalloc/ccstatusline
cd ccstatusline
bun install
bun start # Launch TUI
bun run example # Render once using example payload
Q20: Status line data privacy?
ccstatusline runs locally and does not upload your session content. It only calls the Anthropic usage API when using widgets like weekly/session usage (homologous to Claude Code's own /usage call). Everything is cached in ~/.cache/ccstatusline.
XIV. Backup & Multi-Machine Synchronization
14.1 Files to Backup
~/.config/ccstatusline/settings.json # All widget configurations
~/.claude/settings.json (statusLine field) # The hook for Claude Code
14.2 Dotfiles Integration Example
# Inside your dotfiles repository
mkdir -p config/ccstatusline
cp ~/.config/ccstatusline/settings.json config/ccstatusline/
# Restore on a new machine
mkdir -p ~/.config/ccstatusline
ln -sf "$PWD/config/ccstatusline/settings.json" ~/.config/ccstatusline/settings.json
# Run TUI once more to write Claude Code settings
npx -y ccstatusline@latest
# Enter → Install → Pinned global install
14.3 Switching Between Multiple Configurations
# Development environment
ccstatusline --config ~/.config/ccstatusline/dev.json
# Demo mode (minimalist)
ccstatusline --config ~/.config/ccstatusline/demo.json
Write these commands into aliases like claude-dev / claude-demo to switch based on your scenario.
Recommended Starter Configuration
If you don't want to think about it, just copy this:
Line 1: Model | Context Length | Git Branch | Git Changes
Line 2: Block Timer | Weekly Usage | Session Cost | Session Clock
Color suggestions:
Model→ cyanGit Branch→ magentaGit Changes→ yellowWeekly Usage→ green- Leave the rest as default
After a week of use, you will likely want to add:
context-percentage-usable(prevents context overflow)free-memory(monitor machine status)compaction-counter(monitor compaction counts)- Custom Commands (integrate CI/PR/Weather, etc.)
By then, you will be proficient enough not to need the tutorial.
Resource Links
- Project Homepage: https://github.com/sirmalloc/ccstatusline
- npm Package: https://www.npmjs.com/package/ccstatusline
- Detailed Windows Docs:
docs/WINDOWS.mdin the repository - Complete Usage Docs:
docs/USAGE.mdin the repository - Development Docs:
docs/DEVELOPMENT.mdin the repository - Related Projects:
Happy hacking. ✨
If you want to:
- Overhaul your
settings.json→ Tell me your requirements - Integrate a Custom Command to run a specific script → Paste the script
- Design a Powerline theme → Describe your desired visual style
I can help you push further based on this tutorial.