Commit Graph

5 Commits

Author SHA1 Message Date
Jason d164191bd1 feat: display subscription quota for Codex OAuth provider cards
Codex OAuth (ChatGPT Plus/Pro) providers previously fell through to the
default UsageFooter branch and showed no quota at all, while Copilot and
official Codex providers already had a wham/usage-backed quota footer.

This wires up the same five-hour / seven-day tier badges for codex_oauth
provider cards by reusing the existing query_codex_quota function and
SubscriptionQuotaFooter rendering, parameterized to keep both the CLI
credential path ("codex") and the cc-switch managed OAuth path
("codex_oauth") working from a single source of truth.

- Parameterize services::subscription::query_codex_quota with tool_label
  and expired_message; promote SubscriptionQuota constructors to
  pub(crate). The CLI path keeps its existing "codex" label and the
  "re-login with Codex CLI" message; the new path passes "codex_oauth"
  and a cc-switch-specific re-login hint.
- Add a new get_codex_oauth_quota Tauri command in commands/codex_oauth.rs
  that resolves the ChatGPT account (explicit binding > default account
  > not_found), pulls a valid access_token from CodexOAuthManager
  (auto-refresh handled), and delegates to query_codex_quota.
- Extract SubscriptionQuotaFooter's render body into a pure
  SubscriptionQuotaView component (props: quota / loading / refetch /
  appIdForExpiredHint / inline). The existing SubscriptionQuotaFooter
  becomes a thin wrapper with identical props and behavior, so
  CopilotQuotaFooter and the official Claude/Codex/Gemini paths are
  untouched. This avoids duplicating ~280 lines of five-state rendering.
- Add CodexOauthQuotaFooter, a 38-line wrapper that calls the new
  useCodexOauthQuota hook and forwards to SubscriptionQuotaView.
- ProviderCard inserts an isCodexOauth branch between isCopilot and
  isOfficial, keyed off PROVIDER_TYPES.CODEX_OAUTH (newly added to
  config/constants.ts to centralize the previously scattered string).
- Frontend hook caches per (codex_oauth, accountId) so multiple cards
  bound to the same ChatGPT account share one fetch via react-query
  dedup; cards bound to different accounts get independent fetches.
- No new i18n keys: existing subscription.fiveHour / sevenDay / expired /
  refresh / queryFailed / expiredHint are reused.
2026-04-09 16:49:13 +08:00
Jason 602c5717b2 fix: gate parse_gemini_keychain_json with cfg(target_os = "macos")
The function is only called from read_gemini_credentials_from_keychain
which is already macOS-only. Without the gate, non-macOS CI fails with
dead-code error due to -D warnings.
2026-04-05 16:04:20 +08:00
Jason 98230c3970 feat: add official subscription quota display for Gemini
- Read Gemini OAuth credentials from macOS Keychain (gemini-cli-oauth)
  or legacy file (~/.gemini/oauth_creds.json)
- Auto-refresh expired access tokens using refresh_token (Google OAuth
  tokens expire in ~1h, unlike Claude/Codex)
- Two-step API: loadCodeAssist for project ID, then retrieveUserQuota
  for per-model quota buckets
- Classify models into Pro/Flash/Flash Lite categories, show min
  remaining fraction as utilization percentage
- Extend isOfficialProvider() for Gemini (no API key + no base URL)
- Parameterize expiredHint i18n key with tool name for all three apps
2026-04-04 22:53:20 +08:00
Jason 0200fe79ae feat: add official subscription quota display for Codex
Read Codex OAuth credentials from ~/.codex/auth.json (with macOS
Keychain fallback) and query chatgpt.com/backend-api/wham/usage to
show rate limit utilization on official Codex provider cards. Reuses
the same tier naming (five_hour, seven_day) for frontend i18n compat.
2026-04-04 22:53:20 +08:00
Jason b30f3c27ad feat: display official subscription quota on Claude provider cards
Read Claude OAuth credentials from macOS Keychain (with file fallback)
and query the Anthropic usage API to show quota utilization inline on
official provider cards. Includes compact countdown timer for reset
windows and hides the rarely-used seven_day_sonnet tier in inline mode.
2026-04-04 22:53:20 +08:00