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
1 change: 1 addition & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,7 @@
- Widgets: opt-in display of Claude model-scoped weekly quotas (for example Fable) projected from the shared usage snapshot, off by default (#2645). Thanks @alfredjbclaw!

### Fixed
- Claude: let Auto reuse a working CLI fallback when OAuth Keychain access is revoked by Claude Code token rotation, distinguish revoked access from missing credentials, and keep last-known quota history visible with its capture age when every live source fails (#2516). Thanks @axisrow and everyone who supplied forensics!
- Menu: apply the cost summary display style to every provider's menu card, so Submenu only hides inline cost rows for z.ai and other providers (#2976). Thanks @ar0nbg!
- Cost history: align x-axis date labels with their bars in status-menu charts (#2974). Thanks @Yuxin-Qiao!
- Codex: preserve completed empty local history as known-zero usage and spend without fabricating zeroes for incomplete scans (#2932). Thanks @Yuxin-Qiao!
Expand Down
25 changes: 25 additions & 0 deletions Sources/CodexBar/Providers/Claude/ClaudeUIErrorMapper.swift
Original file line number Diff line number Diff line change
@@ -0,0 +1,25 @@
import CodexBarCore
import Foundation

@MainActor
enum ClaudeUIErrorMapper {
static func userFacingMessage(
_ raw: String?,
staleSnapshotUpdatedAt: Date?,
localize: (String) -> String = L) -> String?
{
guard let raw else { return nil }
let trimmed = raw.trimmingCharacters(in: .whitespacesAndNewlines)
guard !trimmed.isEmpty else { return nil }

let message = if trimmed == ClaudeOAuthCredentialsError.keychainAccessRevoked.localizedDescription {
localize("claude_oauth_keychain_access_revoked")
} else {
trimmed
}
guard let staleSnapshotUpdatedAt else { return message }
return message + " " + String(
format: localize("claude_showing_last_known_usage"),
staleSnapshotUpdatedAt.relativeDescription())
}
}
2 changes: 2 additions & 0 deletions Sources/CodexBar/Resources/ar.lproj/Localizable.strings
Original file line number Diff line number Diff line change
Expand Up @@ -1454,3 +1454,5 @@
"5-hour usage" = "الاستخدام خلال 5 ساعات";
"7-day usage" = "الاستخدام خلال 7 أيام";
"Total usage" = "إجمالي الاستخدام";
"claude_oauth_keychain_access_revoked" = "تم إلغاء وصول CodexBar إلى سلسلة مفاتيح Claude بسبب تدوير الرمز المميز في Claude Code. انقر على «تحديث» لمنح الوصول مجددًا، أو بدّل مصدر استخدام Claude إلى CLI/Web.";
"claude_showing_last_known_usage" = "يتم عرض آخر بيانات استخدام معروفة، تم التقاطها %@.";
2 changes: 2 additions & 0 deletions Sources/CodexBar/Resources/ca.lproj/Localizable.strings
Original file line number Diff line number Diff line change
Expand Up @@ -1453,3 +1453,5 @@
"5-hour usage" = "Ús de 5 hores";
"7-day usage" = "Ús de 7 dies";
"Total usage" = "Ús total";
"claude_oauth_keychain_access_revoked" = "L'accés al clauer de Claude s'ha revocat per la rotació del testimoni de Claude Code. Feu clic a Actualitza per tornar a concedir l'accés, o canvieu l'origen d'ús de Claude a CLI/Web.";
"claude_showing_last_known_usage" = "Es mostra l'últim ús conegut capturat %@.";
2 changes: 2 additions & 0 deletions Sources/CodexBar/Resources/de.lproj/Localizable.strings
Original file line number Diff line number Diff line change
Expand Up @@ -1451,3 +1451,5 @@
"5-hour usage" = "5-Stunden-Nutzung";
"7-day usage" = "7-Tage-Nutzung";
"Total usage" = "Gesamtnutzung";
"claude_oauth_keychain_access_revoked" = "Der Zugriff auf den Claude-Schlüsselbund wurde durch die Token-Rotation von Claude Code widerrufen. Klicken Sie auf „Aktualisieren“, um den Zugriff erneut zu gewähren, oder stellen Sie die Claude-Nutzungsquelle auf CLI/Web um.";
"claude_showing_last_known_usage" = "Letzte bekannte Nutzung wird angezeigt (erfasst: %@).";
2 changes: 2 additions & 0 deletions Sources/CodexBar/Resources/en.lproj/Localizable.strings
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,8 @@
"ollama_safari_cookie_access_hint" = "Safari cookies need Full Disk Access for CodexBar (System Settings > Privacy & Security).";
"ollama_browser_cookie_decryption_denied" = "%@ cookie decryption was declined in Keychain. Open the provider card and click Refresh (⌘R) to request Keychain access again.";
"ollama_browser_cookie_decryption_disabled" = "%@ cookie decryption is disabled in CodexBar; enable Keychain access and refresh.";
"claude_oauth_keychain_access_revoked" = "Claude Keychain access was revoked by Claude Code's token rotation. Click Refresh to re-grant access, or switch Claude Usage source to CLI/Web.";
"claude_showing_last_known_usage" = "Showing last-known usage captured %@.";

" providers" = " providers";
"(System)" = "(System)";
Expand Down
2 changes: 2 additions & 0 deletions Sources/CodexBar/Resources/es.lproj/Localizable.strings
Original file line number Diff line number Diff line change
Expand Up @@ -1449,3 +1449,5 @@
"5-hour usage" = "Uso de 5 horas";
"7-day usage" = "Uso de 7 días";
"Total usage" = "Uso total";
"claude_oauth_keychain_access_revoked" = "El acceso al llavero de Claude fue revocado por la rotación del token de Claude Code. Haz clic en Actualizar para volver a conceder acceso o cambia el origen del uso de Claude a CLI/Web.";
"claude_showing_last_known_usage" = "Mostrando el último uso conocido, capturado %@.";
2 changes: 2 additions & 0 deletions Sources/CodexBar/Resources/fa.lproj/Localizable.strings
Original file line number Diff line number Diff line change
Expand Up @@ -1454,3 +1454,5 @@
"5-hour usage" = "مصرف ۵ ساعته";
"7-day usage" = "مصرف ۷ روزه";
"Total usage" = "مصرف کل";
"claude_oauth_keychain_access_revoked" = "دسترسی به Keychain کلود با چرخش توکن Claude Code لغو شد. برای اعطای مجدد دسترسی روی «تازه‌سازی» کلیک کنید، یا منبع استفاده Claude را به CLI/Web تغییر دهید.";
"claude_showing_last_known_usage" = "آخرین میزان استفاده شناخته‌شده که در %@ ثبت شده نمایش داده می‌شود.";
2 changes: 2 additions & 0 deletions Sources/CodexBar/Resources/fr.lproj/Localizable.strings
Original file line number Diff line number Diff line change
Expand Up @@ -1450,3 +1450,5 @@
"5-hour usage" = "Utilisation sur 5 heures";
"7-day usage" = "Utilisation sur 7 jours";
"Total usage" = "Utilisation totale";
"claude_oauth_keychain_access_revoked" = "L’accès au trousseau Claude a été révoqué par la rotation du jeton de Claude Code. Cliquez sur Actualiser pour accorder à nouveau l’accès, ou définissez la source d’utilisation de Claude sur CLI/Web.";
"claude_showing_last_known_usage" = "Affichage de la dernière utilisation connue, capturée %@.";
2 changes: 2 additions & 0 deletions Sources/CodexBar/Resources/gl.lproj/Localizable.strings
Original file line number Diff line number Diff line change
Expand Up @@ -1450,3 +1450,5 @@
"5-hour usage" = "Uso de 5 horas";
"7-day usage" = "Uso de 7 días";
"Total usage" = "Uso total";
"claude_oauth_keychain_access_revoked" = "O acceso ao chaveiro de Claude foi revogado pola rotación do token de Claude Code. Preme Actualizar para volver conceder o acceso ou cambia a orixe de uso de Claude a CLI/Web.";
"claude_showing_last_known_usage" = "Mostrando o último uso coñecido, capturado %@.";
2 changes: 2 additions & 0 deletions Sources/CodexBar/Resources/id.lproj/Localizable.strings
Original file line number Diff line number Diff line change
Expand Up @@ -1454,3 +1454,5 @@
"5-hour usage" = "Penggunaan 5 jam";
"7-day usage" = "Penggunaan 7 hari";
"Total usage" = "Total penggunaan";
"claude_oauth_keychain_access_revoked" = "Akses Rantai Kunci Claude dicabut akibat rotasi token Claude Code. Klik Segarkan untuk memberikan akses lagi, atau ubah sumber penggunaan Claude ke CLI/Web.";
"claude_showing_last_known_usage" = "Menampilkan penggunaan terakhir yang diketahui, diambil %@.";
2 changes: 2 additions & 0 deletions Sources/CodexBar/Resources/it.lproj/Localizable.strings
Original file line number Diff line number Diff line change
Expand Up @@ -1454,3 +1454,5 @@
"5-hour usage" = "Utilizzo di 5 ore";
"7-day usage" = "Utilizzo di 7 giorni";
"Total usage" = "Utilizzo totale";
"claude_oauth_keychain_access_revoked" = "L'accesso al portachiavi di Claude è stato revocato dalla rotazione del token di Claude Code. Fai clic su Aggiorna per concedere nuovamente l'accesso oppure imposta la fonte di utilizzo di Claude su CLI/Web.";
"claude_showing_last_known_usage" = "Visualizzazione dell'ultimo utilizzo noto, acquisito %@.";
2 changes: 2 additions & 0 deletions Sources/CodexBar/Resources/ja.lproj/Localizable.strings
Original file line number Diff line number Diff line change
Expand Up @@ -1451,3 +1451,5 @@
"5-hour usage" = "5時間の使用量";
"7-day usage" = "7日間の使用量";
"Total usage" = "合計使用量";
"claude_oauth_keychain_access_revoked" = "Claude Code のトークン更新により、Claude キーチェーンへのアクセスが取り消されました。「更新」をクリックしてアクセスを再許可するか、Claude の使用量の取得元を CLI/Web に切り替えてください。";
"claude_showing_last_known_usage" = "最後に取得した既知の使用量を表示しています(取得: %@)。";
2 changes: 2 additions & 0 deletions Sources/CodexBar/Resources/ko.lproj/Localizable.strings
Original file line number Diff line number Diff line change
Expand Up @@ -1418,3 +1418,5 @@
"5-hour usage" = "5시간 사용량";
"7-day usage" = "7일 사용량";
"Total usage" = "총 사용량";
"claude_oauth_keychain_access_revoked" = "Claude Code의 토큰 교체로 Claude 키체인 접근 권한이 취소되었습니다. 새로 고침을 클릭해 접근 권한을 다시 부여하거나 Claude 사용량 소스를 CLI/Web으로 전환하세요.";
"claude_showing_last_known_usage" = "마지막으로 확인된 사용량을 표시 중입니다(캡처: %@).";
2 changes: 2 additions & 0 deletions Sources/CodexBar/Resources/nl.lproj/Localizable.strings
Original file line number Diff line number Diff line change
Expand Up @@ -1450,3 +1450,5 @@
"5-hour usage" = "5-uursgebruik";
"7-day usage" = "7-dagengebruik";
"Total usage" = "Totaal gebruik";
"claude_oauth_keychain_access_revoked" = "De toegang tot de Claude-sleutelhanger is ingetrokken door de tokenrotatie van Claude Code. Klik op Vernieuwen om opnieuw toegang te verlenen of zet de Claude-gebruiksbron op CLI/Web.";
"claude_showing_last_known_usage" = "De laatst bekende gebruiksgegevens worden weergegeven (vastgelegd: %@).";
2 changes: 2 additions & 0 deletions Sources/CodexBar/Resources/pl.lproj/Localizable.strings
Original file line number Diff line number Diff line change
Expand Up @@ -1454,3 +1454,5 @@
"5-hour usage" = "Użycie 5-godzinne";
"7-day usage" = "Użycie 7-dniowe";
"Total usage" = "Łączne użycie";
"claude_oauth_keychain_access_revoked" = "Dostęp do pęku kluczy Claude został cofnięty wskutek rotacji tokenu przez Claude Code. Kliknij Odśwież, aby ponownie przyznać dostęp, albo przełącz źródło użycia Claude na CLI/Web.";
"claude_showing_last_known_usage" = "Wyświetlane jest ostatnie znane użycie zarejestrowane %@.";
2 changes: 2 additions & 0 deletions Sources/CodexBar/Resources/pt-BR.lproj/Localizable.strings
Original file line number Diff line number Diff line change
Expand Up @@ -1451,3 +1451,5 @@
"5-hour usage" = "Uso de 5 horas";
"7-day usage" = "Uso de 7 dias";
"Total usage" = "Uso total";
"claude_oauth_keychain_access_revoked" = "O acesso às Chaves do Claude foi revogado pela rotação do token do Claude Code. Clique em Atualizar para conceder o acesso novamente ou altere a fonte de uso do Claude para CLI/Web.";
"claude_showing_last_known_usage" = "Exibindo o último uso conhecido, capturado %@.";
2 changes: 2 additions & 0 deletions Sources/CodexBar/Resources/ru.lproj/Localizable.strings
Original file line number Diff line number Diff line change
Expand Up @@ -1452,3 +1452,5 @@
"5-hour usage" = "Использование за 5 часов";
"7-day usage" = "Использование за 7 дней";
"Total usage" = "Общее использование";
"claude_oauth_keychain_access_revoked" = "Доступ к Связке ключей Claude был отозван из-за ротации токена в Claude Code. Нажмите «Обновить», чтобы повторно предоставить доступ, или переключите источник использования Claude на CLI/Web.";
"claude_showing_last_known_usage" = "Показаны последние известные данные об использовании (получены %@).";
2 changes: 2 additions & 0 deletions Sources/CodexBar/Resources/sv.lproj/Localizable.strings
Original file line number Diff line number Diff line change
Expand Up @@ -1449,3 +1449,5 @@
"5-hour usage" = "5-timmarsanvändning";
"7-day usage" = "7-dagarsanvändning";
"Total usage" = "Total användning";
"claude_oauth_keychain_access_revoked" = "Åtkomsten till Claudes nyckelring återkallades när Claude Code roterade token. Klicka på Uppdatera för att ge åtkomst igen, eller byt Claudes användningskälla till CLI/Web.";
"claude_showing_last_known_usage" = "Visar senast kända användning, registrerad %@.";
2 changes: 2 additions & 0 deletions Sources/CodexBar/Resources/th.lproj/Localizable.strings
Original file line number Diff line number Diff line change
Expand Up @@ -1454,3 +1454,5 @@
"5-hour usage" = "การใช้งาน 5 ชั่วโมง";
"7-day usage" = "การใช้งาน 7 วัน";
"Total usage" = "การใช้งานทั้งหมด";
"claude_oauth_keychain_access_revoked" = "สิทธิ์เข้าถึงพวงกุญแจ Claude ถูกเพิกถอนจากการหมุนเวียนโทเค็นของ Claude Code คลิกรีเฟรชเพื่อให้สิทธิ์อีกครั้ง หรือเปลี่ยนแหล่งที่มาการใช้งาน Claude เป็น CLI/Web";
"claude_showing_last_known_usage" = "กำลังแสดงการใช้งานล่าสุดที่ทราบ ซึ่งบันทึกเมื่อ %@";
2 changes: 2 additions & 0 deletions Sources/CodexBar/Resources/tr.lproj/Localizable.strings
Original file line number Diff line number Diff line change
Expand Up @@ -1452,3 +1452,5 @@
"5-hour usage" = "5 saatlik kullanım";
"7-day usage" = "7 günlük kullanım";
"Total usage" = "Toplam kullanım";
"claude_oauth_keychain_access_revoked" = "Claude Anahtar Zinciri erişimi, Claude Code'un belirteç yenilemesi nedeniyle iptal edildi. Erişimi yeniden vermek için Yenile'ye tıklayın veya Claude Kullanım kaynağını CLI/Web olarak değiştirin.";
"claude_showing_last_known_usage" = "Bilinen son kullanım gösteriliyor (yakalanma zamanı: %@).";
2 changes: 2 additions & 0 deletions Sources/CodexBar/Resources/uk.lproj/Localizable.strings
Original file line number Diff line number Diff line change
Expand Up @@ -1450,3 +1450,5 @@
"5-hour usage" = "Використання за 5 годин";
"7-day usage" = "Використання за 7 днів";
"Total usage" = "Загальне використання";
"claude_oauth_keychain_access_revoked" = "Доступ до В’язки ключів Claude було відкликано через ротацію токена в Claude Code. Натисніть «Оновити», щоб повторно надати доступ, або перемкніть джерело використання Claude на CLI/Web.";
"claude_showing_last_known_usage" = "Показано останні відомі дані про використання (отримано %@).";
2 changes: 2 additions & 0 deletions Sources/CodexBar/Resources/vi.lproj/Localizable.strings
Original file line number Diff line number Diff line change
Expand Up @@ -1451,3 +1451,5 @@
"5-hour usage" = "Mức sử dụng 5 giờ";
"7-day usage" = "Mức sử dụng 7 ngày";
"Total usage" = "Tổng mức sử dụng";
"claude_oauth_keychain_access_revoked" = "Quyền truy cập Chuỗi khóa Claude đã bị thu hồi do Claude Code xoay vòng mã thông báo. Nhấp vào Làm mới để cấp lại quyền truy cập hoặc chuyển nguồn sử dụng Claude sang CLI/Web.";
"claude_showing_last_known_usage" = "Đang hiển thị mức sử dụng đã biết gần nhất, được ghi nhận %@.";
2 changes: 2 additions & 0 deletions Sources/CodexBar/Resources/zh-Hans.lproj/Localizable.strings
Original file line number Diff line number Diff line change
Expand Up @@ -1429,3 +1429,5 @@
"5-hour usage" = "5 小时用量";
"7-day usage" = "7 天用量";
"Total usage" = "总用量";
"claude_oauth_keychain_access_revoked" = "Claude Code 轮换令牌后撤销了对 Claude 钥匙串的访问权限。点击“刷新”以重新授权,或将 Claude 用量来源切换为 CLI/Web。";
"claude_showing_last_known_usage" = "正在显示 %@ 采集的最后已知用量。";
2 changes: 2 additions & 0 deletions Sources/CodexBar/Resources/zh-Hant.lproj/Localizable.strings
Original file line number Diff line number Diff line change
Expand Up @@ -1481,3 +1481,5 @@
"5-hour usage" = "5 小時用量";
"7-day usage" = "7 天用量";
"Total usage" = "總用量";
"claude_oauth_keychain_access_revoked" = "Claude Code 輪替權杖後撤銷了 Claude 鑰匙圈的存取權。按一下「重新整理」以重新授權,或將 Claude 使用量來源切換為 CLI/Web。";
"claude_showing_last_known_usage" = "正在顯示於 %@ 擷取的最後已知使用量。";
4 changes: 4 additions & 0 deletions Sources/CodexBar/UsageStore+Accessors.swift
Original file line number Diff line number Diff line change
Expand Up @@ -153,6 +153,10 @@ extension UsageStore {
switch provider {
case .codex:
return CodexUIErrorMapper.userFacingMessage(raw)
case .claude:
return ClaudeUIErrorMapper.userFacingMessage(
raw,
staleSnapshotUpdatedAt: self.snapshots[provider.instanceID]?.updatedAt)
case .ollama:
return OllamaUIErrorMapper.userFacingMessage(raw)
default:
Expand Down
Loading