Add Atlassian Rovo Dev provider#676
Conversation
Adds a new `.rovodev` provider that tracks Atlassian Rovo Dev monthly
credit usage via a silent Web-API based background fetcher — no CLI
dependency, same pattern as the Ollama extension.
## What's included
**New provider files**
- `RovoDevUsageSnapshot` — data model: `currentUsage`, `creditCap`,
`nextRefresh`, `effectiveEntitlement`; converts to `UsageSnapshot`
with `usedPercent = currentUsage / creditCap * 100`
- `RovoDevACLIConfig` — reads `~/.config/acli/global_auth_config.yaml`
at runtime to resolve the active Atlassian site and cloud ID
- `RovoDevUsageFetcher` — POSTs to
`https://{site}/gateway/api/rovodev/v3/credits/entitlements/entitlement-allowance`
authenticated via browser cookies imported with `SweetCookieKit`
- `RovoDevProviderDescriptor` — metadata, fetch strategy, status link
points to the Rovo Dev usage page (not the generic status page)
- `RovoDevSettingsStore` — cookie source (auto/manual) and manual
cookie header settings
- `RovoDevProviderImplementation` — settings UI, cookie picker,
"Open Rovo Dev Usage" link action
- `ProviderIcon-rovodev.svg` — Atlassian-branded diamond icon
**Shared wiring**
- `Providers.swift` — `.rovodev` added to `UsageProvider` and `IconStyle`
- `ProviderSettingsSnapshot` — `RovoDevProviderSettings` struct + full
builder chain
- `ProviderDescriptor` — descriptor registered
- `ProviderImplementationRegistry` — implementation registered
- `LogCategories` — `rovodev` log category
- `CostUsageScanner` — exhaustive switch updated
- `TokenAccountCLI` — `.rovodev` case + snapshot wiring
- `UsageStore` — `.rovodev` debug probe
- `CodexBarWidgetProvider` / `CodexBarWidgetViews` — widget stubs
**Build fix**
- `MenuHighlightStyle.swift` — manually expanded `@Entry` macro so the
project builds with `swift build` CLI (SwiftUIMacros plugin is only
available inside the full Xcode toolchain)
## Validation
- `./Scripts/compile_and_run.sh`
- Verified live: app shows "0% used · ROVO_DEV_STANDARD_TRIAL · Resets
May 7, 2026" matching https://outreach-io.atlassian.net/rovodev/your-usage
There was a problem hiding this comment.
💡 Codex Review
Here are some automated review suggestions for this pull request.
Reviewed commit: 44e27245b4
ℹ️ About Codex in GitHub
Codex has been enabled to automatically 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 👍.
When you sign up for Codex through ChatGPT, Codex can also answer questions or update the PR, like "@codex address that feedback".
| matching: query, in: browser, logger: log) | ||
| for source in sources where !source.records.isEmpty { | ||
| let cookies = BrowserCookieClient.makeHTTPCookies(source.records, origin: query.origin) | ||
| allCookies.append(contentsOf: cookies) |
There was a problem hiding this comment.
Select one browser cookie source instead of concatenating all
importSession appends every cookie from every detected browser/profile into a single Cookie header, which can mix different Atlassian sessions and duplicate cookie names. In environments where users are signed into different Atlassian accounts across browsers, the request can authenticate as the wrong account or fail intermittently because conflicting cookie values are sent together. Prefer selecting one validated session source (as other importers do) rather than aggregating all cookies.
Useful? React with 👍 / 👎.
| site = Self.value(after: "site:", in: trimmed) | ||
| } else if trimmed.hasPrefix("cloud_id:") { | ||
| cloudID = Self.value(after: "cloud_id:", in: trimmed) | ||
| } | ||
| if site != nil, cloudID != nil { break } |
There was a problem hiding this comment.
Parse site/cloud_id from the same YAML profile block
This parser takes the first site: and first cloud_id: seen anywhere in the file and stops, without enforcing that both values came from the same YAML object. If global_auth_config.yaml contains multiple profiles, it can pair a site from one profile with a cloud ID from another, causing requests to hit the wrong tenant and consistently fail. The parser needs to respect YAML structure when extracting the active profile.
Useful? React with 👍 / 👎.
Summary
.rovodevprovider tracking Atlassian Rovo Dev monthly credit usage via a silent Web-API background fetcher (no CLI dependency, same pattern as Ollama)~/.config/acli/global_auth_config.yaml— zero manual config needed for ACLI usersSweetCookieKit(Chrome/Safari/Firefox); manual cookie paste also supportedMenuHighlightStyle.swift@Entrymacro so the project builds withswift buildCLI (SwiftUIMacros plugin requires the full Xcode toolchain)API
New files
CodexBarCore/Providers/RovoDev/RovoDevUsageSnapshot.swiftUsageSnapshotCodexBarCore/Providers/RovoDev/RovoDevUsageFetcher.swiftCodexBarCore/Providers/RovoDev/RovoDevProviderDescriptor.swiftRovoDevWebFetchStrategyCodexBar/Providers/RovoDev/RovoDevSettingsStore.swiftCodexBar/Providers/RovoDev/RovoDevProviderImplementation.swiftCodexBar/Resources/ProviderIcon-rovodev.svgShared wiring
Providers.swift·ProviderSettingsSnapshot·ProviderDescriptor·ProviderImplementationRegistry·LogCategories·CostUsageScanner·TokenAccountCLI·UsageStore·CodexBarWidgetProvider·CodexBarWidgetViewsValidation
./Scripts/compile_and_run.sh— clean build and launch ✅