Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
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
26 changes: 16 additions & 10 deletions rust/src/providers/claude/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -682,7 +682,11 @@ impl ClaudeProvider {

// Fallback: collect all percentages in order. Activity stats carry
// their own percentages, which must never be read as plan limits.
if session_percent.is_none() && !activity_stats {
// Without a "Current session" row (weekly-only plans) the first
// percentage belongs to a weekly window, so there is no fallback
// (upstream steipete/CodexBar#4914).
if session_percent.is_none() && !activity_stats && clean_lower.contains("current session")
{
let all_percents: Vec<f64> = percent_matches(&clean).collect();
if !all_percents.is_empty() {
session_percent = Some(all_percents[0]);
Expand Down Expand Up @@ -727,15 +731,17 @@ impl ClaudeProvider {
}

// Build usage snapshot
let session_used = session_percent.unwrap_or(0.0);
let primary = RateWindow::with_details(
session_used,
Some(300), // 5 hour session window
session_reset
.as_deref()
.and_then(|reset| parse_claude_reset_date(reset, now, Some(300))),
session_reset,
);
let primary = match session_percent {
Some(session_used) => RateWindow::with_details(
session_used,
Some(300), // 5 hour session window
session_reset
.as_deref()
.and_then(|reset| parse_claude_reset_date(reset, now, Some(300))),
session_reset,
),
None => RateWindow::no_active_session(),
};

let mut usage = UsageSnapshot::new(primary);

Expand Down
24 changes: 24 additions & 0 deletions rust/src/providers/claude/tests.rs
Original file line number Diff line number Diff line change
Expand Up @@ -326,6 +326,30 @@ fn parse_err(output: &str) -> ProviderError {
.expect_err("should reject")
}

/// Plans without a 5-hour limit print no "Current session" row. The first
/// percentage on the panel is then the weekly one and must not become the
/// session (VibeTV-shop/vibetv#614, upstream steipete/CodexBar#4914).
#[test]
fn weekly_only_cli_screen_keeps_session_empty() {
let usage = parse_ok(
r#"
Status Config Usage

Current week (all models)
████ 8% used
Resets Nov 9 at 9am (America/New_York)

Current week (Fable only)
▌ 0% used
Resets Nov 9 at 9am (America/New_York)
"#,
)
.usage;
assert!(usage.primary.is_informational);
assert_eq!(usage.primary.used_percent, 0.0);
assert_eq!(usage.secondary.map(|w| w.used_percent), Some(8.0));
}

#[test]
fn parses_current_cli_usage_screen() {
let output = r#"
Expand Down
Loading