Agent skill
box-factory-status-line
Practical guidance for Claude Code status lines - what to display for real workflow benefits, not just configuration syntax. Use when setting up status lines or wondering what information would actually help.
Install this agent skill to your Project
npx add-skill https://github.com/majiayu000/claude-skill-registry/tree/main/skills/development/box-factory-status-line
SKILL.md
Status Line Skill
This skill provides practical guidance on what makes status lines useful. The official docs explain how to configure them; this skill explains what to display and why.
Fundamentals
Three core principles underpin effective status line design:
1. Workflow-Driven Information
Status lines exist to prevent problems, not display all available data. Choose what to show based on pain points you've experienced: cost surprise, model confusion, wrong branch commits.
2. Glanceable, Not Comprehensive
You'll stop reading a status line that's too long. Pick 3-4 most valuable pieces. Use multi-line community tools only if you genuinely need more.
3. Performance Matters
Scripts run every 300ms. Keep them fast (<100ms ideally). Use JSON data when possible, cache slow operations, wrap git commands in existence checks.
Workflow Selection
| If you need to... | Go to... |
|---|---|
| Understand what status lines are and when to use them | Core Understanding |
| Solve specific workflow problems (cost, git, model) | Practical Workflows |
| Choose between custom script and community tools | Decision Framework |
| Get started quickly with working status line | Quick Start |
| Optimize slow scripts or fix errors | Performance Considerations |
| See complete examples for different use cases | Composition Patterns |
| Look up available JSON fields | What's Available |
| Avoid common mistakes | Common Pitfalls |
Official Documentation
Fetch official documentation with WebFetch:
- https://code.claude.com/docs/en/statusline - Configuration and JSON schema
Core Understanding
What Status Lines Actually Are
Status lines are a real-time development dashboard at the bottom of Claude Code. Think vim statusline or tmux status bar - persistent, glanceable, always-current information.
How they work:
- Script runs on every message update (throttled to 300ms)
- Receives structured JSON via stdin with session data
- First line of stdout becomes the display
- ANSI colors and emojis supported
What you DON'T need a status line skill to know:
- JSON parsing syntax
- Configuration file locations
- How to write bash/python scripts
Claude knows all that. This skill focuses on what to display based on real developer workflows.
Practical Workflows (Why Status Lines Matter)
1. Cost Awareness
The problem: You're deep in a session and suddenly realize you've burned through $15 in API costs.
The solution: Display session cost and daily total prominently.
cost=$(echo "$input" | jq -r '.cost.total_cost_usd')
printf "💰 \$%.4f" "$cost"
Workflow benefit: Catch runaway sessions early. Know when to switch models.
2. Context Window Management
The problem: Claude starts forgetting earlier context because you've filled the window.
The solution: Display context usage percentage.
Workflow benefit: Know when to compact (/compact) or start fresh before context degrades.
Note: The official JSON schema includes cost data but context percentage requires external tools like ccstatusline.
3. Model Visibility
The problem: You switched to haiku for a quick task and forgot, now wondering why responses feel different.
The solution: Always show current model.
model=$(echo "$input" | jq -r '.model.display_name')
echo "[$model]"
Workflow benefit: Model awareness without checking settings. Crucial when switching between opus/sonnet/haiku for different task types.
4. Git Branch Awareness
The problem: You're making changes on the wrong branch.
The solution: Show current git branch in status line.
if git rev-parse --git-dir > /dev/null 2>&1; then
branch=$(git symbolic-ref --short HEAD 2>/dev/null || echo "detached")
echo "🌿 $branch"
fi
Workflow benefit: Never commit to main accidentally. Stay oriented in multi-branch workflows.
5. Session Duration / Block Management
The problem: Claude Code 5-hour blocks expire and you lose context.
The solution: Display session duration or time remaining in block.
duration_sec=$(echo "$input" | jq -r '.cost.total_duration_ms / 1000 | floor')
printf "[%dm]" "$((duration_sec / 60))"
Workflow benefit: Plan commits and breaks around block boundaries. Don't lose work mid-session.
6. Project Orientation
The problem: Working across multiple projects and forgetting which terminal is which.
The solution: Show project directory name.
dir=$(echo "$input" | jq -r '.workspace.project_dir' | xargs basename)
echo "📁 $dir"
Workflow benefit: Instant orientation. Critical in multi-terminal setups.
Composition Patterns
Minimal (Model + Directory)
#!/bin/bash
input=$(cat)
model=$(echo "$input" | jq -r '.model.display_name')
dir=$(echo "$input" | jq -r '.workspace.current_dir' | xargs basename)
echo "[$model] 📁 $dir"
Best for: Simple awareness, low noise.
Developer Standard (Model + Git + Cost)
#!/bin/bash
input=$(cat)
model=$(echo "$input" | jq -r '.model.display_name')
cost=$(echo "$input" | jq -r '.cost.total_cost_usd')
dir=$(echo "$input" | jq -r '.workspace.project_dir')
branch=""
if git -C "$dir" rev-parse --git-dir > /dev/null 2>&1; then
branch=" 🌿 $(git -C "$dir" symbolic-ref --short HEAD 2>/dev/null)"
fi
printf "[%s]%s 💰 \$%.4f\n" "$model" "$branch" "$cost"
Best for: Most development workflows. Balance of information and brevity.
Terminal-Only Workflow
When working without an IDE (terminal-only), you need more context:
#!/bin/bash
input=$(cat)
model=$(echo "$input" | jq -r '.model.display_name')
dir=$(echo "$input" | jq -r '.workspace.project_dir')
# Full git status for terminal-only work
if git -C "$dir" rev-parse --git-dir > /dev/null 2>&1; then
branch=$(git -C "$dir" symbolic-ref --short HEAD 2>/dev/null)
staged=$(git -C "$dir" diff --cached --numstat | wc -l | tr -d ' ')
unstaged=$(git -C "$dir" diff --numstat | wc -l | tr -d ' ')
echo "[$model] $branch ✓$staged ✗$unstaged"
else
echo "[$model] ${dir##*/}"
fi
Best for: Pure terminal development without IDE git integration.
Community Tools (When Custom Scripts Aren't Enough)
ccstatusline
Multi-line powerline-style status with widgets. Interactive TUI configuration.
When to use: You want rich visuals without writing scripts, or need widgets for context percentage/tokens.
Install: npx ccstatusline@latest
claude-code-statusline
18 atomic components, 1-9 configurable lines, TOML configuration.
When to use: Complex layouts, cost projections, MCP server monitoring, Islamic prayer times integration.
Unique features: Cache efficiency metrics, burn rate alerts, daily/weekly/monthly cost tracking.
ccusage statusline
Focused on cost tracking with visual burn rate indicators.
When to use: Cost management is your primary concern.
Decision Framework
Ask yourself:
-
What problem am I solving?
- If none → Don't add a status line (default is fine)
- If cost surprise → Add cost display
- If model confusion → Add model display
- If git mistakes → Add branch display
-
How much information density?
- Minimal → Model + directory only
- Standard → Model + git + cost
- Maximum → Use community tool for multi-line
-
How performance-sensitive?
- Very → Avoid git commands, use only JSON data
- Normal → Git commands are fine (cached by git)
- Not concerned → External API calls acceptable
-
Custom script vs community tool?
- Need specific format → Custom script
- Want rich features fast → Community tool
- Want to learn → Start custom, migrate later
Performance Considerations
Scripts run frequently (every 300ms throttle). Keep them fast.
Safe (use JSON data only):
model=$(echo "$input" | jq -r '.model.display_name')
cost=$(echo "$input" | jq -r '.cost.total_cost_usd')
Usually fine (git is fast locally):
branch=$(git symbolic-ref --short HEAD 2>/dev/null)
Potentially slow (cache if needed):
# External API calls, npm commands, slow git operations
Caching pattern for slow operations:
CACHE_FILE="/tmp/statusline_cache"
CACHE_TTL=5
if [ -f "$CACHE_FILE" ] && [ $(($(date +%s) - $(stat -f%m "$CACHE_FILE"))) -lt $CACHE_TTL ]; then
cat "$CACHE_FILE"
else
expensive_result=$(expensive_command)
echo "$expensive_result" > "$CACHE_FILE"
echo "$expensive_result"
fi
Common Pitfalls
Pitfall: Too Much Information
Problem: Status line so long it wraps or gets truncated.
Reality: You'll stop reading it. Less is more.
Fix: Pick 3-4 most valuable pieces. Use community tools for multi-line if you need more.
Pitfall: Slow Scripts
Problem: Status line lags behind, script takes 500ms+.
Impact: Typing feels sluggish.
Fix: Profile with time echo '{}' | ./statusline.sh. Keep under 100ms ideally.
Pitfall: Git Commands in Non-Git Directories
Problem: Script fails or shows errors in non-git directories.
Fix: Always check:
if git rev-parse --git-dir > /dev/null 2>&1; then
# git commands here
fi
Pitfall: Missing jq
Problem: Script assumes jq is installed.
Fix: Use Python or Node instead, or check for jq:
if ! command -v jq &> /dev/null; then
echo "[status line: jq required]"
exit 0
fi
Pitfall: Forgetting to Make Script Executable
Problem: Status line doesn't work.
Fix: chmod +x ~/.claude/statusline.sh
Quick Start
Fastest path to useful status line:
# Create script
cat > ~/.claude/statusline.sh << 'EOF'
#!/bin/bash
input=$(cat)
model=$(echo "$input" | jq -r '.model.display_name')
cost=$(echo "$input" | jq -r '.cost.total_cost_usd')
dir=$(echo "$input" | jq -r '.workspace.current_dir' | xargs basename)
printf "[%s] 📁 %s 💰 \$%.4f\n" "$model" "$dir" "$cost"
EOF
# Make executable
chmod +x ~/.claude/statusline.sh
# Configure (add to ~/.claude/settings.json)
# {
# "statusLine": {
# "type": "command",
# "command": "~/.claude/statusline.sh"
# }
# }
Or use /statusline command to have Claude Code set it up for you.
What's Available in JSON Input
Your script receives this via stdin (partial list - see official docs for complete schema):
{
"model": {
"id": "model-identifier",
"display_name": "Claude 3.5 Sonnet"
},
"workspace": {
"current_dir": "/path/to/current",
"project_dir": "/path/to/project"
},
"cost": {
"total_cost_usd": 0.012,
"total_duration_ms": 45000
},
"session_id": "unique-id",
"version": "1.0.80"
}
Key fields for workflows:
model.display_name- Current model namecost.total_cost_usd- Session costcost.total_duration_ms- Session durationworkspace.project_dir- Project rootworkspace.current_dir- Current directory
Quality Checklist
Before finalizing your status line:
Configuration:
- Script is executable (ran
chmod +xon script file) - Correct path configured in settings.json
- Fetched official docs for current JSON schema
Performance:
- Script runs under 100ms (tested with
time echo '{}' | ./statusline.sh) - Git commands wrapped in existence checks (
git rev-parse --git-dir) - Slow operations cached with TTL pattern if needed
- No external API calls unless absolutely necessary
Content:
- Displays 3-4 most valuable pieces (not everything available)
- Handles non-git directories gracefully (no errors)
- Checks for required tools (jq, etc) with fallback
- Chosen fields solve actual workflow problems (cost, model, branch)
Testing:
- Tested in git repository (shows branch correctly)
- Tested in non-git directory (no errors or warnings)
- Tested across multiple sessions (updates correctly)
- Status line remains readable (not truncated or wrapped)
Documentation References
- https://code.claude.com/docs/en/statusline - Official configuration
- https://github.com/sirmalloc/ccstatusline - Powerline-style tool
- https://github.com/rz1989s/claude-code-statusline - Atomic component tool
- https://ccusage.com/guide/statusline - Cost-focused status line
Didn't find tool you were looking for?