Skip to content

feat(usage): add opt-in Copilot and Codex subscription quotas - #1

Draft
gpicron wants to merge 2 commits into
pifydev:mainfrom
gpicron:feat/subscription-quotas
Draft

gpicron wants to merge 2 commits into
pifydev:mainfrom
gpicron:feat/subscription-quotas

Conversation

@gpicron

@gpicron gpicron commented Oct 26, 2026

Copy link
Copy Markdown

Summary

Add explicitly requested subscription-quota reporting for GitHub Copilot and OpenAI Codex, alongside the existing balance endpoints and passive rate-limit headers.

  • /usage quota checks only the active model's provider. An unused configured OpenRouter key is no longer resolved or queried when Copilot is active.
  • Report Copilot premium-interaction/credit percentages and Codex primary/secondary windows as remaining, including resets and unlimited quota. Missing or unrecognized data is unavailable, not a fabricated zero.
  • Show the active subscription's cached quota first in the footer. The cache is in-memory only, cleared on session start/reload, and marked stale on the next redraw after 15 minutes or a reported reset. No background polling is introduced.
  • Namespace the status as pify-usage and add /pify-usage as a stable alias for coexistence with another usage extension. /usage remains available when unambiguous; Pi's existing duplicate-command disambiguation is documented.

Authentication and request boundaries

Credentials come from Pi's public APIs; this package does not parse an auth file or maintain another credential store.

  • Copilot uses the original GitHub OAuth login token, never the Copilot inference token. Resolve the credential and its matching endpoint together: github.com → api.github.com; a GHE Cloud data-residency login on <tenant>.ghe.com → api.<tenant>.ghe.com.
  • The allowlist contains only the matching API host. No public/Enterprise fallback; unsupported/custom authorities, userinfo, non-default ports, paths, queries and fragments are rejected before a request.
  • Codex requires an OAuth credential and checks that Pi's resolved token matches the stored access token after refresh. Only the required account-id claim is extracted locally; inference headers and other JWT claims are not forwarded.
  • Preserve HTTPS-only requests, refused redirects, the eight-second quota HTTP timeout, ignored non-2xx bodies and sanitized errors. Pi-managed OAuth refresh can take additional time and persist refreshed credentials.
  • Startup, model changes, footer redraws and usage_status do not initiate quota requests. Explicit auth failures for the active provider are displayed rather than silently omitted.

Existing OpenRouter/DeepSeek balances, local token/cost reporting and passive Anthropic subscription warnings remain supported. No dependencies or lockfile changes.

Endpoint-policy note

This intentionally extends the current balance-endpoints-only policy to subscription endpoints published in official client documentation/source:

Publication in a client is not a stable, versioned third-party HTTP API guarantee. The separately documented Codex app-server account/rateLimits/read interface is not being presented as that guarantee. The README records this compatibility risk and the opt-in behavior. Opening as a draft for maintainer review of this policy extension.

Validation

  • bun run typecheck — passed.
  • bun test — 77 passed, 0 failed.
  • node --test test/*.test.ts — 77 passed, 0 failed.
  • Additional local offline loader/command-resolution smoke checks against Pi SDK 0.87.0 and 1.4.0 passed.

Tests use synthetic credentials and mocked responses. They cover active-provider selection with an unused OpenRouter key, original-vs-inference token separation, public/GHE authority binding, spoofed authorities, no fallback after 403, Codex token mismatch, malformed data, cache/reset expiry, model switching and status/command coexistence through the real SDK resolver.

No authenticated quota requests or model launches are part of these tests. Windows is covered by the repository's existing CI matrix, not claimed as locally verified. No successful live-server quota result or real TUI rendering is claimed by the automated checks.

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