Skip to content

feat(providers): add Codebuff support#778

Open
anandghegde wants to merge 2 commits intosteipete:mainfrom
anandghegde:feat/codebuff-provider
Open

feat(providers): add Codebuff support#778
anandghegde wants to merge 2 commits intosteipete:mainfrom
anandghegde:feat/codebuff-provider

Conversation

@anandghegde
Copy link
Copy Markdown

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:

Method Endpoint Returns
POST https://www.codebuff.com/api/v1/usage usage, quota, remainingBalance, next_quota_reset, autoTopupEnabled
GET https://www.codebuff.com/api/user/subscription subscription{ status, tier, billingPeriodEnd }, rateLimit{ weeklyUsed, weeklyLimit }, email

Both are called in parallel; subscription failures degrade gracefully (the primary credits window still renders).

Authentication

Resolved in this order (mirrors the Kilo pattern):

  1. CODEBUFF_API_KEY environment variable.
  2. API key configured in Settings → Providers → Codebuff (stored in ~/.codexbar/config.json like other providers).
  3. ~/.config/manicode/credentials.json — the file the official codebuff CLI writes after codebuff login. CodexBar reads the authToken field and uses it as a Bearer token.

If none is available, the provider surfaces CodebuffUsageError.missingCredentials with guidance. Nothing is written outside the existing CodexBar config path.

UX

  • Primary row: credit balance (usage / quota) with the next-reset date, if provided.
  • Secondary row: weekly rate limit (weeklyUsed / weeklyLimit) on a 7-day window.
  • Account panel shows the tier (e.g. "Pro"), remaining balance, and whether auto top-up is enabled.
  • Lime-green (#44FF00) CodexBar icon added to match Codebuff's own branding.

Files

New core (Sources/CodexBarCore/Providers/Codebuff/)

  • CodebuffSettingsReader.swift — env var + credentials.json parser.
  • CodebuffProviderDescriptor.swift — provider registration + CodebuffAPIFetchStrategy.
  • CodebuffUsageFetcher.swift — async fetchUsage, 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.swiftSettingsStore.codebuffAPIToken persistence.

New asset

  • Sources/CodexBar/Resources/ProviderIcon-codebuff.svg.

Edits

  • Providers.swift — add case codebuff to UsageProvider and IconStyle.
  • ProviderDescriptor.swift / ProviderImplementationRegistry.swift — register the new provider.
  • ProviderTokenResolver.swift — new codebuffResolution() (env → auth file).
  • ProviderConfigEnvironment.swift — propagate CODEBUFF_API_KEY from 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 → unified UsageSnapshot, missing-credentials fast path.
  • Tests/CodexBarTests/ProviderTokenResolverTests.swift — env vs auth-file precedence, malformed credentials file.

Verified locally (macOS 15, Swift 6.2):

swift build                                           # ok
swift test --filter Codebuff                          # 27 / 27 ✔
swift test --filter ProviderTokenResolver             # 12 / 12 ✔
swift test --filter ProviderRegistry|ProvidersPane|ConfigValidation  # ok
swift test                                            # all 1289 + 15 xctests pass

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

  • I don't have swiftformat / swiftlint installed on this machine, so the new files follow the observed style manually (4-space indent, explicit self, MARK organization). Happy to push a follow-up commit after running them if you prefer.
  • Icon is a simple two-path lime "hex" mark — feel free to swap for a higher-fidelity design; the descriptor points at it by name so any drop-in replacement works.
  • CODEBUFF_API_URL env 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.

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>
@anandghegde anandghegde force-pushed the feat/codebuff-provider branch from ed25e20 to 5928622 Compare April 21, 2026 12:34
Copy link
Copy Markdown

@chatgpt-codex-connector chatgpt-codex-connector Bot left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

💡 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,
Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

P2 Badge 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>
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant