codex-cost 0.1.0

Local web dashboard for inspecting Codex token usage from session logs.
Documentation
use chrono::{DateTime, Utc};
use serde::{Deserialize, Serialize};

pub const UNKNOWN: &str = "Unknown";

#[derive(Debug, Clone, Default, PartialEq, Eq, Serialize, Deserialize)]
pub struct TokenUsage {
    pub input_tokens: u64,
    pub cached_input_tokens: u64,
    pub output_tokens: u64,
    pub reasoning_output_tokens: u64,
    pub total_tokens: u64,
}

#[derive(Debug, Clone, PartialEq, Eq, Serialize, Deserialize)]
pub struct UsageEvent {
    pub timestamp: DateTime<Utc>,
    pub session_id: String,
    pub thread: String,
    pub project: String,
    pub model: String,
    pub effort: String,
    pub context_window: Option<u64>,
    pub usage: TokenUsage,
    pub cumulative_total_tokens: Option<u64>,
    pub source_file: String,
}

#[derive(Debug, Clone, PartialEq, Eq, Serialize, Deserialize)]
pub struct UsageWarning {
    pub file: String,
    pub line: Option<usize>,
    pub message: String,
}

#[derive(Debug, Clone, Default, PartialEq, Eq, Serialize, Deserialize)]
pub struct UsageLoad {
    pub events: Vec<UsageEvent>,
    pub warnings: Vec<UsageWarning>,
    pub session_count: usize,
}

#[derive(Debug, Clone, Default, PartialEq, Eq, Serialize, Deserialize)]
pub struct Totals {
    pub all_time_tokens: u64,
    pub today_tokens: u64,
    pub last_7_days_tokens: u64,
    pub event_count: usize,
    pub session_count: usize,
    pub input_tokens: u64,
    pub cached_input_tokens: u64,
    pub output_tokens: u64,
    pub reasoning_output_tokens: u64,
}

#[derive(Debug, Clone, PartialEq, Eq, Serialize, Deserialize)]
pub struct DistributionPoint {
    pub label: String,
    pub total_tokens: u64,
    pub event_count: usize,
}

#[derive(Debug, Clone, PartialEq, Eq, Serialize, Deserialize)]
pub struct TimelinePoint {
    pub bucket: String,
    pub total_tokens: u64,
    pub event_count: usize,
}

#[derive(Debug, Clone, Default, PartialEq, Eq, Serialize, Deserialize)]
pub struct DimensionDistributions {
    pub projects: Vec<DistributionPoint>,
    pub models: Vec<DistributionPoint>,
    pub threads: Vec<DistributionPoint>,
    pub efforts: Vec<DistributionPoint>,
    pub context_windows: Vec<DistributionPoint>,
}

#[derive(Debug, Clone, PartialEq, Eq, Serialize, Deserialize)]
pub struct UsageSummary {
    pub generated_at: DateTime<Utc>,
    pub totals: Totals,
    pub timeline: Vec<TimelinePoint>,
    pub distributions: DimensionDistributions,
    pub events: Vec<UsageEvent>,
    pub warnings: Vec<UsageWarning>,
}