Status Detection
The status detection engine analyzes Claude Code terminal output to determine the current session state. This document describes the detection patterns and state machine logic.
Two-Level Status System
Status detection uses a two-level hierarchy:
Level 1: Primary Status
The primary status represents the fundamental state of the session:
| Status | Description |
|---|---|
idle | Claude is ready and waiting for user input |
active | Claude is performing work |
waiting | Claude needs user response |
stuck | No activity for extended period |
dead | Session no longer exists |
Level 2: Detail Status
Detail provides context for the primary status:
Active Details:
thinking- Claude is processing the requestusing_tools- Claude is executing tool callsresponding- Claude is generating a responsecompacting- Claude is compressing conversation history
Waiting Details:
permission- Claude needs permission to proceedquestion- Claude has asked a question
Idle Details:
ready- Initial ready statewaiting_input- Waiting for user command
Detection Patterns
The StatusDetector analyzes terminal output for specific patterns:
Idle Detection
Pattern: `> ` followed by `? for shortcuts`
Result: idle (waiting_input)
This indicates Claude Code is at the command prompt, ready for input.
Active Detection
Pattern: `Thinking` or `∴`
Result: active (thinking)
Pattern: `●\s+[A-Z]` (tool indicator)
Result: active (using_tools)
Pattern: Text generation without other indicators
Result: active (responding)
Pattern: `Compacting conversation`
Result: active (compacting)
Waiting Detection
Pattern: `❯` followed by Yes/No options
Result: waiting (permission)
Pattern: `(y/n)` prompt
Result: waiting (permission)
Pattern: `Would you like` or `Which` questions
Result: waiting (question)
Stuck Detection
Condition: No state change for 15+ seconds
Result: stuck
The unchanged count increments with each detection cycle that produces the same state.
Implementation
class StatusDetector {
private lastContent: string = '';
private unchangedCount: number = 0;
private stuckThreshold: number = 15;
detectStatus(content: string): ClaudeStatus {
// Check if content changed
if (content === this.lastContent) {
this.unchangedCount++;
} else {
this.unchangedCount = 0;
this.lastContent = content;
}
// Detect primary status and detail
const { primary, detail } = this.analyzeContent(content);
// Check for stuck condition
if (this.unchangedCount >= this.stuckThreshold) {
return {
primary: 'stuck',
detail: null,
health: 'STUCK',
timestamp: new Date().toISOString(),
unchangedCount: this.unchangedCount
};
}
return {
primary,
detail,
health: this.determineHealth(primary),
timestamp: new Date().toISOString(),
unchangedCount: this.unchangedCount
};
}
}
Health State Machine
Health transitions follow this logic:
ALIVE ──(stuck)──> STUCK ──(activity)──> RECOVERED
↑ │ │
└──────────────────┴───────────────────────┘
│
(session closed)
↓
DEAD
| Current | Condition | Next |
|---|---|---|
| ALIVE | 15+ seconds unchanged | STUCK |
| ALIVE | Session closed | DEAD |
| STUCK | Activity detected | RECOVERED |
| STUCK | Session closed | DEAD |
| RECOVERED | Normal operation | ALIVE |
| DEAD | (terminal state) | DEAD |
Customization
Adjusting Stuck Threshold
The default stuck threshold is 15 seconds. To modify:
const detector = new StatusDetector({
stuckThreshold: 30 // 30 seconds
});
Adding Custom Patterns
To detect additional patterns, extend the pattern matching:
private analyzeContent(content: string): { primary: PrimaryStatus; detail: StatusDetail } {
// Custom pattern example
if (content.includes('Custom pattern')) {
return { primary: 'active', detail: 'custom_activity' };
}
// Default detection logic
// ...
}
Edge Cases
Rapid State Changes
During tool execution, status may rapidly alternate between states. The system uses the most recent detection without debouncing to ensure accurate real-time display.
Long-Running Operations
Some operations (large file reads, complex computations) may appear stuck but are actually processing. Consider:
- Increasing stuck threshold for known long operations
- Monitoring specific patterns that indicate ongoing work
- Using the health state to distinguish between stuck and long-running
Terminal Noise
ANSI escape codes and control characters are handled during content processing. The detector normalizes terminal output before pattern matching.