Skip to content
Open
Show file tree
Hide file tree
Changes from 1 commit
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
3 changes: 2 additions & 1 deletion src/config/loader.rs
Original file line number Diff line number Diff line change
Expand Up @@ -124,7 +124,8 @@ impl Config {
}

let content = fs::read_to_string(config_path)?;
let config: Config = toml::from_str(&content)?;
let mut config: Config = toml::from_str(&content)?;
config.migrate();
Ok(config)
}

Expand Down
57 changes: 57 additions & 0 deletions src/config/types.rs
Original file line number Diff line number Diff line change
Expand Up @@ -69,6 +69,10 @@ pub enum SegmentId {
Git,
ContextWindow,
Usage,
#[serde(rename = "usage_5h")]
Usage5h,
#[serde(rename = "usage_7d")]
Usage7d,
Cost,
Session,
OutputStyle,
Expand Down Expand Up @@ -110,13 +114,26 @@ pub struct OutputStyle {
pub name: String,
}

#[derive(Deserialize)]
pub struct RateLimitPeriod {
pub used_percentage: f64,
pub resets_at: Option<i64>, // Unix timestamp from Claude Code
}

#[derive(Deserialize)]
pub struct RateLimits {
pub five_hour: Option<RateLimitPeriod>,
pub seven_day: Option<RateLimitPeriod>,
}

#[derive(Deserialize)]
pub struct InputData {
pub model: Model,
pub workspace: Workspace,
pub transcript_path: String,
pub cost: Option<Cost>,
pub output_style: Option<OutputStyle>,
pub rate_limits: Option<RateLimits>,
}

// OpenAI-style nested token details
Expand Down Expand Up @@ -271,6 +288,46 @@ impl Config {
!self.matches_theme(&self.theme)
}

/// Migrate old config: if usage exists but usage_5h/usage_7d don't, add them
pub fn migrate(&mut self) {
let has_usage = self.segments.iter().any(|s| s.id == SegmentId::Usage);
let has_5h = self.segments.iter().any(|s| s.id == SegmentId::Usage5h);
let has_7d = self.segments.iter().any(|s| s.id == SegmentId::Usage7d);

if has_usage && !has_5h && !has_7d {
// Find the old usage segment to copy its colors
let usage_seg = self.segments.iter().find(|s| s.id == SegmentId::Usage).cloned();
if let Some(old) = usage_seg {
// Find position of old usage to insert after it
let pos = self.segments.iter().position(|s| s.id == SegmentId::Usage).unwrap();

let seg_5h = SegmentConfig {
id: SegmentId::Usage5h,
enabled: old.enabled,
icon: old.icon.clone(),
colors: old.colors.clone(),
styles: old.styles.clone(),
options: old.options.clone(),
};
let seg_7d = SegmentConfig {
id: SegmentId::Usage7d,
enabled: old.enabled,
icon: old.icon.clone(),
colors: old.colors.clone(),
styles: old.styles.clone(),
options: old.options.clone(),
};

// Disable old usage
self.segments[pos].enabled = false;

// Insert new ones after old usage
self.segments.insert(pos + 1, seg_5h);
self.segments.insert(pos + 2, seg_7d);
}
}
}

/// Compare two segment configs for equality
fn segment_matches(&self, current: &SegmentConfig, preset: &SegmentConfig) -> bool {
current.id == preset.id
Expand Down
2 changes: 1 addition & 1 deletion src/core/segments/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -33,4 +33,4 @@ pub use model::ModelSegment;
pub use output_style::OutputStyleSegment;
pub use session::SessionSegment;
pub use update::UpdateSegment;
pub use usage::UsageSegment;
pub use usage::{Usage5hSegment, Usage7dSegment, UsageSegment};
Loading