Overview
The bash generator creates self-contained, optimized bash scripts that display statusline information in Claude Code terminals. The generation system is template-based with conditional sections determined by user configuration.
Generator Architecture
Main Generator Function
The core generator function is generateBashStatusline() in src/generators/bash-generator.ts:
export function generateBashStatusline ( config : StatuslineConfig ) : string {
const hasGit = config . features . includes ( 'git' )
const hasUsage = config . features . some ( f =>
[ 'usage' , 'session' , 'tokens' , 'burnrate' ]. includes ( f )
)
const hasDirectory = config . features . includes ( 'directory' )
const hasModel = config . features . includes ( 'model' )
const hasContext = config . features . includes ( 'context' )
// Build usage feature config
const usageConfig = {
enabled: hasUsage && config . ccusageIntegration ,
showCost: config . features . includes ( 'usage' ),
showTokens: config . features . includes ( 'tokens' ),
showBurnRate: config . features . includes ( 'burnrate' ),
showSession: config . features . includes ( 'session' ),
showProgressBar: config . theme !== 'minimal'
}
// Generate script with conditional sections
const script = `#!/bin/bash
# Generated by cc-statusline v ${ VERSION }
input=$(cat)
${ config . logging ? generateLoggingCode () : '' }
${ generateColorBashCode ({ enabled: config . colors , theme: config . theme }) }
${ hasGit ? generateGitBashCode ( gitConfig , config . colors ) : '' }
${ hasUsage ? generateUsageBashCode ( usageConfig , config . colors ) : '' }
${ generateDisplaySection ( config , gitConfig , usageConfig ) }
`
return script . replace ( / \n\n\n + / g , ' \n\n ' ). trim () + ' \n '
}
Feature Flag System
Feature flags control which bash code blocks are included:
Feature Detection
Conditional Generation
const hasGit = config . features . includes ( 'git' )
const hasUsage = config . features . some ( f =>
[ 'usage' , 'session' , 'tokens' , 'burnrate' ]. includes ( f )
)
const hasDirectory = config . features . includes ( 'directory' )
const hasModel = config . features . includes ( 'model' )
const hasContext = config . features . includes ( 'context' )
Only enabled features generate corresponding bash code, keeping scripts minimal.
Script Structure
Generated Script Anatomy
#!/bin/bash
# Header: Version, timestamp, configuration
STATUSLINE_VERSION = "1.4.0"
input = $( cat ) # Read JSON input from stdin
# Check jq availability
HAS_JQ = 0
if command -v jq > /dev/null 2>&1 ; then
HAS_JQ = 1
fi
# Optional: Logging code
# Color definitions
# Utility functions
# Feature-specific code (git, usage, context)
# Display section
Every script includes metadata:
const timestamp = new Date (). toISOString ()
const script = `#!/bin/bash
# Generated by cc-statusline v ${ VERSION } (https://www.npmjs.com/package/@chongdashu/cc-statusline)
# Custom Claude Code statusline - Created: ${ timestamp }
# Theme: ${ config . theme } | Colors: ${ config . colors } | Features: ${ config . features . join ( ', ' ) }
STATUSLINE_VERSION=" ${ VERSION } "
JSON Parsing System
jq vs Fallback Parser
Scripts include two JSON parsing strategies:
if [ " $HAS_JQ " -eq 1 ]; then
current_dir = $( echo " $input " | jq -r '.workspace.current_dir // .cwd // "unknown"' 2> /dev/null | sed "s|^ $HOME |~|g" )
model_name = $( echo " $input " | jq -r '.model.display_name // "Claude"' 2> /dev/null )
fi
else
# Bash fallback for JSON extraction
current_dir = $( echo " $input " | grep -o '"workspace"[[:space:]]*:[[:space:]]*{[^}]*"current_dir"[[:space:]]*:[[:space:]]*"[^"]*"' | sed 's/.*"current_dir"[[:space:]]*:[[:space:]]*"\([^"]*\)".*/\1/' | sed 's/\\\\\\/\//g' )
[ -z " $current_dir " ] && current_dir = "unknown"
current_dir = $( echo " $current_dir " | sed "s|^ $HOME |~|g" )
fi
The fallback parser uses a reusable utility function (src/generators/bash-generator.ts:88-121):
extract_json_string () {
local json = " $1 "
local key = " $2 "
local default = " ${3 :- } "
# For nested keys like workspace.current_dir, get the last part
local field = "${ key ##* .}"
field = "${ field %% * }" # Remove any jq operators
# Try to extract string value (quoted)
local value = $( echo " $json " | grep -o " \\ " \$ {field} \\ "[[:space:]]*:[[:space:]]* \\ "[^ \\ "]* \\ "" | head -1 | sed 's/.*:[[:space:]]*" \( [^"]*\)". * / \1 /')
# Convert escaped backslashes to forward slashes for Windows paths
if [ -n "$value" ]; then
value=$(echo "$value" | sed 's/ \\\\\\ / \/ /g')
fi
# If no string value found, try to extract number value (unquoted)
if [ -z "$value" ] || [ "$value" = "null" ]; then
value=$(echo "$json" | grep -o "\\"\${field}\\"[[:space:]]*:[[:space:]]*[0-9.]+" | head -1 | sed 's/. * :[[:space:]] * \( [0-9.]+ \) . * / \1 /')
fi
# Return value or default
if [ -n "$value" ] && [ "$value" != "null" ]; then
echo "$value"
else
echo "$default"
fi
}
Quote Escaping
The Critical Bug-Prone Area
Lines 100-105 in bash-generator.ts contain grep patterns requiring double escaping . This is the most error-prone part of the codebase.
Escaping Rules
TypeScript Template Literal : Needs \\ for a single backslash
Bash Script : Needs \" for escaped quotes
Combined : \\"\\${field}\\" produces "${field}" in the final bash script
Example
TypeScript Source
Generated Bash
Final Execution
// In bash-generator.ts
local value = $ ( echo "$json" | grep - o " \\ " \\ $ { field }\\ "[[:space:]]*:[[:space:]]* \\ " [ ^ \\ "]* \\ "" | head -1 )
Feature Generators
Git Code Generation
From src/features/git.ts:
export function generateGitBashCode ( config : GitConfig , colors : boolean ) : string {
return `
# ---- git information ----
git_branch=""
if command -v git >/dev/null 2>&1 && git rev-parse --git-dir >/dev/null 2>&1; then
git_branch=$(git symbolic-ref --short HEAD 2>/dev/null || git rev-parse --short HEAD 2>/dev/null)
fi
${ colors ? `git_color() { printf ' \\ 033[38;5;158m'; } # mint green` : '' }
`
}
Usage Code Generation
From src/features/usage.ts:
export function generateUsageBashCode ( config : UsageConfig , colors : boolean ) : string {
if ( ! config . enabled ) return ''
return `
# ---- usage tracking via ccusage ----
${ config . showCost ? `cost_usd=""` : '' }
${ config . showTokens ? `tot_tokens=""` : '' }
${ config . showBurnRate ? `
cost_per_hour=""
tpm=""
` : '' }
# Execute ccusage with locking mechanism
if command -v npx >/dev/null 2>&1; then
# [Lock-based ccusage execution code]
fi
${ colors ? generateUsageColors () : '' }
`
}
Display Section Generation
The display section creates the final output (src/generators/bash-generator.ts:214-293):
function generateDisplaySection ( config : StatuslineConfig , gitConfig : any , usageConfig : any ) : string {
return `
# ---- render statusline ----
# Line 1: Core info (directory, git, model, claude code version, output style)
${ config . features . includes ( 'directory' ) ? `printf '📁 %s%s%s' "$(dir_color)" "$current_dir" "$(rst)"` : '' }${ gitConfig . enabled ? `
if [ -n "$git_branch" ]; then
printf ' 🌿 %s%s%s' "$(git_color)" "$git_branch" "$(rst)"
fi` : '' }
# Line 2: Context and session time
line2="" ${ config . features . includes ( 'context' ) ? `
if [ -n "$context_pct" ]; then
context_bar=$(progress_bar "$context_remaining_pct" 10)
line2="🧠 $(context_color)Context Remaining: \$ {context_pct} [ \$ {context_bar}]$(rst)"
fi` : '' }
# Print lines
if [ -n "$line2" ]; then
printf ' \\ n%s' "$line2"
fi
printf ' \\ n'
`
}
Optimization Techniques
Template Cleanup
Remove excessive blank lines:
return script . replace ( / \n\n\n + / g , ' \n\n ' ). trim () + ' \n '
Conditional Code Blocks
Only generate code for enabled features:
$ { hasGit ? generateGitBashCode ( gitConfig , config . colors ) : '' }
$ { hasUsage ? generateUsageBashCode ( usageConfig , config . colors ) : '' }
POSIX Compliance
Generated scripts work with sh, bash, and zsh:
Avoid bash-specific features when possible
Use portable command syntax
Provide fallbacks for bash-only features
Testing Generated Scripts
Preview Command
Test scripts before installation:
cc-statusline preview .claude/statusline.sh
The preview command:
Loads the generated script
Pipes mock JSON data to it
Captures and displays output
Reports performance metrics
Mock Data Generation
From src/utils/tester.ts:
const mockInput = {
workspace: { current_dir: process . cwd () },
model: { display_name: "Claude Sonnet" , version: "4" },
session_id: "test-session" ,
version: "1.0.85" ,
output_style: { name: "default" },
context_window: {
context_window_size: 200000 ,
current_usage: { input_tokens: 25000 }
}
}
Next Steps
Architecture Learn about project architecture
Contributing Start contributing to the project