Reference documentation for the Claude Code Delegation System. Main documentation: CLAUDE.md
- Overview
- Script Location
- Display Components
- Hook Integration
- State Files
- Usage Examples
- Troubleshooting
The StatusLine is a dynamic status display system that provides real-time visibility into workflow execution state and active delegations in the Claude Code Delegation System.
- Real-time updates - Status changes as workflows progress
- Execution mode indicator - Shows sequential vs parallel mode
- Active delegation count - Tracks running subagents
- Wave information - Shows current wave in parallel workflows
- Recent events - Displays last workflow events
- Non-blocking cost tracking - Background cache refresh for sub-100ms response times
StatusLine is displayed:
- During delegation workflows
- When subagents are active
- Updated automatically by hooks
Primary Script: scripts/statusline.py
Runtime: Python 3.12+ (cross-platform: Windows, macOS, Linux)
The statusline script is installed during system setup and configured via the statusLine field in settings.json:
# Verify installation
ls -la scripts/statusline.py
# Test manually (reads JSON from stdin)
echo '{}' | python3 scripts/statusline.pyThe statusline script performs:
- Read state files - Loads
.claude/state/active_delegations.json - Format status - Creates compact, color-coded display
- Output status - Single-line format for terminal display
- Update display - Called by hooks on state changes
Shows the current execution mode:
| Indicator | Meaning |
|---|---|
[SEQ] |
Sequential execution mode |
[PAR] |
Parallel execution mode |
Shows the number of currently running subagents:
Active: 2
Active: 0- No subagents runningActive: 3- Three subagents executing concurrently
Shows the current wave in parallel workflows:
Wave 1
Wave 2
Waves execute sequentially, with all subagents in a wave completing before the next wave starts.
Shows the last significant workflow event:
Last: Phase-A completed (113s)
Last: Wave 1 sync complete
Last: delegation-orchestrator started
[MODE] Active: N Wave W | Last: Event description
Examples:
[SEQ] Active: 1 | Last: code-cleanup-optimizer started
[PAR] Active: 3 Wave 1 | Last: Phase-A started
[PAR] Active: 2 Wave 1 | Last: Phase-B completed (87s)
[PAR] Active: 0 Wave 2 | Last: Wave 1 sync complete
[SEQ] Active: 0 | Last: Workflow complete
The StatusLine is updated by hooks throughout the workflow lifecycle.
SessionStart Hook
|
v
StatusLine: [SEQ] Active: 0 | Last: Session initialized
|
v
PreToolUse Hook (on delegation)
|
v
StatusLine: [SEQ] Active: 1 | Last: delegation-orchestrator started
|
v
Task Tool (spawns subagents)
|
v
StatusLine: [PAR] Active: 3 Wave 1 | Last: Wave 1 started
|
v
SubagentStop Hook (subagent completes)
|
v
StatusLine: [PAR] Active: 2 Wave 1 | Last: Phase-A completed (113s)
|
v
SubagentStop Hook (wave complete)
|
v
StatusLine: [PAR] Active: 0 Wave 2 | Last: Wave 1 sync complete
|
v
Stop Hook (session ends)
|
v
StatusLine cleared
# Called at session initialization
~/.claude/scripts/statusline.sh initUpdates StatusLine with:
- Initial mode (SEQ by default)
- Active count: 0
- Event: "Session initialized"
# Called when delegation begins
~/.claude/scripts/statusline.sh delegation_start "$AGENT_NAME"Updates StatusLine with:
- Mode based on workflow plan
- Active count incremented
- Event: Agent name started
# Called when subagent completes
~/.claude/scripts/statusline.sh subagent_stop "$SESSION_ID" "$DURATION"Updates StatusLine with:
- Active count decremented
- Event: Phase completed with duration
- Wave sync check (if all wave subagents complete)
# Called at session end
~/.claude/scripts/statusline.sh clearClears StatusLine display.
StatusLine reads from two state files to determine current status.
Location: .claude/state/active_delegations.json
Schema:
{
"version": "2.0",
"workflow_id": "wf_20250111_143022",
"execution_mode": "parallel",
"active_delegations": [
{
"delegation_id": "deleg_20250111_143022_001",
"phase_id": "phase_a",
"session_id": "sess_abc123",
"wave": 1,
"status": "active",
"started_at": "2025-01-11T14:30:22Z",
"agent": "codebase-context-analyzer"
},
{
"delegation_id": "deleg_20250111_143023_002",
"phase_id": "phase_b",
"session_id": "sess_def456",
"wave": 1,
"status": "active",
"started_at": "2025-01-11T14:30:23Z",
"agent": "tech-lead-architect"
}
],
"max_concurrent": 8
}Fields Used by StatusLine:
| Field | StatusLine Component |
|---|---|
execution_mode |
Mode indicator ([SEQ]/[PAR]) |
active_delegations.length |
Active count |
active_delegations[].wave |
Wave number |
active_delegations[].agent |
Event agent name |
active_delegations[].status |
Completion detection |
Location: /tmp/claude_session_log.txt
Format:
[2025-01-11 14:30:22] SESSION_START session_id=sess_abc123 type=main
[2025-01-11 14:30:25] SUBAGENT_START session_id=sess_def456 agent=codebase-context-analyzer
[2025-01-11 14:32:18] SUBAGENT_STOP session_id=sess_def456 duration=113s exit_code=0
[2025-01-11 14:35:00] SESSION_STOP session_id=sess_abc123 duration=278s
Used For:
- Recent events (last 5 entries)
- Subagent completion times
- Error messages
Open a separate terminal to watch status updates:
# Watch status updates every second
watch -n 1 ~/.claude/scripts/statusline.sh
# Or use a continuous loop
while true; do
clear
~/.claude/scripts/statusline.sh
sleep 1
done# Check current status
~/.claude/scripts/statusline.sh
# Check state file directly
cat .claude/state/active_delegations.json | jq .
# Check recent session events
tail -20 /tmp/claude_session_log.txt# Enable verbose output
DEBUG=1 ~/.claude/scripts/statusline.sh
# Check what state files exist
ls -la .claude/state/
# Verify JSON validity
cat .claude/state/active_delegations.json | jq .# Terminal 1: Monitor status
watch -n 1 ~/.claude/scripts/statusline.sh
# Terminal 2: Run workflow
/workflow-orchestrator:delegate "Analyze auth system AND design payment API"StatusLine progression:
[SEQ] Active: 0 | Last: Session initialized
[SEQ] Active: 1 | Last: delegation-orchestrator started
[PAR] Active: 2 Wave 1 | Last: codebase-context-analyzer started
[PAR] Active: 2 Wave 1 | Last: tech-lead-architect started
[PAR] Active: 1 Wave 1 | Last: codebase-context-analyzer completed (87s)
[PAR] Active: 0 Wave 1 | Last: tech-lead-architect completed (102s)
[PAR] Active: 0 | Last: Wave 1 sync complete
[SEQ] Active: 0 | Last: Workflow complete
The statusline cost tracking was optimized from a cold-start latency of ~28 seconds to ~0.078 seconds (360x improvement). This section documents the optimization strategy.
The original implementation made two sequential bunx ccusage calls (one for daily cost, one for session cost) on every statusline refresh. Each call took ~14 seconds (package resolution + execution), resulting in a ~28-second cold start that blocked the statusline display.
The optimization applies three techniques:
1. Merged API calls
Two separate bunx ccusage invocations were merged into a single call using the -i flag, which returns per-project breakdown including daily totals. Both daily and session costs are extracted from one response.
# Before: 2 sequential calls (~28s total)
# bunx ccusage daily --json --since $TODAY # daily cost
# bunx ccusage daily --json --since $TODAY -p . # session cost
# After: 1 call (~14s, but only in background)
# bunx ccusage daily --json --since $TODAY -i # both values2. Background cache refresh via subprocess.Popen
When the cache is expired, the statusline returns immediately with stale values (or $... placeholders on first run) and spawns a background process to refresh the cache. The background process uses start_new_session=True to fully detach from the parent.
Statusline call:
1. Check cache file → valid? → return cached values (< 0.001s)
2. Cache expired? → return stale values immediately
3. Spawn background Python process (fire-and-forget)
4. Background process: fetch costs → write cache file → exit
5. Next statusline call picks up fresh cache
3. Extended cache TTL
COST_CACHE_TTL_SECONDS was increased from 60 to 300 seconds. Cost data changes slowly (per-session, not per-turn), making a 5-minute TTL appropriate.
4. Lock file for concurrent refresh prevention
A lock file (statusline_cost_refresh.lock) prevents multiple background refresh processes from running simultaneously. The lock is considered stale after 60 seconds.
| Scenario | Latency | Behavior |
|---|---|---|
| Warm cache (< 300s old) | < 0.001s | Return cached values directly |
| Stale cache (> 300s old) | ~0.078s | Return stale values, spawn background refresh |
| Cold start (no cache) | ~0.078s | Return $... placeholders, spawn background refresh |
| Background refresh | ~14s | Runs in detached process, writes to cache file |
| File | Location | Purpose |
|---|---|---|
statusline_cost_cache.json |
System temp dir | Cached daily and session costs with timestamp |
statusline_cost_refresh.lock |
System temp dir | Prevents concurrent background refreshes |
{
"daily_cost": "$12.34",
"session_cost": "$3.45",
"timestamp": 1736611822.5,
"cwd": "/Users/user/project"
}The cwd field is used for cache invalidation when switching between projects.
Symptom: Status display is stale or not changing.
Diagnosis:
# Check script permissions
ls -la ~/.claude/scripts/statusline.sh
chmod +x ~/.claude/scripts/statusline.sh
# Check state file exists
ls -la .claude/state/active_delegations.json
# Verify hooks are calling statusline
grep statusline ~/.claude/hooks/*/*.sh
# Test script directly
~/.claude/scripts/statusline.shSolutions:
-
Fix permissions:
chmod +x ~/.claude/scripts/statusline.sh -
Create state directory:
mkdir -p .claude/state
-
Reinstall scripts:
cp -r src/scripts ~/.claude/ chmod +x ~/.claude/scripts/*.sh
Symptom: Wave number doesn't match expected execution phase.
Diagnosis:
# Check active_delegations.json schema
cat .claude/state/active_delegations.json | jq .
# Verify SubagentStop hook is updating state
tail -f /tmp/claude_session_log.txt | grep SUBAGENT_STOP
# Check wave values in state
cat .claude/state/active_delegations.json | jq '.active_delegations[].wave'Solutions:
-
Verify JSON structure:
# Check for JSON errors cat .claude/state/active_delegations.json | jq . || echo "Invalid JSON"
-
Reset state:
rm .claude/state/active_delegations.json # Let next workflow recreate it -
Check SubagentStop hook:
bash -n ~/.claude/hooks/SubagentStop/log_subagent_stop.sh
Symptom: Active delegation count doesn't match running subagents.
Diagnosis:
# Count active delegations in state
cat .claude/state/active_delegations.json | jq '.active_delegations | length'
# Count running claude processes
ps aux | grep claude | grep -v grep | wc -l
# Check for orphaned entries
cat .claude/state/active_delegations.json | jq '.active_delegations[] | select(.status == "active")'Solutions:
-
Clear stale state:
cat .claude/state/active_delegations.json | jq '.active_delegations = []' > /tmp/clean_state.json mv /tmp/clean_state.json .claude/state/active_delegations.json
-
Restart workflow:
# Clear all state rm -f .claude/state/active_delegations.json rm -f .claude/state/delegated_sessions.txt # Start fresh /workflow-orchestrator:delegate "Your task"
Symptom: Script produces errors or crashes.
Diagnosis:
# Check for syntax errors
bash -n ~/.claude/scripts/statusline.sh
# Run with debug output
bash -x ~/.claude/scripts/statusline.sh
# Check dependencies (jq required)
which jq || echo "jq not installed"Solutions:
-
Install jq:
# macOS brew install jq # Ubuntu/Debian sudo apt-get install jq
-
Fix script syntax:
# Re-copy from source cp src/scripts/statusline.sh ~/.claude/scripts/ chmod +x ~/.claude/scripts/statusline.sh
Symptom: StatusLine shows defaults because state file doesn't exist.
Diagnosis:
# Check if state file exists
ls -la .claude/state/active_delegations.json
# Check if state directory exists
ls -la .claude/state/
# Check CLAUDE_PROJECT_DIR setting
echo $CLAUDE_PROJECT_DIRSolutions:
-
Create state directory:
mkdir -p .claude/state
-
Initialize state file:
echo '{"version":"2.0","execution_mode":"sequential","active_delegations":[]}' > .claude/state/active_delegations.json
-
Check project directory:
# Ensure CLAUDE_PROJECT_DIR points to correct location export CLAUDE_PROJECT_DIR=$PWD
- Hook Debugging Guide - Hook integration details
- Environment Variables - CLAUDE_PROJECT_DIR setting
- Main Documentation - Complete system reference