Skip to content
Closed
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
2 changes: 1 addition & 1 deletion README.md
Original file line number Diff line number Diff line change
Expand Up @@ -10,7 +10,7 @@
[![License: MIT](https://img.shields.io/badge/license-MIT-6e5aff?style=flat-square)](LICENSE)
[![Site](https://img.shields.io/badge/site-codexbar.app-16d3b4?style=flat-square)](https://codexbar.app)

<a href="https://codexbar.app"><img src="docs/social.png?v=8f9e451056014143" alt="CodexBar — every AI coding limit in your menu bar. 106 providers." width="100%" /></a>
<a href="https://codexbar.app"><img src="docs/social.png?v=8f9e451056014143" alt="CodexBar — every AI coding limit in your menu bar. 107 providers." width="100%" /></a>

Tiny macOS 14+ menu bar app that keeps **AI coding-provider limits visible** and shows when each window resets. See the [supported providers](#providers) below. One status item per provider, or Merge Icons mode with a provider switcher. No Dock icon, minimal UI, dynamic bar icons.

Expand Down
5 changes: 4 additions & 1 deletion Sources/CodexBar/Config/ProviderConfig+FetchIdentity.swift
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,10 @@ extension ProviderConfig {
var fetchIdentityConfig: Self {
var copy = self
copy.accentColor = nil
copy.hiddenUsageItemIDs = nil
// Provider-specific by design: OMP usage aggregation dynamically reflects active visible items.
if self.id != ProviderInstanceID.omp {
copy.hiddenUsageItemIDs = nil
}
copy.modelRateLimits = nil
if let data = copy.tokenAccounts {
copy.tokenAccounts = ProviderTokenAccountData(
Expand Down
4 changes: 3 additions & 1 deletion Sources/CodexBar/ProviderUsageItemVisibility.swift
Original file line number Diff line number Diff line change
Expand Up @@ -284,7 +284,9 @@ extension SettingsStore {
for provider: UsageProvider)
{
let rawIDs = hiddenItemIDs.map(\.rawValue).sorted()
self.updateProviderConfig(provider: provider, affectsBackgroundWork: false) { entry in
// Provider-specific by design: OMP usage aggregation dynamically reflects active visible items.
let affectsBackground = provider == .omp
self.updateProviderConfig(provider: provider, affectsBackgroundWork: affectsBackground) { entry in
entry.hiddenUsageItemIDs = rawIDs
}
}
Expand Down
51 changes: 51 additions & 0 deletions Sources/CodexBar/Providers/OMP/OMPProviderImplementation.swift
Original file line number Diff line number Diff line change
@@ -0,0 +1,51 @@
import CodexBarCore
import Foundation
import SwiftUI

struct OMPProviderImplementation: ProviderImplementation {
let id: UsageProvider = .omp

@MainActor
func settingsSnapshot(context: ProviderSettingsSnapshotContext) -> ProviderSettingsSnapshotContribution? {
.omp(context.settings.ompSettingsSnapshot())
}

@MainActor
func settingsPickers(context: ProviderSettingsContext) -> [ProviderSettingsPickerDescriptor] {
[
ProviderSettingsPickerDescriptor(
id: "omp-subprovider",
title: "Subprovider",
subtitle: "Select which provider limits to display from OMP, or Combined for all aggregated limits.",
binding: context.binding(\.ompSubprovider),
options: [
ProviderSettingsPickerOption(id: "all", title: "Combined (All Limits)"),
ProviderSettingsPickerOption(id: "google-antigravity", title: "Google Antigravity (agy)"),
ProviderSettingsPickerOption(id: "openai-codex", title: "OpenAI Codex"),
ProviderSettingsPickerOption(id: "anthropic", title: "Anthropic Claude"),
ProviderSettingsPickerOption(id: "github-copilot", title: "GitHub Copilot"),
ProviderSettingsPickerOption(id: "xai-oauth", title: "xAI Grok"),
ProviderSettingsPickerOption(id: "custom", title: "Custom Subprovider…"),
],
isVisible: nil,
onChange: { _ in
await context.store.refreshProvider(.omp)
}),
]
}

@MainActor
func settingsFields(context: ProviderSettingsContext) -> [ProviderSettingsFieldDescriptor] {
[
ProviderSettingsFieldDescriptor(
id: "omp-custom-subprovider",
title: "Custom Subprovider ID",
subtitle: "Specify a custom subprovider ID (e.g. for new providers added to OMP).",
kind: .plain,
placeholder: "e.g. google-antigravity",
binding: context.binding(\.ompCustomSubprovider),
actions: [],
isVisible: { context.settings.ompSubprovider == "custom" }),
]
}
}
26 changes: 26 additions & 0 deletions Sources/CodexBar/Providers/OMP/OMPSettingsStore.swift
Original file line number Diff line number Diff line change
@@ -0,0 +1,26 @@
import CodexBarCore
import Foundation

extension SettingsStore {
public var ompSubprovider: String {
get { self.configSnapshot.providerConfig(for: .omp)?.ompSubprovider ?? "all" }
set {
self.updateProviderConfig(provider: .omp) { $0.ompSubprovider = newValue }
}
}

public var ompCustomSubprovider: String {
get { self.configSnapshot.providerConfig(for: .omp)?.ompCustomSubprovider ?? "" }
set {
self.updateProviderConfig(provider: .omp) { $0.ompCustomSubprovider = newValue }
}
}

public func ompSettingsSnapshot() -> OMPProviderSettings {
let hidden = self.configSnapshot.providerConfig(for: .omp)?.hiddenUsageItemIDs ?? []
Comment thread
renan-brasilio marked this conversation as resolved.
return OMPProviderSettings(
subprovider: self.ompSubprovider,
customSubprovider: self.ompCustomSubprovider,
hiddenUsageItemIDs: hidden)
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -111,5 +111,6 @@ enum ProviderImplementationManifest {
PluginCookieProviderImplementation(spec: ParallelProviderDescriptor.spec),
PluginCookieProviderImplementation(spec: ClaudePlatformProviderDescriptor.spec),
PluginAPIKeyProviderImplementation(spec: MunitoProviderDescriptor.spec),
OMPProviderImplementation(),
]
}
4 changes: 4 additions & 0 deletions Sources/CodexBar/Resources/ProviderIcon-omp.svg
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Loading