pi-quota

Pi extension that keeps AI subscription quota on screen and switches subscriptions by hand

Packages

Package details

extension

Install pi-quota from npm and Pi will load the resources declared by the package manifest.

$ pi install npm:pi-quota
Package
pi-quota
Version
0.1.0
Published
Aug 19, 2026
Downloads
177/mo · 20/wk
Author
macguffin
License
MIT
Types
extension
Size
46.3 KB
Dependencies
0 dependencies · 1 peer
Pi manifest JSON
{
  "extensions": [
    "./extensions/index.ts"
  ]
}

Security note

Pi packages can execute code and influence agent behavior. Review the source before installing third-party packages.

README

pi-quota

A Pi extension that keeps your coding-subscription quota on screen and switches subscriptions by hand.

The status line always shows the 5h and weekly windows of the subscription behind the active model:

Z.ai 5h ██████░░░░ 62% (resets in 1h 47m) | wk █████░░░░░ 55% (resets in 2d 3h)

The bar and the percentage are quota remaining, so both empty out as you spend. Both are blue: the remaining run bright (\x1b[94m), the spent track dim (\x1b[34m), so the split reads at a glance without adding a second hue. Nothing else on the line is colored. Set NO_COLOR to turn it off.

Only ASCII plus the block characters █░─ are used; glyphs like are missing from too many terminal fonts.

/quota opens a panel above the editor with every window of every tracked provider:

 Z.ai  coding-plan · ZAI_API_KEY
   5h     ██████░░░░  62% left   reset 13:47
   week   █████░░░░░  55% left   reset Fri 15:00
 OpenCode Go  opencode auth.json
   5h     ████████░░  88% left   reset 17:10
   week   ███████░░░  71% left   reset Mon 00:00
   month  ████░░░░░░  40% left   reset Sep 01

Install

pi install npm:pi-quota

Or pin a git ref, or point at a local checkout:

pi install git:github.com/USER/pi-quota@v0.1.0
pi install /path/to/pi-quota

Requires Node >=22.19.0, the same floor as Pi itself.

pi install writes to ~/.pi/agent/settings.json. Add -l to write to the project's .pi/settings.json instead, which shares the package with anyone who trusts that project.

Commands

Command What it does
/sub Switch which subscription serves requests.
/quota Toggle the panel. The choice persists across sessions.
/quota refresh Re-read quota now instead of waiting for the poll.
/quota switch Alias for /sub.

/sub lists one row per provider, not per model:

● Z.ai  5h 62% (1h 47m) | wk 29% (2d 3h)
  OpenCode Go  5h 100% (4h 59m) | wk 100% (3d 21h)

Picking a provider switches to the model you last used on it, falling back to its first model in Pi's catalog. Choosing among a provider's models is Pi's own /model command's job.

A provider whose key Pi cannot see — because it lives only in the OpenCode auth file or the zcode config — still appears, marked needs a Pi credential. Its quota is readable, but routing to it requires adding the key to Pi with /login or ~/.pi/agent/auth.json.

Providers

Provider Windows Switchable
Z.ai coding plan (zai) 5h, weekly yes
OpenCode Go (opencode-go) 5h, weekly, monthly yes

Both are built into Pi, so switching is an ordinary model change. Codex and Grok are routable by Pi and can be added the same way; Cursor is a desktop-app session against Cursor's own backend and could only ever be display-only.

Where the credentials come from

For each provider, in order:

  1. The key Pi itself resolved (ctx.modelRegistry.getProviderAuth). Preferring this means the number on screen describes the account Pi is spending.
  2. The OpenCode auth file — $XDG_DATA_HOME/opencode/auth.json, ~/Library/Application Support/opencode/auth.json on macOS, otherwise ~/.local/share/opencode/auth.json.
  3. For Z.ai only, ~/.zcode/v2/config.json.

The panel names the source it used, so it is visible when the displayed quota belongs to a different account than the one Pi is billing.

Credentials are never written to the config file, the status line, the panel, or any error message: provider errors pass through a redaction step first.

Configuration

~/.pi/agent/pi-quota.json:

{
  "panel": false,
  "pollIntervalMs": 300000,
  "lastModelByProvider": {
    "zai": "glm-4.7"
  }
}

lastModelByProvider is what makes /sub return you to the model you were on.

pollIntervalMs has a floor of 60s. These are undocumented vendor endpoints; there is no reason to hammer them.

Environment overrides, mostly for testing:

  • PI_QUOTA_CONFIG — path to the config file
  • PI_QUOTA_OPENCODE_AUTH — path to the OpenCode auth file
  • PI_QUOTA_ZCODE_CONFIG — path to the zcode config

Behavior notes

  • Nothing runs in print (-p) or JSON mode. Those have no UI, so there is no polling, no painting, and no network traffic.
  • A failed refresh keeps the last good reading and marks it stale (~ on the status line, stale 6m in the panel). The provider's error text only reaches the panel after three consecutive failures.
  • As the terminal narrows the status line sheds detail in order: the "resets in" phrasing, the bars, the weekly reset, the weekly window, and finally everything but the 5h percentage.
  • Quota is refreshed at session start, on the poll interval, after a turn when the last refresh is over a minute old, and on demand.

Caveat

Neither quota endpoint is a documented, stable interface. They can change or start failing without notice.

  • Z.ai: GET https://api.z.ai/api/monitor/usage/quota/limit
  • OpenCode Go: GET https://opencode.ai/zen/go/v1/usage

Development

npm install
npm test
npm run typecheck
pi -e ./extensions/index.ts

Releasing

npm test && npm run typecheck
npm pack --dry-run          # check the tarball contents
npm version patch|minor|major
npm publish                 # needs `npm login`
git push && git push --tags

There is no build step, so the tarball ships the TypeScript sources that Pi loads through jiti. @earendil-works/pi-coding-agent is a peer marked optional: Pi injects its own modules through loader aliases, and marking it optional stops npm from fetching the whole host package when the extension is installed from a git source.

The design is written up in docs/superpowers/specs/2026-08-19-pi-quota-design.md.