Skip to content
Closed
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
22 commits
Select commit Hold shift + click to select a range
854090a
feat(core): generalized usage/spend scanning + pricing foundation
Yuxin-Qiao Jul 31, 2026
c338e8f
Keep Groq out of the cost-capable set in the foundation layer
Yuxin-Qiao Jul 31, 2026
c565404
feat(core): registerable local-history scanner registry + zcode/trae/…
Yuxin-Qiao Aug 1, 2026
1bba0c5
feat(core): unified usage-event layer + shared aggregator, add Copilot
Yuxin-Qiao Aug 1, 2026
3eb62c2
style(tests): apply SwiftFormat to new engine/copilot suites
Yuxin-Qiao Aug 1, 2026
6cfcb0c
feat(core): full-history manual rescan + live scan progress
Yuxin-Qiao Aug 1, 2026
9792595
fix(i18n): translate "Scanning history" into Italian
Yuxin-Qiao Aug 1, 2026
5c2ae86
fix(core): provider ownership + complete-cost + cache-write pricing
Yuxin-Qiao Aug 1, 2026
2d25dab
fix(core): prefer refreshed catalog rates over embedded Gemini table
Yuxin-Qiao Aug 1, 2026
d5f4385
fix(core): fall back to OpenCode's time_created column
Yuxin-Qiao Aug 1, 2026
0adc8a1
feat(core): wire local history scanners into the dashboard loader
Yuxin-Qiao Aug 1, 2026
1d68546
refactor(core): migrate Kimi/MiniMax/Antigravity scanners to the shar…
Yuxin-Qiao Aug 1, 2026
b7110f4
feat(core): retain OpenCode billing ownership evidence end to end
Yuxin-Qiao Aug 1, 2026
f719adf
style: satisfy swift-format lint-macos gate
Yuxin-Qiao Aug 1, 2026
3a22838
fix(core): wire local-history providers into the token refresh pipeline
Yuxin-Qiao Aug 1, 2026
204f1eb
fix(core): preserve billing ownership across merged daily reports
Yuxin-Qiao Aug 1, 2026
65af90d
fix(core): withhold OpenCode headline cost on unpriced days and mark …
Yuxin-Qiao Aug 1, 2026
10fb613
fix(core): omit Trae activity outside the requested history window
Yuxin-Qiao Aug 1, 2026
7ef4935
fix(core): lift the per-file cap for full Codex rescans and bridge ca…
Yuxin-Qiao Aug 1, 2026
b366ef8
fix(core): overflow-safe total checks and Copilot rollup request counts
Yuxin-Qiao Aug 1, 2026
20c8725
fix(scanner): prefer recent OpenCode files before the scan cap
Yuxin-Qiao Aug 2, 2026
40949c0
fix(core): keep outer billing route and withhold partial window costs
Yuxin-Qiao Aug 2, 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
10 changes: 9 additions & 1 deletion Sources/CodexBar/PreferencesSpendDashboardPane.swift
Original file line number Diff line number Diff line change
Expand Up @@ -115,7 +115,15 @@ struct SpendDashboardPane: View {
self.controller.refresh()
} label: {
if self.controller.isRefreshing {
ProgressView().controlSize(.small)
HStack(spacing: 6) {
ProgressView().controlSize(.small)
if let progress = self.controller.codexScanProgress, progress.total > 0 {
Text(L("Scanning history %d/%d", progress.scanned, progress.total))
.font(.caption)
.foregroundStyle(.secondary)
.monospacedDigit()
}
}
} else {
Label(L("Refresh"), systemImage: "arrow.clockwise")
}
Expand Down
1 change: 1 addition & 0 deletions Sources/CodexBar/Resources/ar.lproj/Localizable.strings
Original file line number Diff line number Diff line change
Expand Up @@ -1266,6 +1266,7 @@
"No local cost history yet" = "لا يوجد سجل تكاليف محلي بعد";
"Turn on cost tracking or refresh after using a supported provider." = "فعّل تتبّع التكاليف أو حدّث بعد استخدام مزوّد مدعوم.";
"Refresh failures" = "حالات فشل التحديث";
"Scanning history %d/%d" = "Scanning history %d/%d";
"Native currencies stay separate; Codex account rows exclude Pi session history." = "تبقى العملات الأصلية منفصلة؛ تستبعد صفوف حساب Codex سجل جلسات Pi.";
"Spend unavailable" = "الإنفاق غير متاح";
"Model breakdown unavailable" = "تفصيل الإنفاق حسب النموذج غير متاح";
Expand Down
1 change: 1 addition & 0 deletions Sources/CodexBar/Resources/ca.lproj/Localizable.strings
Original file line number Diff line number Diff line change
Expand Up @@ -1265,6 +1265,7 @@
"No local cost history yet" = "Encara no hi ha historial local de costos";
"Turn on cost tracking or refresh after using a supported provider." = "Activa el seguiment de costos o actualitza després d’utilitzar un proveïdor compatible.";
"Refresh failures" = "Actualitzacions fallides";
"Scanning history %d/%d" = "Scanning history %d/%d";
"Native currencies stay separate; Codex account rows exclude Pi session history." = "Les monedes originals es mantenen separades; les files de comptes de Codex exclouen l’historial de sessions de Pi.";
"Spend unavailable" = "Despesa no disponible";
"Model breakdown unavailable" = "Desglossament per model no disponible";
Expand Down
1 change: 1 addition & 0 deletions Sources/CodexBar/Resources/de.lproj/Localizable.strings
Original file line number Diff line number Diff line change
Expand Up @@ -1263,6 +1263,7 @@
"No local cost history yet" = "Noch kein lokaler Kostenverlauf";
"Turn on cost tracking or refresh after using a supported provider." = "Aktivieren Sie die Kostenverfolgung oder aktualisieren Sie nach der Nutzung eines unterstützten Anbieters.";
"Refresh failures" = "Fehlgeschlagene Aktualisierungen";
"Scanning history %d/%d" = "Scanning history %d/%d";
"Native currencies stay separate; Codex account rows exclude Pi session history." = "Originalwährungen bleiben getrennt; Codex-Kontozeilen schließen den Pi-Sitzungsverlauf aus.";
"Spend unavailable" = "Ausgaben nicht verfügbar";
"Model breakdown unavailable" = "Modellaufschlüsselung nicht verfügbar";
Expand Down
1 change: 1 addition & 0 deletions Sources/CodexBar/Resources/en.lproj/Localizable.strings
Original file line number Diff line number Diff line change
Expand Up @@ -1267,6 +1267,7 @@
"No local cost history yet" = "No local cost history yet";
"Turn on cost tracking or refresh after using a supported provider." = "Turn on cost tracking or refresh after using a supported provider.";
"Refresh failures" = "Refresh failures";
"Scanning history %d/%d" = "Scanning history %d/%d";
"Native currencies stay separate; Codex account rows exclude Pi session history." = "Native currencies stay separate; Codex account rows exclude Pi session history.";
"Spend unavailable" = "Spend unavailable";
"Model breakdown unavailable" = "Model breakdown unavailable";
Expand Down
1 change: 1 addition & 0 deletions Sources/CodexBar/Resources/es.lproj/Localizable.strings
Original file line number Diff line number Diff line change
Expand Up @@ -1261,6 +1261,7 @@
"No local cost history yet" = "Aún no hay historial local de costes";
"Turn on cost tracking or refresh after using a supported provider." = "Activa el seguimiento local de costes o actualiza después de usar un proveedor compatible.";
"Refresh failures" = "Actualizaciones fallidas";
"Scanning history %d/%d" = "Scanning history %d/%d";
"Native currencies stay separate; Codex account rows exclude Pi session history." = "Las divisas originales se mantienen separadas; las filas de cuentas de Codex excluyen el historial de sesiones de Pi.";
"Spend unavailable" = "Gasto no disponible";
"Model breakdown unavailable" = "Desglose por modelo no disponible";
Expand Down
1 change: 1 addition & 0 deletions Sources/CodexBar/Resources/fa.lproj/Localizable.strings
Original file line number Diff line number Diff line change
Expand Up @@ -1266,6 +1266,7 @@
"No local cost history yet" = "هنوز تاریخچه هزینه محلی وجود ندارد";
"Turn on cost tracking or refresh after using a supported provider." = "پیگیری هزینه را روشن کنید یا پس از استفاده از یک ارائه‌دهنده پشتیبانی‌شده تازه‌سازی کنید.";
"Refresh failures" = "خطاهای تازه‌سازی";
"Scanning history %d/%d" = "Scanning history %d/%d";
"Native currencies stay separate; Codex account rows exclude Pi session history." = "ارزهای اصلی جدا نگه داشته می‌شوند؛ ردیف‌های حساب Codex تاریخچه نشست‌های Pi را دربر نمی‌گیرند.";
"Spend unavailable" = "هزینه در دسترس نیست";
"Model breakdown unavailable" = "تفکیک مدل در دسترس نیست";
Expand Down
1 change: 1 addition & 0 deletions Sources/CodexBar/Resources/fr.lproj/Localizable.strings
Original file line number Diff line number Diff line change
Expand Up @@ -1262,6 +1262,7 @@
"No local cost history yet" = "Aucun historique local des coûts pour l’instant";
"Turn on cost tracking or refresh after using a supported provider." = "Activez le suivi local des coûts ou actualisez après avoir utilisé un fournisseur pris en charge.";
"Refresh failures" = "Échecs d’actualisation";
"Scanning history %d/%d" = "Scanning history %d/%d";
"Native currencies stay separate; Codex account rows exclude Pi session history." = "Les devises d’origine restent séparées ; les lignes de compte Codex excluent l’historique des sessions Pi.";
"Spend unavailable" = "Dépenses indisponibles";
"Model breakdown unavailable" = "Répartition par modèle indisponible";
Expand Down
1 change: 1 addition & 0 deletions Sources/CodexBar/Resources/gl.lproj/Localizable.strings
Original file line number Diff line number Diff line change
Expand Up @@ -1262,6 +1262,7 @@
"No local cost history yet" = "Aínda non hai historial local de custos";
"Turn on cost tracking or refresh after using a supported provider." = "Activa o seguimento de custos ou actualiza despois de usar un provedor compatible.";
"Refresh failures" = "Actualizacións falladas";
"Scanning history %d/%d" = "Scanning history %d/%d";
"Native currencies stay separate; Codex account rows exclude Pi session history." = "As moedas orixinais mantéñense separadas; as filas das contas de Codex exclúen o historial de sesións de Pi.";
"Spend unavailable" = "Gasto non dispoñible";
"Model breakdown unavailable" = "Desglose por modelo non dispoñible";
Expand Down
1 change: 1 addition & 0 deletions Sources/CodexBar/Resources/id.lproj/Localizable.strings
Original file line number Diff line number Diff line change
Expand Up @@ -1266,6 +1266,7 @@
"No local cost history yet" = "Belum ada riwayat biaya lokal";
"Turn on cost tracking or refresh after using a supported provider." = "Aktifkan pelacakan biaya atau segarkan setelah menggunakan penyedia yang didukung.";
"Refresh failures" = "Kegagalan penyegaran";
"Scanning history %d/%d" = "Scanning history %d/%d";
"Native currencies stay separate; Codex account rows exclude Pi session history." = "Mata uang asli tetap dipisahkan; baris akun Codex tidak menyertakan riwayat sesi Pi.";
"Spend unavailable" = "Data pengeluaran tidak tersedia";
"Model breakdown unavailable" = "Rincian per model tidak tersedia";
Expand Down
1 change: 1 addition & 0 deletions Sources/CodexBar/Resources/it.lproj/Localizable.strings
Original file line number Diff line number Diff line change
Expand Up @@ -1266,6 +1266,7 @@
"No local cost history yet" = "Ancora nessuna cronologia locale dei costi";
"Turn on cost tracking or refresh after using a supported provider." = "Attiva il monitoraggio dei costi o aggiorna dopo aver usato un provider supportato.";
"Refresh failures" = "Aggiornamenti non riusciti";
"Scanning history %d/%d" = "Scansione cronologia %d/%d";
"Native currencies stay separate; Codex account rows exclude Pi session history." = "Le valute originali rimangono separate; le righe degli account Codex escludono la cronologia delle sessioni Pi.";
"Spend unavailable" = "Spesa non disponibile";
"Model breakdown unavailable" = "Ripartizione per modello non disponibile";
Expand Down
1 change: 1 addition & 0 deletions Sources/CodexBar/Resources/ja.lproj/Localizable.strings
Original file line number Diff line number Diff line change
Expand Up @@ -1263,6 +1263,7 @@
"No local cost history yet" = "ローカルのコスト履歴はまだありません";
"Turn on cost tracking or refresh after using a supported provider." = "コスト追跡をオンにするか、対応プロバイダの使用後に更新してください。";
"Refresh failures" = "更新失敗";
"Scanning history %d/%d" = "Scanning history %d/%d";
"Native currencies stay separate; Codex account rows exclude Pi session history." = "各通貨は別々に扱われ、Codex アカウント行には Pi セッション履歴を含めません。";
"Spend unavailable" = "支出を取得できません";
"Model breakdown unavailable" = "モデル別の内訳を取得できません";
Expand Down
1 change: 1 addition & 0 deletions Sources/CodexBar/Resources/ko.lproj/Localizable.strings
Original file line number Diff line number Diff line change
Expand Up @@ -1230,6 +1230,7 @@
"No local cost history yet" = "아직 로컬 비용 내역이 없습니다";
"Turn on cost tracking or refresh after using a supported provider." = "비용 추적을 켜거나 지원되는 공급자를 사용한 후 새로 고치세요.";
"Refresh failures" = "새로 고침 실패";
"Scanning history %d/%d" = "Scanning history %d/%d";
"Native currencies stay separate; Codex account rows exclude Pi session history." = "각 통화는 별도로 유지되며 Codex 계정 행에서는 Pi 세션 기록이 제외됩니다.";
"Spend unavailable" = "지출 정보 없음";
"Model breakdown unavailable" = "모델별 내역을 사용할 수 없습니다";
Expand Down
1 change: 1 addition & 0 deletions Sources/CodexBar/Resources/nl.lproj/Localizable.strings
Original file line number Diff line number Diff line change
Expand Up @@ -1262,6 +1262,7 @@
"No local cost history yet" = "Nog geen lokale kostengeschiedenis";
"Turn on cost tracking or refresh after using a supported provider." = "Schakel kostenregistratie in of vernieuw nadat je een ondersteunde aanbieder hebt gebruikt.";
"Refresh failures" = "Mislukte vernieuwingen";
"Scanning history %d/%d" = "Scanning history %d/%d";
"Native currencies stay separate; Codex account rows exclude Pi session history." = "Oorspronkelijke valuta’s blijven gescheiden; rijen met Codex-accounts sluiten Pi-sessiegeschiedenis uit.";
"Spend unavailable" = "Uitgaven niet beschikbaar";
"Model breakdown unavailable" = "Uitsplitsing per model niet beschikbaar";
Expand Down
1 change: 1 addition & 0 deletions Sources/CodexBar/Resources/pl.lproj/Localizable.strings
Original file line number Diff line number Diff line change
Expand Up @@ -1266,6 +1266,7 @@
"No local cost history yet" = "Brak lokalnej historii kosztów";
"Turn on cost tracking or refresh after using a supported provider." = "Włącz śledzenie kosztów lub odśwież po użyciu obsługiwanego dostawcy.";
"Refresh failures" = "Błędy odświeżania";
"Scanning history %d/%d" = "Scanning history %d/%d";
"Native currencies stay separate; Codex account rows exclude Pi session history." = "Waluty źródłowe pozostają rozdzielone; wiersze kont Codex nie obejmują historii sesji Pi.";
"Spend unavailable" = "Wydatki niedostępne";
"Model breakdown unavailable" = "Podział według modeli jest niedostępny";
Expand Down
1 change: 1 addition & 0 deletions Sources/CodexBar/Resources/pt-BR.lproj/Localizable.strings
Original file line number Diff line number Diff line change
Expand Up @@ -1263,6 +1263,7 @@
"No local cost history yet" = "Ainda não há histórico local de custos";
"Turn on cost tracking or refresh after using a supported provider." = "Ative o acompanhamento de custos ou atualize após usar um provedor compatível.";
"Refresh failures" = "Falhas de atualização";
"Scanning history %d/%d" = "Scanning history %d/%d";
"Native currencies stay separate; Codex account rows exclude Pi session history." = "As moedas originais permanecem separadas; as linhas de contas do Codex excluem o histórico de sessões do Pi.";
"Spend unavailable" = "Gastos indisponíveis";
"Model breakdown unavailable" = "Detalhamento por modelo indisponível";
Expand Down
1 change: 1 addition & 0 deletions Sources/CodexBar/Resources/ru.lproj/Localizable.strings
Original file line number Diff line number Diff line change
Expand Up @@ -1264,6 +1264,7 @@
"No local cost history yet" = "Локальной истории расходов пока нет";
"Turn on cost tracking or refresh after using a supported provider." = "Включите отслеживание расходов или обновите данные после использования поддерживаемого провайдера.";
"Refresh failures" = "Ошибки обновления";
"Scanning history %d/%d" = "Scanning history %d/%d";
"Native currencies stay separate; Codex account rows exclude Pi session history." = "Исходные валюты остаются раздельными; строки учётных записей Codex не включают историю сеансов Pi.";
"Spend unavailable" = "Расходы недоступны";
"Model breakdown unavailable" = "Разбивка по моделям недоступна";
Expand Down
1 change: 1 addition & 0 deletions Sources/CodexBar/Resources/sv.lproj/Localizable.strings
Original file line number Diff line number Diff line change
Expand Up @@ -1261,6 +1261,7 @@
"No local cost history yet" = "Ingen lokal kostnadshistorik än";
"Turn on cost tracking or refresh after using a supported provider." = "Aktivera kostnadsspårning eller uppdatera efter att ha använt en leverantör som stöds.";
"Refresh failures" = "Misslyckade uppdateringar";
"Scanning history %d/%d" = "Scanning history %d/%d";
"Native currencies stay separate; Codex account rows exclude Pi session history." = "Ursprungliga valutor hålls åtskilda; rader för Codex-konton utesluter Pi-sessionshistorik.";
"Spend unavailable" = "Utgifter ej tillgängliga";
"Model breakdown unavailable" = "Modellfördelning ej tillgänglig";
Expand Down
1 change: 1 addition & 0 deletions Sources/CodexBar/Resources/th.lproj/Localizable.strings
Original file line number Diff line number Diff line change
Expand Up @@ -1266,6 +1266,7 @@
"No local cost history yet" = "ยังไม่มีประวัติค่าใช้จ่ายในเครื่อง";
"Turn on cost tracking or refresh after using a supported provider." = "เปิดการติดตามค่าใช้จ่ายหรือรีเฟรชหลังจากใช้ผู้ให้บริการที่รองรับ";
"Refresh failures" = "การรีเฟรชที่ล้มเหลว";
"Scanning history %d/%d" = "Scanning history %d/%d";
"Native currencies stay separate; Codex account rows exclude Pi session history." = "สกุลเงินต้นทางแยกจากกัน แถวบัญชี Codex ไม่รวมประวัติเซสชัน Pi";
"Spend unavailable" = "ไม่มีข้อมูลค่าใช้จ่าย";
"Model breakdown unavailable" = "ไม่มีรายละเอียดแยกตามโมเดล";
Expand Down
1 change: 1 addition & 0 deletions Sources/CodexBar/Resources/tr.lproj/Localizable.strings
Original file line number Diff line number Diff line change
Expand Up @@ -1264,6 +1264,7 @@
"No local cost history yet" = "Henüz yerel maliyet geçmişi yok";
"Turn on cost tracking or refresh after using a supported provider." = "Maliyet takibini açın veya desteklenen bir sağlayıcıyı kullandıktan sonra yenileyin.";
"Refresh failures" = "Yenileme hataları";
"Scanning history %d/%d" = "Scanning history %d/%d";
"Native currencies stay separate; Codex account rows exclude Pi session history." = "Kaynak para birimleri ayrı tutulur; Codex hesap satırlarına Pi oturum geçmişi dahil edilmez.";
"Spend unavailable" = "Harcama verisi kullanılamıyor";
"Model breakdown unavailable" = "Model dökümü kullanılamıyor";
Expand Down
1 change: 1 addition & 0 deletions Sources/CodexBar/Resources/uk.lproj/Localizable.strings
Original file line number Diff line number Diff line change
Expand Up @@ -1262,6 +1262,7 @@
"No local cost history yet" = "Локальної історії витрат ще немає";
"Turn on cost tracking or refresh after using a supported provider." = "Увімкніть відстеження витрат або оновіть дані після використання підтримуваного провайдера.";
"Refresh failures" = "Помилки оновлення";
"Scanning history %d/%d" = "Scanning history %d/%d";
"Native currencies stay separate; Codex account rows exclude Pi session history." = "Вихідні валюти залишаються розділеними; рядки облікових записів Codex не включають історію сеансів Pi.";
"Spend unavailable" = "Витрати недоступні";
"Model breakdown unavailable" = "Розподіл за моделями недоступний";
Expand Down
1 change: 1 addition & 0 deletions Sources/CodexBar/Resources/vi.lproj/Localizable.strings
Original file line number Diff line number Diff line change
Expand Up @@ -1263,6 +1263,7 @@
"No local cost history yet" = "Chưa có lịch sử chi phí cục bộ";
"Turn on cost tracking or refresh after using a supported provider." = "Bật tính năng theo dõi chi phí hoặc làm mới sau khi sử dụng nhà cung cấp được hỗ trợ.";
"Refresh failures" = "Lần làm mới thất bại";
"Scanning history %d/%d" = "Scanning history %d/%d";
"Native currencies stay separate; Codex account rows exclude Pi session history." = "Đơn vị tiền tệ gốc được giữ riêng biệt; các hàng tài khoản Codex không bao gồm lịch sử phiên Pi.";
"Spend unavailable" = "Không có dữ liệu chi tiêu";
"Model breakdown unavailable" = "Phân tích theo mô hình không khả dụng";
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -1238,6 +1238,7 @@
"No local cost history yet" = "暂无本地费用历史";
"Turn on cost tracking or refresh after using a supported provider." = "启用费用跟踪,或在使用受支持的提供商后刷新。";
"Refresh failures" = "刷新失败";
"Scanning history %d/%d" = "正在扫描历史 %d/%d";
"Native currencies stay separate; Codex account rows exclude Pi session history." = "各原始币种保持分开;Codex 帐户行不包含 Pi 会话历史。";
"Spend unavailable" = "支出数据不可用";
"Model breakdown unavailable" = "模型明细不可用";
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -1293,6 +1293,7 @@
"No local cost history yet" = "尚無本機費用歷史";
"Turn on cost tracking or refresh after using a supported provider." = "開啟費用追蹤,或在使用支援的提供者後重新整理。";
"Refresh failures" = "重新整理失敗";
"Scanning history %d/%d" = "正在掃描歷史 %d/%d";
"Native currencies stay separate; Codex account rows exclude Pi session history." = "各原始幣別保持分開;Codex 帳號列不包含 Pi 工作階段歷史。";
"Spend unavailable" = "無法取得支出資料";
"Model breakdown unavailable" = "無法取得模型明細";
Expand Down
2 changes: 1 addition & 1 deletion Sources/CodexBar/SettingsStore+MenuPreferences.swift
Original file line number Diff line number Diff line change
Expand Up @@ -333,7 +333,7 @@ extension SettingsStore {
func isCostUsageEffectivelyEnabled(for provider: UsageProvider) -> Bool {
let isEnabled = self.costUsageEnabled ||
(provider == .codex && self.codexLocalSessionCostLedgerEnabled)
return isEnabled && ProviderDescriptorRegistry.descriptor(for: provider).tokenCost.supportsTokenCost
return isEnabled && ProviderDescriptorRegistry.descriptor(for: provider).tokenCost.supportsDashboardHistory
}

var resetTimeDisplayStyle: ResetTimeDisplayStyle {
Expand Down
Loading
Loading