Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
28 commits
Select commit Hold shift + click to select a range
9854b21
Improve Kiro credits UX
solnikhil May 13, 2026
cd2c2c4
Add provider changelog links
ThiagoCAltoe May 13, 2026
0919805
Fix changelog menu test
ThiagoCAltoe May 13, 2026
81a420a
feat: gate provider changelog links behind setting
steipete May 13, 2026
f7c83fe
Address Kiro review feedback
solnikhil May 13, 2026
766cb36
Polish Kiro credit detail styling
solnikhil May 13, 2026
cd2abfd
fix: repair stale managed Codex account removal
steipete May 13, 2026
34d9b18
fix: handle Claude enterprise web accounts (#941)
clintandrewhall May 14, 2026
100e32f
docs: update changelog for Claude enterprise fix
steipete May 14, 2026
36db0c6
fix: handle quota and usage edge cases
steipete May 14, 2026
ac5de84
Rebalance Kimi provider icon (#912)
giuseppebisemi May 14, 2026
6423275
Add zh-Hans translations for Claude peak hour labels (#921)
whtis May 14, 2026
e48a4bc
docs: update changelog for recent contributor fixes
steipete May 14, 2026
e6ea0ae
Add Tahoe menu bar visibility guidance
pdurlej May 14, 2026
4abfbb6
Coalesce historical pace reset buckets
zhulijin1991 May 14, 2026
2f6a31c
Add Codex priority cost pricing
iam-brain May 14, 2026
9d7a24e
fix: parse Claude web spend limits
steipete May 14, 2026
24d67e5
fix: refresh Gemini credentials without access token
steipete May 14, 2026
8c3e254
refactor: split Claude web extra usage helpers
steipete May 14, 2026
aebe1c9
fix: defer account switcher menu rebuilds
steipete May 14, 2026
6e68613
docs: fix changelog spacing
steipete May 14, 2026
32fd0ec
fix: handle unavailable Codex limits gracefully
steipete May 14, 2026
0776680
docs: update unreleased changelog
steipete May 14, 2026
837cdb9
fix: repair update and account menu paths
steipete May 14, 2026
eba4b6f
fix: handle account-scoped usage and menu login bugs
steipete May 14, 2026
a15df5c
Add Antigravity account switching (#937)
hhh2210 May 14, 2026
9902384
docs: add Antigravity account switching changelog
steipete May 14, 2026
5aa8113
Merge main into Kiro credits PR
steipete May 14, 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
32 changes: 29 additions & 3 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -3,22 +3,48 @@
## 0.26 — Unreleased

### Added
- Display: add a setting to hide quota-warning tick marks on usage bars while keeping quota warning notifications active (#918, fixes #916). Thanks @ThiagoCAltoe!
- Antigravity: add Google OAuth token-account switching with selected-account refresh persistence (#937, fixes #936). Thanks @hhh2210!
- Moonshot / Kimi API: add API-key balance tracking, CLI support, docs, and menu bar balance copy (#899). Thanks @giuseppebisemi!
- Menu: add an opt-in setting for provider changelog links, starting with Codex, Claude Code, and Gemini CLI (#929, fixes #660). Thanks @ThiagoCAltoe!
- Display: add a setting to hide quota-warning tick marks on usage bars while keeping quota warning notifications active (#918, fixes #916). Thanks @ThiagoCAltoe!
- Codex: add tiered long-context and Fast/Priority pricing to local cost history using local app-server priority traces (#917). Thanks @iam-brain!
- Localization: add Brazilian Portuguese translations (#902). Thanks @ThiagoCAltoe!
- Localization: add Simplified Chinese translations for Claude peak-hour labels (#921). Thanks @whtis!

### Fixed
- Settings: apply the selected app language from packaged SwiftPM resources instead of falling back to English when the `.lproj` directory casing differs (#908).
- Codex: scope local cost history to the selected managed account's `CODEX_HOME` and label cost cards as local-log estimates (#910).
- Cursor: open Add Account in the user's browser and import the resulting browser session instead of trapping login in an embedded web view (#922).
- Menu: disable implicit provider-switcher layer animations and reuse the deferred rebuild path so open menus stay stable under pointer movement (#950).
- Updates: make the restart/apply-update menu action use Sparkle's prepared install callback on the first click (#947). Thanks @velvet-shark!
- Multi-account menus: keep stacked token-account cards capped to current accounts and ignore stale snapshots from removed accounts (#949).
- Droid: accept pasted Factory `Authorization: Bearer` headers and bearer tokens for manual sessions when cookies alone are insufficient (#914).
- Codex: show authenticated plan/account rows as "Limits not available" instead of a red no-rate-limit error when Codex reports profile data but no rate-limit windows yet.
- Overview: hide provider rows that only contain an error, and avoid showing a one-item Codex System Account submenu.
- Claude: handle Enterprise and organization spend-limit usage across OAuth/web accounts, including null session quota windows, inline spend-limit usage, `extra_usage`-only responses, and token-account Org ID support (#925, #941, fixes #940). Thanks @clintandrewhall!
- Menu: defer account-switcher menu rebuilds so switching Codex or token accounts does not send the open menu into a flicker loop (#946, fixes #944). Thanks @kubahasek!
- Menu: avoid rebuilding visible menus during background open-menu refreshes so hover submenus stay responsive (#923, fixes #909). Thanks @AmrMohamad!
- Menu bar: detect when macOS Tahoe hides CodexBar behind the new Allow in Menu Bar setting and show recovery guidance (#945, fixes #890). Thanks @pdurlej!
- CLI: route Claude token-account `--source cli` reads through the selected OAuth/session credential so `--all-accounts` no longer relabels ambient CLI usage (#403).
- Codex: route menu account refreshes through the resolved live-vs-managed account source so matched accounts keep using the stable `CODEX_HOME` (#932, fixes #931). Thanks @ThiagoCAltoe!
- Gemini: refresh OAuth credentials when the CLI has a refresh token but no cached access token instead of reporting "not logged in" after authentication (#915).
- Gemini: label OAuth-backed API fetches as `oauth-api` instead of plain `api` (#930). Thanks @ThiagoCAltoe!
- Codex: keep session and weekly quota-warning marker thresholds independent so usage bars do not duplicate marker lines (#938, fixes #927). Thanks @iam-brain!
- Codex: coalesce historical pace reset timestamps into 5-minute buckets so dashboard and live reset jitter do not duplicate weekly history windows (#901). Thanks @zhulijin1991!
- Menu: middle-truncate long account emails in Codex account controls and keep the Codex account switcher visible during merged-menu refreshes with transient account snapshots.
- Settings: apply the selected app language from packaged SwiftPM resources instead of falling back to English when the `.lproj` directory casing differs (#908).
- Settings: let stale managed Codex account records be removed even when their stored home path is outside CodexBar's managed-home directory, and keep CLI known-owner tests from writing fixtures into the live app store.
- ChatGPT credits: restrict purchase links to real HTTPS `chatgpt.com` settings/usage/billing/credits paths and drop query/fragment data (#903). Thanks @ThiagoCAltoe!
- z.ai: show the MCP quota bucket as monthly instead of a misleading 1-minute window (#904). Thanks @ThiagoCAltoe!
- Menu: middle-truncate long account emails in Codex account controls and keep the Codex account switcher visible during merged-menu refreshes with transient account snapshots.
- Kimi: rebalance provider icon alignment within its viewBox (#912). Thanks @giuseppebisemi!

## 0.25.1 — 2026-05-11

### Fixed
- Settings: avoid packaged-app crashes from SwiftPM localization bundle lookup when opening Settings or About (#896, fixes #891). Thanks @lederniermagicien!
- CLI: include a VERSION file in standalone release archives so `--version` reports the release tag outside the app bundle (#898). Thanks @ThiagoCAltoe!
- Pi: rebuild stale session cost caches after cache-version migrations so refreshed cost history reflects current scanner data.
- Keychain cache: reduce repeated development prompt churn by trusting the bundled helper when writing CodexBar-owned cache items (#888).

## 0.25 — 2026-05-10

### Highlights
Expand Down
62 changes: 59 additions & 3 deletions Sources/CodexBar/CodexbarApp.swift
Original file line number Diff line number Diff line change
Expand Up @@ -125,6 +125,7 @@ protocol UpdaterProviding: AnyObject {
var unavailableReason: String? { get }
var updateStatus: UpdateStatus { get }
func checkForUpdates(_ sender: Any?)
func installUpdate()
}

/// No-op updater used for debug builds and non-bundled runs to suppress Sparkle dialogs.
Expand All @@ -140,6 +141,7 @@ final class DisabledUpdaterController: UpdaterProviding {
}

func checkForUpdates(_ sender: Any?) {}
func installUpdate() {}
}

@MainActor
Expand All @@ -158,12 +160,25 @@ import Sparkle

@MainActor
final class SparkleUpdaterController: NSObject, UpdaterProviding, SPUUpdaterDelegate {
private final class ImmediateInstallHandler: @unchecked Sendable {
private let handler: () -> Void

init(_ handler: @escaping () -> Void) {
self.handler = handler
}

func install() {
self.handler()
}
}

private lazy var controller = SPUStandardUpdaterController(
startingUpdater: false,
updaterDelegate: self,
userDriverDelegate: nil)
let updateStatus = UpdateStatus()
let unavailableReason: String? = nil
private var immediateInstallHandler: ImmediateInstallHandler?

init(savedAutoUpdate: Bool) {
super.init()
Expand Down Expand Up @@ -191,20 +206,59 @@ final class SparkleUpdaterController: NSObject, UpdaterProviding, SPUUpdaterDele
self.controller.checkForUpdates(sender)
}

nonisolated func updater(_ updater: SPUUpdater, didDownloadUpdate item: SUAppcastItem) {
Task { @MainActor in
self.updateStatus.isUpdateReady = true
func installUpdate() {
guard let immediateInstallHandler else {
self.controller.checkForUpdates(nil)
return
}

immediateInstallHandler.install()
}

nonisolated func updater(_ updater: SPUUpdater, didDownloadUpdate item: SUAppcastItem) {
_ = updater
_ = item
}

nonisolated func updater(_ updater: SPUUpdater, failedToDownloadUpdate item: SUAppcastItem, error: Error) {
_ = updater
_ = item
_ = error
Task { @MainActor in
self.immediateInstallHandler = nil
self.updateStatus.isUpdateReady = false
}
}

nonisolated func userDidCancelDownload(_ updater: SPUUpdater) {
_ = updater
Task { @MainActor in
self.immediateInstallHandler = nil
self.updateStatus.isUpdateReady = false
}
}

nonisolated func updater(
_ updater: SPUUpdater,
willInstallUpdateOnQuit item: SUAppcastItem,
immediateInstallationBlock immediateInstallHandler: @escaping () -> Void)
-> Bool
{
_ = updater
_ = item
let installHandler = ImmediateInstallHandler(immediateInstallHandler)
Task { @MainActor in
self.immediateInstallHandler = installHandler
self.updateStatus.isUpdateReady = true
}
return true
}

nonisolated func updater(_ updater: SPUUpdater, didAbortWithError error: Error) {
_ = updater
_ = error
Task { @MainActor in
self.immediateInstallHandler = nil
self.updateStatus.isUpdateReady = false
}
}
Expand All @@ -219,10 +273,12 @@ final class SparkleUpdaterController: NSObject, UpdaterProviding, SPUUpdaterDele
Task { @MainActor in
switch choice {
case .install, .skip:
self.immediateInstallHandler = nil
self.updateStatus.isUpdateReady = false
case .dismiss:
self.updateStatus.isUpdateReady = downloaded
@unknown default:
self.immediateInstallHandler = nil
self.updateStatus.isUpdateReady = false
}
}
Expand Down
Loading