feat(providers): add Codebuff support#778
Conversation
Add a new CodexBar provider for Codebuff (https://www.codebuff.com), the successor to the Manicode CLI. The provider surfaces live credit balance and the weekly rate-limit window in the menu bar alongside the other providers. Data sources: * POST https://www.codebuff.com/api/v1/usage -> credit usage / quota / remaining balance / next reset / auto-topup state. * GET https://www.codebuff.com/api/user/subscription -> subscription tier + weekly rate limit + billing period end. Auth token resolution mirrors the Kilo pattern: 1. CODEBUFF_API_KEY env var. 2. API key configured in Settings -> Providers -> Codebuff. 3. ~/.config/manicode/credentials.json (authToken field) written by the official `codebuff login` CLI. New core files under Sources/CodexBarCore/Providers/Codebuff/: CodebuffSettingsReader, CodebuffProviderDescriptor, CodebuffUsageFetcher, CodebuffUsageSnapshot, CodebuffUsageError. App-side files under Sources/CodexBar/Providers/Codebuff/: CodebuffProviderImplementation, CodebuffSettingsStore. Lime-green SVG icon added to Resources. Registers .codebuff in UsageProvider + IconStyle + the descriptor / implementation registries, the token resolver, config env propagation, and all exhaustive switches across CostUsageScanner, UsageStore, CodexBarCLI settings snapshot, and the widget views. Unit tests added: * CodebuffSettingsReaderTests (11 cases) — env, quotes, auth-file parsing, descriptor shape. * CodebuffUsageFetcherTests (16 cases) — URL building, status code mapping, usage/subscription parsers, snapshot -> UsageSnapshot mapping, missing-creds fast-path. * ProviderTokenResolverTests — 3 new cases for env vs auth-file precedence and malformed credentials handling. Verified: `swift build` and targeted `swift test` runs green (27 new Codebuff tests + 12 resolver tests + the provider registry coverage subset). Co-authored-by: factory-droid[bot] <138933559+factory-droid[bot]@users.noreply.github.com>
ed25e20 to
5928622
Compare
There was a problem hiding this comment.
💡 Codex Review
Here are some automated review suggestions for this pull request.
Reviewed commit: ed25e20682
ℹ️ About Codex in GitHub
Your team has set up Codex to review pull requests in this repo. Reviews are triggered when you
- Open a pull request for review
- Mark a draft as ready
- Comment "@codex review".
If Codex has suggestions, it will comment; otherwise it will react with 👍.
Codex can also answer questions or update the PR. Try commenting "@codex address that feedback".
| if self.creditsRemaining != nil || self.creditsUsed != nil { | ||
| // Degenerate case: show exhausted state so users notice missing configuration. | ||
| return RateWindow( | ||
| usedPercent: 0, |
There was a problem hiding this comment.
Mark fallback credit window as exhausted
When the API returns partial credit data (creditsUsed/creditsRemaining) but no total quota, this fallback branch is intended to show an exhausted state, but usedPercent is set to 0, which renders as fully healthy usage instead of a warning state. In that scenario users will see a misleading green/low-usage primary window even though the code is explicitly treating the response as degenerate; this should use an exhausted/unknown representation (e.g., 100%) so missing quota data is visible.
Useful? React with 👍 / 👎.
When the Codebuff API responds with partial credit data (only creditsUsed or only creditsRemaining and no total quota), the fallback branch previously set usedPercent=0, which rendered as a fully healthy bar despite the code treating the payload as degenerate. Flip it to 100% exhausted so missing quota data stays visible to the user — this matches Kilo's behaviour for zero/unknown totals. Address review feedback on PR steipete#778. Add regression tests for both the used-only and remaining-only fallback branches plus an empty-snapshot case. Co-authored-by: factory-droid[bot] <138933559+factory-droid[bot]@users.noreply.github.com>
Summary
Adds Codebuff (https://www.codebuff.com) as a first-class provider in CodexBar. The menu bar now shows live credit balance and the weekly rate-limit window alongside the other 26 providers.
Why
Codebuff is an active open-source CLI agent (successor to
manicode) with a metered credit model. Users on my team wanted it to show up next to their Codex / Claude / Kilo quotas without switching to the browser.Data sources
Codebuff exposes two stable Bearer-token endpoints used by their own dashboard + CLI:
POSThttps://www.codebuff.com/api/v1/usageusage,quota,remainingBalance,next_quota_reset,autoTopupEnabledGEThttps://www.codebuff.com/api/user/subscriptionsubscription{ status, tier, billingPeriodEnd },rateLimit{ weeklyUsed, weeklyLimit }, emailBoth are called in parallel; subscription failures degrade gracefully (the primary credits window still renders).
Authentication
Resolved in this order (mirrors the Kilo pattern):
CODEBUFF_API_KEYenvironment variable.~/.codexbar/config.jsonlike other providers).~/.config/manicode/credentials.json— the file the officialcodebuffCLI writes aftercodebuff login. CodexBar reads theauthTokenfield and uses it as a Bearer token.If none is available, the provider surfaces
CodebuffUsageError.missingCredentialswith guidance. Nothing is written outside the existing CodexBar config path.UX
usage / quota) with the next-reset date, if provided.weeklyUsed / weeklyLimit) on a 7-day window.#44FF00) CodexBar icon added to match Codebuff's own branding.Files
New core (Sources/CodexBarCore/Providers/Codebuff/)
CodebuffSettingsReader.swift— env var +credentials.jsonparser.CodebuffProviderDescriptor.swift— provider registration +CodebuffAPIFetchStrategy.CodebuffUsageFetcher.swift— asyncfetchUsage, URL builders, status-code mapping, JSON parsers.CodebuffUsageSnapshot.swift— models the unified rate windows + identity mapping.CodebuffUsageError.swift— auth / endpoint / service / network / parse variants.New app (Sources/CodexBar/Providers/Codebuff/)
CodebuffProviderImplementation.swift— settings pane (secure API-key field + dashboard link).CodebuffSettingsStore.swift—SettingsStore.codebuffAPITokenpersistence.New asset
Sources/CodexBar/Resources/ProviderIcon-codebuff.svg.Edits
Providers.swift— addcase codebufftoUsageProviderandIconStyle.ProviderDescriptor.swift/ProviderImplementationRegistry.swift— register the new provider.ProviderTokenResolver.swift— newcodebuffResolution()(env → auth file).ProviderConfigEnvironment.swift— propagateCODEBUFF_API_KEYfrom config → fetch env.CostUsageScanner.swift,UsageStore.swift(debug log),TokenAccountCLI.swift, widget provider / views — extend exhaustive switches.README.md,docs/codebuff.md— describe the new provider.Tests
27 new swift-testing cases, plus 3 new resolver cases:
Tests/CodexBarTests/CodebuffSettingsReaderTests.swift(11) — API URL default + override, env-var trimming / quote stripping, credentials-file parsing (valid / malformed / missing), descriptor shape.Tests/CodexBarTests/CodebuffUsageFetcherTests.swift(16) — URL building, 200/401/403/404/5xx status mapping, usage & subscription parsers (numeric + string-encoded fields, absent fields, malformed JSON), snapshot → unifiedUsageSnapshot, missing-credentials fast path.Tests/CodexBarTests/ProviderTokenResolverTests.swift— env vs auth-file precedence, malformed credentials file.Verified locally (macOS 15, Swift 6.2):
Pre-existing subprocess-runner stress tests emit a "signal code 5" warning on some runs (unrelated to this change; reproduced on a stashed baseline).
Notes for the reviewer
swiftformat/swiftlintinstalled on this machine, so the new files follow the observed style manually (4-space indent, explicitself,MARKorganization). Happy to push a follow-up commit after running them if you prefer.CODEBUFF_API_URLenv override is supported for staging, following the same pattern as OpenRouter.Happy to adjust scope, rename, or split further if you'd rather land this in steps.