claude-code-status-line 1.2.5

A configurable status line for Claude Code with powerline arrows, context tracking, and quota monitoring
Documentation
use crate::colors::SectionColors;
use crate::utils::visible_len;
use serde::{Deserialize, Serialize};

#[derive(Clone, PartialEq, Debug)]
pub enum SectionKind {
    Generic,
    QuotaCompact(String),
    QuotaDetailed(String),
    ContextCompact,
    ContextDetailed,
}

#[derive(Clone)]
pub struct Section {
    pub kind: SectionKind,
    pub content: String,
    pub priority: u16,         // Lower number = higher priority (0 = always show)
    pub colors: SectionColors, // Per-section colors
    pub width: usize,          // Cached visible width (excluding padding/separators)
}

impl Section {
    pub fn new(content: String, priority: u16, colors: SectionColors) -> Self {
        let width = visible_len(&content);
        Section {
            kind: SectionKind::Generic,
            content,
            priority,
            colors,
            width,
        }
    }

    pub fn new_quota_compact(
        label: &str,
        content: String,
        priority: u16,
        colors: SectionColors,
    ) -> Self {
        let width = visible_len(&content);
        Section {
            kind: SectionKind::QuotaCompact(label.to_string()),
            content,
            priority,
            colors,
            width,
        }
    }

    pub fn new_quota_detailed(
        label: &str,
        content: String,
        priority: u16,
        colors: SectionColors,
    ) -> Self {
        let width = visible_len(&content);
        Section {
            kind: SectionKind::QuotaDetailed(label.to_string()),
            content,
            priority,
            colors,
            width,
        }
    }

    pub fn new_context_compact(content: String, priority: u16, colors: SectionColors) -> Self {
        let width = visible_len(&content);
        Section {
            kind: SectionKind::ContextCompact,
            content,
            priority,
            colors,
            width,
        }
    }

    pub fn new_context_detailed(content: String, priority: u16, colors: SectionColors) -> Self {
        let width = visible_len(&content);
        Section {
            kind: SectionKind::ContextDetailed,
            content,
            priority,
            colors,
            width,
        }
    }
}

/// Context usage information (used for display formatting)
pub struct ContextUsageInfo {
    pub percentage: f64,
    pub current_usage_tokens: u64,
    pub context_window_size: u64,
    pub is_exact: bool, // true if from direct percentage, false if calculated
}

#[derive(Debug, Deserialize)]
pub struct ClaudeInput {
    pub workspace: Option<Workspace>,
    pub model: Option<Model>,
    pub context_window: Option<ContextWindow>,
    pub cost: Option<Cost>,
    pub output_style: Option<OutputStyle>,
}

#[derive(Debug, Deserialize)]
pub struct Workspace {
    pub current_dir: Option<String>,
}

#[derive(Debug, Deserialize)]
pub struct Model {
    pub display_name: Option<String>,
}

#[derive(Debug, Deserialize)]
pub struct OutputStyle {
    pub name: Option<String>,
}

#[derive(Debug, Deserialize)]
pub struct ContextWindow {
    pub context_window_size: Option<u64>,
    pub current_usage: Option<CurrentUsage>,
    pub used_percentage: Option<f64>,
    pub remaining_percentage: Option<f64>,
}

#[derive(Debug, Deserialize)]
pub struct CurrentUsage {
    pub input_tokens: Option<u64>,
    pub _output_tokens: Option<u64>,
    pub cache_creation_input_tokens: Option<u64>,
    pub cache_read_input_tokens: Option<u64>,
}

#[derive(Debug, Deserialize)]
pub struct Cost {
    pub total_cost_usd: Option<f64>,
    pub total_duration_ms: Option<u64>,
    pub total_api_duration_ms: Option<u64>,
    pub total_lines_added: Option<u64>,
    pub total_lines_removed: Option<u64>,
}

#[derive(Debug, Deserialize)]
pub struct QuotaResponse {
    pub five_hour: Option<QuotaLimit>,
    pub seven_day: Option<QuotaLimit>,
}

#[derive(Debug, Deserialize)]
pub struct QuotaLimit {
    pub utilization: f64,
    pub resets_at: Option<String>,
}

#[derive(Debug, Deserialize)]
pub struct KeychainCredentials {
    #[serde(rename = "claudeAiOauth")]
    pub claude_ai_oauth: Option<OAuthCredentials>,
}

#[derive(Debug, Deserialize)]
pub struct OAuthCredentials {
    #[serde(rename = "accessToken")]
    pub access_token: String,
}

// Quota data structure
#[derive(Debug, Deserialize, Serialize, Clone)]
pub struct QuotaData {
    pub five_hour_pct: Option<f64>,
    pub five_hour_resets_at: Option<String>,
    pub seven_day_pct: Option<f64>,
    pub seven_day_resets_at: Option<String>,
}

#[derive(Serialize, Deserialize)]
pub struct CachedQuota {
    pub timestamp: u64,
    pub data: QuotaData,
}

#[derive(Debug, PartialEq)]
pub struct GitInfo {
    pub branch: String,
    pub is_dirty: bool,
    pub repo_name: Option<String>,
    pub lines_added: usize,
    pub lines_removed: usize,
}