Status Line Configuration
Create a custom status line for CodeBuddy Code to display contextual information
Personalize CodeBuddy Code with a custom status line that displays at the bottom of the CodeBuddy Code interface, similar to how terminal prompts (PS1) work in shells like Oh-my-zsh.
Creating a Custom Status Line
You can choose one of the following methods:
Run
/statuslineto have CodeBuddy Code help you set up a custom status line. By default, it will try to replicate your terminal's prompt, but you can provide additional instructions about desired behavior, like/statusline show the model name in orangeAdd a
statusLinecommand directly to your.codebuddy/settings.json:
json
{
"statusLine": {
"type": "command",
"command": "~/.codebuddy/statusline.sh",
"padding": 0 // Optional: set to 0 to let the status line extend to the edges
}
}How It Works
- The status line updates when conversation messages are updated
- Updates run at most every 300ms
- The first line of stdout from the command becomes the status line text
- ANSI color codes are supported for styling the status line
- CodeBuddy Code passes context information about the current session (model, directory, etc.) to your script via stdin in JSON format
JSON Input Structure
Your status line command receives structured data in JSON format via stdin:
json
{
"hook_event_name": "Status",
"session_id": "abc123...",
"transcript_path": "/path/to/transcript.json",
"cwd": "/current/working/directory",
"model": {
"id": "gpt-5",
"display_name": "GPT-5"
},
"workspace": {
"current_dir": "/current/working/directory",
"project_dir": "/original/project/directory"
},
"version": "2.9.0",
"output_style": {
"name": "default"
},
"cost": {
"total_cost_usd": 0.01234,
"total_duration_ms": 45000,
"total_api_duration_ms": 2300,
"total_lines_added": 156,
"total_lines_removed": 23
}
}Example Scripts
Simple Status Line
bash
#!/bin/bash
# Read JSON input from stdin
input=$(cat)
# Extract values using jq
MODEL_DISPLAY=$(echo "$input" | jq -r '.model.display_name')
CURRENT_DIR=$(echo "$input" | jq -r '.workspace.current_dir')
echo "[$MODEL_DISPLAY] 📁 ${CURRENT_DIR##*/}"Git-Aware Status Line
bash
#!/bin/bash
# Read JSON input from stdin
input=$(cat)
# Extract values using jq
MODEL_DISPLAY=$(echo "$input" | jq -r '.model.display_name')
CURRENT_DIR=$(echo "$input" | jq -r '.workspace.current_dir')
# Show git branch if in a git repository
GIT_BRANCH=""
if git rev-parse --git-dir > /dev/null 2>&1; then
BRANCH=$(git branch --show-current 2>/dev/null)
if [ -n "$BRANCH" ]; then
GIT_BRANCH=" | 🌿 $BRANCH"
fi
fi
echo "[$MODEL_DISPLAY] 📁 ${CURRENT_DIR##*/}$GIT_BRANCH"Status Line with Colors
bash
#!/bin/bash
# Read JSON input from stdin
input=$(cat)
# Extract values using jq
MODEL_DISPLAY=$(echo "$input" | jq -r '.model.display_name')
CURRENT_DIR=$(echo "$input" | jq -r '.workspace.current_dir')
SESSION_ID=$(echo "$input" | jq -r '.session_id' | cut -c1-8)
# ANSI color codes
GREEN='\033[0;32m'
BLUE='\033[0;34m'
YELLOW='\033[1;33m'
NC='\033[0m' # No color
# Get git branch
GIT_BRANCH=""
if git rev-parse --git-dir > /dev/null 2>&1; then
BRANCH=$(git branch --show-current 2>/dev/null)
if [ -n "$BRANCH" ]; then
GIT_BRANCH=" ${GREEN}on${NC} ${YELLOW}$BRANCH${NC}"
fi
fi
echo -e "${BLUE}[$MODEL_DISPLAY]${NC} 📁 ${GREEN}${CURRENT_DIR##*/}${NC}$GIT_BRANCH ${BLUE}(${SESSION_ID})${NC}"Showing Cost and Statistics
bash
#!/bin/bash
# Read JSON input from stdin
input=$(cat)
# Extract values
MODEL_DISPLAY=$(echo "$input" | jq -r '.model.display_name')
CURRENT_DIR=$(echo "$input" | jq -r '.workspace.current_dir')
TOTAL_COST=$(echo "$input" | jq -r '.cost.total_cost_usd')
LINES_ADDED=$(echo "$input" | jq -r '.cost.total_lines_added')
LINES_REMOVED=$(echo "$input" | jq -r '.cost.total_lines_removed')
# Format cost
COST_STR=""
if [ "$TOTAL_COST" != "null" ] && [ "$TOTAL_COST" != "0" ]; then
COST_STR=$(printf " | 💰 \$%.4f" "$TOTAL_COST")
fi
# Format code statistics
STATS=""
if [ "$LINES_ADDED" != "null" ] && [ "$LINES_ADDED" != "0" ]; then
STATS=" | +$LINES_ADDED -$LINES_REMOVED"
fi
echo "[$MODEL_DISPLAY] 📁 ${CURRENT_DIR##*/}$COST_STR$STATS"Python Example
python
#!/usr/bin/env python3
import json
import sys
import os
import subprocess
# Read JSON from stdin
data = json.load(sys.stdin)
# Extract values
model = data['model']['display_name']
current_dir = os.path.basename(data['workspace']['current_dir'])
# Check git branch
git_branch = ""
try:
branch = subprocess.check_output(
['git', 'branch', '--show-current'],
stderr=subprocess.DEVNULL
).decode('utf-8').strip()
if branch:
git_branch = f" | 🌿 {branch}"
except:
pass
# ANSI color codes
BLUE = '\033[0;34m'
GREEN = '\033[0;32m'
NC = '\033[0m'
print(f"{BLUE}[{model}]{NC} 📁 {GREEN}{current_dir}{NC}{git_branch}")Node.js Example
javascript
#!/usr/bin/env node
const fs = require('fs');
const path = require('path');
const { execSync } = require('child_process');
// Read JSON from stdin
let input = '';
process.stdin.on('data', chunk => input += chunk);
process.stdin.on('end', () => {
const data = JSON.parse(input);
// Extract values
const model = data.model.display_name;
const currentDir = path.basename(data.workspace.current_dir);
// Check git branch
let gitBranch = '';
try {
const branch = execSync('git branch --show-current', {
encoding: 'utf8',
stdio: ['pipe', 'pipe', 'ignore']
}).trim();
if (branch) {
gitBranch = ` | 🌿 ${branch}`;
}
} catch (e) {
// Not a git repo or can't read branch
}
// ANSI colors
const BLUE = '\x1b[0;34m';
const GREEN = '\x1b[0;32m';
const NC = '\x1b[0m';
console.log(`${BLUE}[${model}]${NC} 📁 ${GREEN}${currentDir}${NC}${gitBranch}`);
});Helper Function Approach
For more complex bash scripts, you can create helper functions:
bash
#!/bin/bash
# Read JSON input once
input=$(cat)
# Helper functions for common extractions
get_model_name() { echo "$input" | jq -r '.model.display_name'; }
get_model_id() { echo "$input" | jq -r '.model.id'; }
get_current_dir() { echo "$input" | jq -r '.workspace.current_dir'; }
get_project_dir() { echo "$input" | jq -r '.workspace.project_dir'; }
get_version() { echo "$input" | jq -r '.version'; }
get_cost() { echo "$input" | jq -r '.cost.total_cost_usd'; }
get_duration() { echo "$input" | jq -r '.cost.total_duration_ms'; }
get_lines_added() { echo "$input" | jq -r '.cost.total_lines_added'; }
get_lines_removed() { echo "$input" | jq -r '.cost.total_lines_removed'; }
get_session_id() { echo "$input" | jq -r '.session_id'; }
# Use helper functions
MODEL=$(get_model_name)
DIR=$(get_current_dir)
COST=$(get_cost)
# Format cost
if [ "$COST" != "null" ] && [ "$COST" != "0" ]; then
COST_DISPLAY=$(printf " | 💰 \$%.4f" "$COST")
else
COST_DISPLAY=""
fi
echo "[$MODEL] 📁 ${DIR##*/}$COST_DISPLAY"Complete Example
bash
#!/bin/bash
# ~/.codebuddy/statusline.sh
# CodeBuddy Code Status Line Example
# Read JSON input from stdin
input=$(cat)
# Extract basic information
MODEL=$(echo "$input" | jq -r '.model.display_name')
CURRENT_DIR=$(echo "$input" | jq -r '.workspace.current_dir')
DIR_NAME=${CURRENT_DIR##*/}
# ANSI colors
BLUE='\033[0;34m'
GREEN='\033[0;32m'
YELLOW='\033[1;33m'
CYAN='\033[0;36m'
NC='\033[0m'
# Git information
GIT_INFO=""
if git rev-parse --git-dir > /dev/null 2>&1; then
BRANCH=$(git branch --show-current 2>/dev/null)
if [ -n "$BRANCH" ]; then
# Check for uncommitted changes
if ! git diff-index --quiet HEAD -- 2>/dev/null; then
STATUS="*"
else
STATUS=""
fi
GIT_INFO=" ${GREEN}branch${NC} ${YELLOW}$BRANCH$STATUS${NC}"
fi
fi
# Cost information
COST=$(echo "$input" | jq -r '.cost.total_cost_usd')
COST_INFO=""
if [ "$COST" != "null" ] && [ "$COST" != "0" ]; then
COST_INFO=$(printf " ${CYAN}cost${NC} \$%.4f" "$COST")
fi
# Output status line
echo -e "${BLUE}[$MODEL]${NC} 📁 ${GREEN}$DIR_NAME${NC}$GIT_INFO$COST_INFO"Advanced Examples
Showing Current Time and Session Duration
bash
#!/bin/bash
input=$(cat)
MODEL=$(echo "$input" | jq -r '.model.display_name')
DIR=$(echo "$input" | jq -r '.workspace.current_dir')
DURATION_MS=$(echo "$input" | jq -r '.cost.total_duration_ms')
# Format duration
if [ "$DURATION_MS" != "null" ] && [ "$DURATION_MS" != "0" ]; then
DURATION_SEC=$((DURATION_MS / 1000))
DURATION_MIN=$((DURATION_SEC / 60))
DURATION_SEC=$((DURATION_SEC % 60))
TIME_INFO=$(printf " | ⏱️ %dm%ds" "$DURATION_MIN" "$DURATION_SEC")
else
TIME_INFO=""
fi
# Current time
CURRENT_TIME=$(date +"%H:%M:%S")
echo "[$MODEL] 📁 ${DIR##*/}$TIME_INFO | 🕐 $CURRENT_TIME"Color-Coded by Cost
bash
#!/bin/bash
input=$(cat)
MODEL=$(echo "$input" | jq -r '.model.display_name')
DIR=$(echo "$input" | jq -r '.workspace.current_dir')
COST=$(echo "$input" | jq -r '.cost.total_cost_usd')
# Color definitions
GREEN='\033[0;32m'
YELLOW='\033[1;33m'
RED='\033[0;31m'
NC='\033[0m'
# Choose color based on cost
if [ "$COST" != "null" ]; then
if (( $(echo "$COST < 0.01" | bc -l) )); then
COST_COLOR=$GREEN
elif (( $(echo "$COST < 0.1" | bc -l) )); then
COST_COLOR=$YELLOW
else
COST_COLOR=$RED
fi
COST_DISPLAY=$(printf "${COST_COLOR}\$%.4f${NC}" "$COST")
else
COST_DISPLAY=""
fi
echo -e "[$MODEL] 📁 ${DIR##*/} | 💰 $COST_DISPLAY"Tips
- Keep the status line concise - it should fit on one line
- Use emoji (if your terminal supports them) and colors to make information easy to scan
- Use
jqfor JSON parsing in Bash (see examples above) - Test your script by running it manually with mock JSON input:bash
echo '{"model":{"display_name":"Test"},"workspace":{"current_dir":"/test"}}' | ./statusline.sh - Consider caching expensive operations (like git status) if needed
- Ensure script output is valid UTF-8 for correct display of Chinese characters and emoji
Common ANSI Color Codes
bash
# Text colors
BLACK='\033[0;30m'
RED='\033[0;31m'
GREEN='\033[0;32m'
YELLOW='\033[0;33m'
BLUE='\033[0;34m'
PURPLE='\033[0;35m'
CYAN='\033[0;36m'
WHITE='\033[0;37m'
# Bold colors
BOLD_BLACK='\033[1;30m'
BOLD_RED='\033[1;31m'
BOLD_GREEN='\033[1;32m'
BOLD_YELLOW='\033[1;33m'
BOLD_BLUE='\033[1;34m'
BOLD_PURPLE='\033[1;35m'
BOLD_CYAN='\033[1;36m'
BOLD_WHITE='\033[1;37m'
# Background colors
BG_BLACK='\033[40m'
BG_RED='\033[41m'
BG_GREEN='\033[42m'
BG_YELLOW='\033[43m'
BG_BLUE='\033[44m'
BG_PURPLE='\033[45m'
BG_CYAN='\033[46m'
BG_WHITE='\033[47m'
# Reset
NC='\033[0m' # No ColorTroubleshooting
Status Line Not Showing
- Check if the script is executable:
chmod +x ~/.codebuddy/statusline.sh - Ensure the script outputs to stdout (not stderr)
- Verify JSON paths are correct:
echo '{}' | ~/.codebuddy/statusline.sh
Chinese Characters or Emoji Displaying Incorrectly
- Ensure your terminal supports UTF-8 encoding
- Check the script file is saved as UTF-8
- Add at the beginning of the script:
export LANG=en_US.UTF-8
Colors Not Displaying
- Check if your terminal supports ANSI colors
- Ensure using
echo -eto interpret escape sequences - Verify color codes are correct
Git Information Not Showing
- Ensure running in a git repository
- Check if git command is in PATH
- Verify permission to read
.gitdirectory
Script Executing Slowly
- Cache expensive operations (like git status)
- Avoid network requests in status line scripts
- Use background processes to update cached information
Configuration Examples
User-Level Configuration
In ~/.codebuddy/settings.json:
json
{
"statusLine": {
"type": "command",
"command": "~/.codebuddy/statusline.sh",
"padding": 0
}
}Project-Level Configuration
In .codebuddy/settings.json:
json
{
"statusLine": {
"type": "command",
"command": "./.codebuddy/statusline.sh"
}
}This allows different projects to use different status line styles.
Recommended Tools
- jq: JSON parsing tool, essential
- bc: For floating-point calculations (cost comparison)
- git: Display branch and status information
- date: Display time information
Installation:
bash
# macOS
brew install jq bc
# Ubuntu/Debian
sudo apt-get install jq bc
# CentOS/RHEL
sudo yum install jq bcRelated Resources
- Settings Configuration - Learn about complete configuration options
- Hooks Documentation - Learn about more customization features
- Slash Commands - Use
/statuslinefor quick configuration
Personalize CodeBuddy Code with a custom status line that fits your workflow