Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
111 commits
Select commit Hold shift + click to select a range
3d16cd6
Port 0.56.4 growing Codex rollouts
Finesssee Sep 6, 2026
33d6a21
Port 0.56.4 Antigravity step timestamps
Finesssee Sep 6, 2026
3c34223
Port 0.56.4 managed workspace authority
Finesssee Sep 6, 2026
b56a73f
Port 0.56.4 Windows UI and Bedrock guidance
Finesssee Sep 6, 2026
4dc8af8
Port 0.56.4 Claude Cloudflare recovery
Finesssee Sep 6, 2026
3d901b1
Fix Bedrock monitoring guidance
Finesssee Sep 6, 2026
e2abce9
Fix 0.56.4 native Rust compile regressions
Finesssee Sep 7, 2026
ce41298
Finish 0.56.4 native Rust compile fixes
Finesssee Sep 7, 2026
c6e263d
Finish 0.56.4 native Tauri compile fixes
Finesssee Sep 7, 2026
f2e388c
Fix 0.56.4 shared timestamp regression test
Finesssee Sep 7, 2026
ff0ec22
Make 0.56.4 Rust port Clippy-clean
Finesssee Sep 7, 2026
26ff5fe
Port 0.56.5 completed empty Codex fragments
Finesssee Sep 6, 2026
4271c99
Port 0.56.5 Kilo auth recovery
Finesssee Sep 6, 2026
60ddc97
Port 0.56.5 z.ai compact token totals
Finesssee Sep 6, 2026
8f624a2
Port 0.56.5 Antigravity turn timestamp correlation
Finesssee Sep 7, 2026
f3fd1e0
Port 0.56.5 Codex extra-credit reconciliation
Finesssee Sep 7, 2026
9950c25
Port 0.56.5 retained Codex scan range
Finesssee Sep 7, 2026
76fb48b
Port 0.56.5 abandoned spend refresh cleanup
Finesssee Sep 7, 2026
606cb26
Port 0.56.5 z.ai reset plausibility
Finesssee Sep 7, 2026
a05cfed
Refactor z.ai reset plausibility
Finesssee Sep 7, 2026
cde5217
Extract z.ai provider tests
Finesssee Sep 7, 2026
814eaab
Port 0.56.5 Claude identity-less account actions
Finesssee Sep 7, 2026
974f07f
Fix Claude account action freshness proof
Finesssee Sep 7, 2026
f84a7af
Refactor 0.56.5 Codex empty-fragment helper
Finesssee Sep 7, 2026
cc10785
Fix Claude account action test fixtures
Finesssee Sep 7, 2026
9e7fee9
Fix 0.56.5 native Rust compile regressions
Finesssee Sep 7, 2026
e2ed904
Finish 0.56.5 native Rust compile fixes
Finesssee Sep 7, 2026
b156898
Finish 0.56.5 native Tauri compile fixes
Finesssee Sep 7, 2026
c5f682d
Fix 0.56.5 native Rust test regressions
Finesssee Sep 7, 2026
145c3c6
Preserve terminal Codex catch-up pause across range changes
Finesssee Sep 7, 2026
5471ed9
Make 0.56.5 Rust port Clippy-clean
Finesssee Sep 7, 2026
9ef4ab7
Port 0.56.6 Kiro unavailable plan summaries
Finesssee Sep 7, 2026
9d43a61
Fix 0.56.6 Kiro unavailable summary semantics
Finesssee Sep 7, 2026
464d7e5
Cover 0.56.6 Hooks label parity
Finesssee Sep 7, 2026
1608620
Port 0.56.6 Kimi membership recovery
Finesssee Sep 7, 2026
50e1d13
Port 0.56.6 exhausted automatic quota selection
Finesssee Sep 7, 2026
4f3c496
Fix 0.56.6 exhausted switcher policy
Finesssee Sep 7, 2026
b7fa271
Port 0.56.6 lazy Codex history reads
Finesssee Sep 7, 2026
bbb4b85
Port 0.56.6 GPT-6 Astra pricing
Finesssee Sep 7, 2026
cd7586c
Port 0.56.6 Codex subscription dates
Finesssee Sep 7, 2026
1b6ee8b
Fix 0.56.6 native Rust compile regressions
Finesssee Sep 7, 2026
3939ff6
Finish 0.56.6 native Rust compile fixes
Finesssee Sep 7, 2026
15996e8
Fix 0.56.6 native Rust test regressions
Finesssee Sep 7, 2026
3f4778b
Make 0.56.6 Rust port Clippy-clean
Finesssee Sep 7, 2026
97d92ae
Port 0.56.7 Moonshot regional balance currency
Finesssee Sep 7, 2026
1100e70
Port 0.56.7 ElevenLabs API key diagnostics
Finesssee Sep 7, 2026
6518c76
Fix 0.56.7 models.dev atomic cache writes
Finesssee Sep 7, 2026
292f693
Port 0.56.7 CommandCode plan retention
Finesssee Sep 7, 2026
64eea63
Fix 0.56.7 native Rust test field access
Finesssee Sep 7, 2026
0ce3cb6
Make 0.56.7 Rust port Clippy-clean
Finesssee Sep 7, 2026
98c694e
ci: rerun hosted checks for 0.56.5
Finesssee Sep 7, 2026
da3025c
Port 0.56.8 Claude scoped weekly labels
Finesssee Sep 7, 2026
d764fe5
Port 0.56.8 Copilot identity-first account reuse
Finesssee Sep 7, 2026
e497e7d
Port 0.56.8 Codex authenticated HTTP errors
Finesssee Sep 7, 2026
f52d6ce
Port 0.56.8 Antigravity UUID-less bookkeeping
Finesssee Sep 7, 2026
49ddee5
Port 0.56.8 Claude credential freshness
Finesssee Sep 7, 2026
65f0bf1
Port 0.56.8 Kiro regional enrichment
Finesssee Sep 7, 2026
ac878ac
ci: rerun hosted checks for 0.56.8 snapshot
Finesssee Sep 7, 2026
06c5bb9
Fix 0.56.8 Copilot Clippy lint
Finesssee Sep 7, 2026
3f696fa
Stabilize 0.56.8 Claude label test
Finesssee Sep 7, 2026
bf2448c
refactor(claude): move recovery policy into provider
Finesssee Sep 8, 2026
65987ed
refactor: unify usage spend refresh state
Finesssee Sep 8, 2026
7082c47
refactor: move metric policy to providers
Finesssee Sep 8, 2026
6cae852
refactor: move atomic file write to shared layer
Finesssee Sep 8, 2026
385ef15
refactor: localize scoped window labels by marker
Finesssee Sep 8, 2026
77ade63
style: apply workspace rustfmt
Finesssee Sep 8, 2026
8698980
style: apply workspace rustfmt
Finesssee Sep 8, 2026
64d34cb
style: apply workspace rustfmt
Finesssee Sep 8, 2026
4815d32
fix: attach async_trait to provider trait
Finesssee Sep 8, 2026
b924b14
fix(claude): attach async_trait to provider impl
Finesssee Sep 8, 2026
fe5b7a5
Merge repaired 0.56.3 base
Finesssee Sep 8, 2026
6f5085d
Merge repaired 0.56.4 base
Finesssee Sep 8, 2026
9ed7182
fix: repair merged provider fetch contract formatting
Finesssee Sep 8, 2026
973b196
Merge repaired 0.56.5 base
Finesssee Sep 8, 2026
7ecb6e9
Merge repaired 0.56.6 base
Finesssee Sep 8, 2026
047575f
Merge repaired 0.56.7 base
Finesssee Sep 8, 2026
80ef86d
Merge formatted repaired base for #438
Finesssee Sep 8, 2026
8188496
Merge formatted repaired base for #439
Finesssee Sep 8, 2026
b72e81c
Merge formatted repaired base for #440
Finesssee Sep 8, 2026
11ebedd
Merge formatted repaired base for #441
Finesssee Sep 8, 2026
e32a0e6
Merge formatted repaired base for #444
Finesssee Sep 8, 2026
181e7aa
Merge repaired 0.56.3 base
Finesssee Sep 8, 2026
b8b0917
Merge repaired 0.56.4 base
Finesssee Sep 8, 2026
4639328
Merge repaired 0.56.5 base
Finesssee Sep 8, 2026
109931e
Merge repaired 0.56.6 base
Finesssee Sep 8, 2026
917e9a0
Merge repaired 0.56.9 base
Finesssee Sep 8, 2026
06dcec3
test: complete Claude fetch fixtures
Finesssee Sep 8, 2026
6d9d48a
Merge repaired child base for #440
Finesssee Sep 8, 2026
08585b4
Merge repaired child base for #441
Finesssee Sep 8, 2026
8fdb1a2
Merge repaired child base for #444
Finesssee Sep 8, 2026
0a7824f
Merge final repaired base for #438
Finesssee Sep 8, 2026
36953d0
Merge final repaired base for #439
Finesssee Sep 8, 2026
28eb93d
Merge final repaired base for #440
Finesssee Sep 8, 2026
d5c1ba7
Merge final repaired base for #441
Finesssee Sep 8, 2026
9636592
Merge final repaired base for #444
Finesssee Sep 8, 2026
a970b6f
Merge final format fix for #438
Finesssee Sep 8, 2026
a213eab
Merge final format fix for #439
Finesssee Sep 8, 2026
3aef903
Merge final format fix for #440
Finesssee Sep 8, 2026
5b9d903
Merge final format fix for #441
Finesssee Sep 8, 2026
764df17
Merge final format fix for #444
Finesssee Sep 8, 2026
e142f3f
test: complete Claude fetch result fixtures
Finesssee Sep 8, 2026
7bdf9d5
Merge stabilized 0.56.3 base
Finesssee Sep 8, 2026
4a781d3
Merge stabilized 0.56.4 base
Finesssee Sep 8, 2026
549dda1
Merge stabilized child base for #440
Finesssee Sep 8, 2026
c37bd9b
Merge stabilized child base for #441
Finesssee Sep 8, 2026
c0df15a
Merge stabilized child base for #444
Finesssee Sep 8, 2026
896c2c4
Merge remote-tracking branch 'origin/main' into HEAD
Finesssee Sep 8, 2026
9bc7ece
Merge latest stacked base for #439
Finesssee Sep 8, 2026
df27cde
Merge latest stacked base for #440
Finesssee Sep 8, 2026
52577f9
Merge latest stacked base for #441
Finesssee Sep 8, 2026
d543133
Merge latest stacked base for #444
Finesssee Sep 8, 2026
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
29 changes: 29 additions & 0 deletions apps/desktop-tauri/src-tauri/src/commands/bridge.rs
Original file line number Diff line number Diff line change
Expand Up @@ -103,6 +103,10 @@ pub struct CostSnapshotBridge {
#[serde(default)]
pub balance: Option<f64>,
#[serde(default)]
pub balance_updated_at: Option<String>,
#[serde(default)]
pub account_id: Option<String>,
#[serde(default)]
pub formatted_balance: Option<String>,
#[serde(default)]
pub daily: Vec<CostDailyPointBridge>,
Expand Down Expand Up @@ -165,6 +169,15 @@ pub struct SessionEquivalentForecastSnapshot {
pub weekly_used_percent: f64,
}

/// Subscription dates from an authenticated OpenAI dashboard/API response.
#[derive(Debug, Clone, Serialize, Deserialize)]
#[serde(rename_all = "camelCase")]
pub struct SubscriptionMetadataSnapshot {
pub starts_at: Option<String>,
pub expires_at: Option<String>,
pub renews_at: Option<String>,
}

/// A frontend-friendly snapshot of one provider's usage data.
#[derive(Debug, Clone, Serialize, Deserialize)]
#[serde(rename_all = "camelCase")]
Expand Down Expand Up @@ -193,8 +206,12 @@ pub struct ProviderUsageSnapshot {
pub plan_name: Option<String>,
#[serde(default)]
pub account_email: Option<String>,
#[serde(default)]
pub subscription: Option<SubscriptionMetadataSnapshot>,
#[serde(default = "default_source_label")]
pub source_label: String,
#[serde(default)]
pub has_successful_claude_cli_quota: bool,
/// Defaults to launch time when absent so the card renders as fresh.
#[serde(default)]
pub updated_at: String,
Expand Down Expand Up @@ -378,6 +395,8 @@ impl ProviderUsageSnapshot {
formatted_used: c.format_used(),
formatted_limit: c.format_limit(),
balance: c.balance,
balance_updated_at: c.balance_updated_at.map(|dt| dt.to_rfc3339()),
account_id: c.account_id.clone(),
formatted_balance: c.format_balance(),
daily: c
.daily
Expand All @@ -391,7 +410,15 @@ impl ProviderUsageSnapshot {
}),
plan_name: usage.login_method.clone(),
account_email: usage.account_email.clone(),
subscription: usage.subscription.as_ref().map(|subscription| {
SubscriptionMetadataSnapshot {
starts_at: subscription.starts_at.map(|date| date.to_rfc3339()),
expires_at: subscription.expires_at.map(|date| date.to_rfc3339()),
renews_at: subscription.renews_at.map(|date| date.to_rfc3339()),
}
}),
source_label: result.source_label.clone(),
has_successful_claude_cli_quota: result.has_successful_claude_cli_quota,
updated_at: usage.updated_at.to_rfc3339(),
error: None,
error_state: codexbar::core::ProviderStateKind::Ready,
Expand Down Expand Up @@ -437,7 +464,9 @@ impl ProviderUsageSnapshot {
cost: None,
plan_name: None,
account_email: None,
subscription: None,
source_label: String::new(),
has_successful_claude_cli_quota: false,
updated_at: chrono::Utc::now().to_rfc3339(),
error: Some(error),
error_state: state_kind,
Expand Down
108 changes: 100 additions & 8 deletions apps/desktop-tauri/src-tauri/src/commands/codex_accounts.rs
Original file line number Diff line number Diff line change
Expand Up @@ -105,13 +105,19 @@ pub(crate) async fn refresh_codex_account_lanes(
let api = CodexAccountApi::new();
let home_path = account.codex_home_path.clone();
let email_hint = account.email_hint.clone();
let workspace_account_id = account.effective_workspace_account_id();
match tokio::time::timeout(
std::time::Duration::from_secs(DEFAULT_FETCH_TIMEOUT_SECONDS),
api.fetch_snapshot(&home_path, email_hint.as_deref(), true),
api.fetch_snapshot_for_workspace(
&home_path,
email_hint.as_deref(),
workspace_account_id.as_deref(),
true,
),
)
.await
{
Ok(Ok(snapshot)) => Some((account.id, snapshot)),
Ok(Ok(snapshot)) => Some((account, snapshot)),
Ok(Err(e)) => {
tracing::debug!(
"codex account lane {} failed: {}",
Expand All @@ -128,10 +134,28 @@ pub(crate) async fn refresh_codex_account_lanes(
}));
}

let current_accounts = load_codex_accounts().unwrap_or_default();
let current_by_id: HashMap<Uuid, CodexAccount> = current_accounts
.iter()
.cloned()
.map(|account| (account.id, account))
.collect();
let mut snapshots = SnapshotStore::new().load().unwrap_or_default();
snapshots.retain(|id, snapshot| {
current_by_id
.get(id)
.is_some_and(|account| account_snapshot_belongs_to(account, snapshot))
});
for handle in handles {
if let Ok(Some((id, snapshot))) = handle.await {
snapshots.insert(id, snapshot);
if let Ok(Some((fetched_account, snapshot))) = handle.await
&& current_by_id
.get(&fetched_account.id)
.is_some_and(|current| {
account_lane_is_current(&fetched_account, current)
&& account_snapshot_belongs_to(current, &snapshot)
})
{
snapshots.insert(fetched_account.id, snapshot);
}
}
if let Err(e) = SnapshotStore::new().save(&snapshots) {
Expand Down Expand Up @@ -232,16 +256,30 @@ pub async fn codex_account_fetch(
let api = CodexAccountApi::new();
let home_path = target.codex_home_path.clone();
let email_hint = target.email_hint.clone();
let workspace_account_id = target.effective_workspace_account_id();
let snapshot = tokio::time::timeout(
std::time::Duration::from_secs(DEFAULT_FETCH_TIMEOUT_SECONDS),
api.fetch_snapshot(&home_path, email_hint.as_deref(), true),
api.fetch_snapshot_for_workspace(
&home_path,
email_hint.as_deref(),
workspace_account_id.as_deref(),
true,
),
)
.await
.map_err(|_| "Timed out waiting for the Codex usage API.".to_string())?
.map_err(into_api_message)?;

// Persist snapshot to the snapshot store, keyed by account id.
if let Ok(mut snapshots) = SnapshotStore::new().load() {
if let Ok(mut snapshots) = SnapshotStore::new().load()
&& load_codex_accounts().ok().is_some_and(|accounts| {
accounts.iter().any(|account| {
account.id == target.id
&& account_lane_is_current(&target, account)
&& account_snapshot_belongs_to(account, &snapshot)
})
})
{
snapshots.insert(target.id, snapshot.clone());
let _ = SnapshotStore::new().save(&snapshots);
}
Expand Down Expand Up @@ -306,6 +344,58 @@ fn into_api_message(error: CodexApiError) -> String {
}
}

fn account_home_key(account: &CodexAccount) -> String {
std::path::absolute(&account.codex_home_path)
.unwrap_or_else(|_| account.codex_home_path.clone())
.to_string_lossy()
.to_lowercase()
}

/// In-flight results are only authoritative for the selected workspace and
/// managed home that started the request.
fn account_lane_is_current(started: &CodexAccount, current: &CodexAccount) -> bool {
started.id == current.id
&& account_home_key(started) == account_home_key(current)
&& started.effective_workspace_account_id() == current.effective_workspace_account_id()
}

fn account_snapshot_belongs_to(
account: &CodexAccount,
snapshot: &codexbar::codex_accounts::AccountUsageSnapshot,
) -> bool {
let snapshot_workspace = snapshot
.provider_account_id
.as_deref()
.map(str::trim)
.filter(|id| !id.is_empty())
.map(str::to_lowercase);
match (account.effective_workspace_account_id(), snapshot_workspace) {
(Some(account_workspace), Some(snapshot_workspace)) => {
account_workspace == snapshot_workspace
}
(None, None) => true,
_ => false,
}
}

fn snapshots_for_accounts(
accounts: &[CodexAccount],
snapshots: HashMap<Uuid, codexbar::codex_accounts::AccountUsageSnapshot>,
) -> HashMap<Uuid, codexbar::codex_accounts::AccountUsageSnapshot> {
let accounts_by_id: HashMap<Uuid, &CodexAccount> = accounts
.iter()
.map(|account| (account.id, account))
.collect();
snapshots
.into_iter()
.filter(|(id, snapshot)| {
accounts_by_id
.get(id)
.is_some_and(|account| account_snapshot_belongs_to(account, snapshot))
})
.collect()
}

#[derive(Debug, serde::Serialize)]
#[serde(rename_all = "camelCase")]
pub struct CodexAccountsStateBridge {
Expand All @@ -320,10 +410,12 @@ pub fn get_codex_accounts_state(
) -> Result<CodexAccountsStateBridge, String> {
let _guard = state.lock().map_err(|e| e.to_string())?;
let accounts = load_codex_accounts()?;
let display_names = display_names_by_id(&accounts);
let snapshots = snapshots_for_accounts(&accounts, codex_account_snapshots()?);
Ok(CodexAccountsStateBridge {
display_names: display_names_by_id(&accounts),
accounts,
snapshots: codex_account_snapshots()?,
display_names,
snapshots,
})
}

Expand Down
Loading