Skip to main content

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:

StatusDescription
idleClaude is ready and waiting for user input
activeClaude is performing work
waitingClaude needs user response
stuckNo activity for extended period
deadSession no longer exists

Level 2: Detail Status

Detail provides context for the primary status:

Active Details:

  • thinking - Claude is processing the request
  • using_tools - Claude is executing tool calls
  • responding - Claude is generating a response
  • compacting - Claude is compressing conversation history

Waiting Details:

  • permission - Claude needs permission to proceed
  • question - Claude has asked a question

Idle Details:

  • ready - Initial ready state
  • waiting_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
CurrentConditionNext
ALIVE15+ seconds unchangedSTUCK
ALIVESession closedDEAD
STUCKActivity detectedRECOVERED
STUCKSession closedDEAD
RECOVEREDNormal operationALIVE
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.