@jack-yang/pi-quota

Quota monitor for the pi coding agent: Zhipu GLM Coding Plan (CN) 5h / weekly / MCP windows and GitHub Copilot AI credits, with run-out warnings and "Quota available" notices; English and Chinese (port of opencode-quota)

Packages

Package details

extension

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

$ pi install npm:@jack-yang/pi-quota
Package
@jack-yang/pi-quota
Version
1.0.0
Published
Nov 4, 2026
Downloads
1,195/mo · 1,195/wk
Author
yangwudong
License
MIT
Types
extension
Size
149.5 KB
Dependencies
0 dependencies · 2 peers
Pi manifest JSON
{
  "image": "https://raw.githubusercontent.com/yangwudong/pi-quota/main/docs/screenshot-widget.png",
  "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

English | 中文

npm version license CI pi

A pi coding agent extension that keeps an eye on your subscription quota: the Zhipu GLM Coding Plan (China, zai-coding-cn) 5-hour, weekly and monthly MCP windows, and GitHub Copilot AI credits. The quota floats at the top right of the chat (or the bottom right, just above the editor) without taking a row; when a window is about to run out it warns you, with the run-out time at your current pace; when a window resets it tells you "Quota available".

Subscription quota is a hard limit: the extension watches it for you and speaks up at the right moment, instead of waiting for you to remember to check.

Ported from the opencode plugin opencode-quota, keeping only what these two providers need (see Differences from opencode-quota). English by default; Simplified Chinese with /quota lang zh.

What it looks like

The quota panel floats at the top right, with a warning below (example data). It takes no rows: the chat and the editor stay where they are:

Quota panel floating at the top right: the 5h, weekly, MCP and Copilot rows with provider names in blue; below, a warning for the Zhipu 5h window and the editor

/quota, the full report (shown to you only, never sent to the model):

/quota full report: every window with its usage, reset time and pace analysis, under the floating panel

/quota config, the settings menu:

/quota config: language, quota panel (floating top right or bottom right, above the editor, hidden), percent shown (left or used), alerts for the 5h and weekly windows

  • Floating by default, and taking no rows and no keyboard input. /quota config → Quota panel cycles through:

    • top right (default): over the oldest rows on screen, which scroll out from under it;
    • bottom right: on the chat's last rows, right above the editor; it moves up with the editor when your input grows or a menu opens. It covers the newest lines' right end, which you cannot scroll out from under while they are the newest;
    • above the editor: lines of their own, as before 0.3;
    • hidden.

    Floating keeps off the chat's last row while pi shows "Jump to latest message" there. When the terminal is too narrow to keep 40 columns of chat beside the card (or too short), the panel goes above the editor until there is room again.

  • Percent shown: /quota config → Percent shown switches the panel, /quota status and the /quota report between the share left (default) and the share used: 18% left is ▰▰▰▰▰▰▰▰▱▱ 82% used. Colors, ⚠ fast and the alerts always go by what is left.

  • Provider names (Zhipu, Copilot) are blue (#008AFA); in terminals without truecolor pi uses the nearest of its 256 colors.

  • Up to 3 rows per provider: 5-hour window (5h), weekly window (wk), monthly MCP allowance (mcp). Windows your plan doesn't have are not shown.

  • Each row: a 10-cell bar, the percent (left, or used), and ⏳ with the time until the reset (14m / 3h12m / 4d).

  • ⚠ fast at the end of a row when the window is used faster than even use (once more than 10% of it has passed).

  • A provider without credentials is not shown. When a credential is rejected or a request fails, its row says why in a word (Zhipu ✗ auth, Zhipu ✗ timeout); the other provider is unaffected.

Notifications:

Warning: pi-quota · Zhipu 5h window: 15% left, resets in 1h20m; at this pace it runs out in about 40m (mute: /quota mute five-hour)
✅ Quota available · Zhipu 5h window is back to 100%

Install

pi install npm:@jack-yang/pi-quota     # from npm (recommended)
pi install /path/to/pi-quota           # local directory: loaded from that path, not copied
pi -e npm:@jack-yang/pi-quota          # try it for this run only, without touching settings

Restart pi afterwards, or run /reload in an open session. Update with pi update --extensions. Install either the npm package or a local directory, not both: with both you get two panels, and the command becomes /quota:1 and /quota:2.

Use the plain path form for a local directory: pi install npm:./pi-quota installs but does not load.

Requirements: pi ≥ 1.5.0 (tested on 1.5.0). No runtime dependencies; the only network requests go to the two quota endpoints, bigmodel.cn and api.github.com.

Credentials

Provider Where it looks Notes
Zhipu zai-coding-cn 1. env ZAI_CODING_CN_API_KEY2. the zai-coding-cn entry of pi's auth.json (the API key saved by /login zai-coding-cn) A !command key in auth.json is not run; set the env variable instead
GitHub Copilot github-copilot only the github-copilot OAuth entry of pi's auth.json (/login github-copilot) Uses its GitHub OAuth token (ghu_…), not the Copilot inference token. No API key or env substitute; GitHub Enterprise is not supported
  • auth.json is where pi keeps it: PI_CODING_AGENT_DIR, by default ~/.pi/agent. It is read on every check, so a new /login applies at once.
  • When the Copilot token has expired or been revoked (HTTP 401), the row shows ✗ auth and asks you to run /login github-copilot again. The extension never refreshes tokens itself.
  • Keys and tokens never appear in an error or a notification: every error text is redacted before it is shown.

Commands

Type /quota to see every argument with a description.

Command What it does
/quota Full report: each window's percent left, usage, reset time (local time and countdown), pace analysis and the alert settings
/quota status One-line summary, tightest window first (a failing provider comes first)
/quota refresh Drop the cache and check again now
/quota config Settings menu: language, quota panel (top right / bottom right / above the editor / hidden), percent shown (left / used), alerts per window; each pick applies at once
/quota lang [en|zh] Set the language, or pick it from a list
/quota mute <five-hour|weekly> Mute a window: no more warnings or "Quota available" for it (5h / wk work too)
/quota unmute <five-hour|weekly> Unmute it
/quota hide / /quota show Hide or show the quota panel (monitoring and alerts go on while it is hidden)

How it monitors

  • When it checks: at session start, after every turn_end, and every 60 seconds (each check restarts the timer, whichever comes first). A successful answer is cached for 60 s, so frequent turn ends do not flood the APIs; a failure is not cached and is retried on the next check. Both providers are asked in parallel, each with an 8 s timeout.
  • Warnings: a 5-hour or weekly window under 20% gets one warning per window (a window is told apart by its reset time). When the current pace would use it up before the reset (and more than 10% of the window has passed), the warning adds "at this pace it runs out in about X".
  • Recovery: a window that was under 20% and is back at 50% or more gets ✅ Quota available, also once per window. While you are idle the timer delivers it; no need to send another prompt.
  • No alerts: the MCP monthly allowance (counted differently) and Copilot's monthly credits are shown in the panel only.
  • Sent alerts are remembered on disk, so restarting pi, /new or several sessions at once never repeat the same warning.
  • It does not run in subagent processes (PI_SUBAGENT_CHILD=1); under pi --offline (PI_OFFLINE) it makes no background requests and checks only when you run /quota.

Configuration

~/.pi/agent/pi-quota/config.json. The commands write it for you; you can also edit it by hand:

{
  "language": "en",
  "placement": "top-right",
  "percent": "remaining",
  "hidden": false,
  "muted": ["five-hour"],
  "warnBelow": 20,
  "recoverAt": 50
}
Field Default Meaning
language "en" "en" or "zh" (/quota lang, /quota config)
placement "top-right" "top-right" / "bottom-right": floating over the chat at that corner; "inline": above the editor (/quota config). 0.3's "float" reads as "top-right"
percent "remaining" What the panel, the status line and the report show: "remaining" (left) or "used" (/quota config)
hidden false Whether the panel is hidden (/quota hide|show)
muted [] Muted windows (/quota mute|unmute)
warnBelow 20 Warn when less than this percent is left, in (0, 100]
recoverAt 50 Say "Quota available" when a warned window is back at this percent or more

state.json next to it remembers the alerts already sent (kept up to date automatically; delete it to start over).

The /quota command's own line in the / menu takes the language at load; after a language change it follows on the next /reload or restart. Everything else switches at once.

Differences from opencode-quota

Kept as in the original: the whole pace model and its constants; Zhipu's window split by unit 3 / 6 / TIME_LIMIT, its parsing and error handling; the five parsing branches and request headers of Copilot's copilot_internal/user; countdowns that round partial minutes up.

Original pi-quota Why
The Zhipu reply's success:false is not checked; a failure shows "Invalid quota data" success:false / code ≥ 400 are checked; codes 1000–1004 count as auth errors bigmodel.cn answers a wrong key with HTTP 200 and {"code":1000,"success":false}
Zhipu gets the bare key, Copilot token <t> Bearer for both Both endpoints accept it (tested)
Copilot within its allowance is labelled with a neutral "Premium interactions" By token_based_billing: true → "AI credits", false → "premium requests" Tells new from legacy billing; the numbers are unchanged, and credits are never called PRUs
Copilot: PAT, billing reports, budgets, GHE, organization / enterprise billing, several logins Personal subscription with pi's OAuth token only Scope
Reset notice whenever any window resets "Quota available" only for a window that was under 20% and is back at ≥ 50% Tell you when it matters
No "under the threshold" warning One warning when a 5h / weekly window drops under 20%, with the run-out forecast The point of this extension
Snapshot file with a file lock; failures back off 1–15 min In-memory cache: 60 s for success, failures not cached Simpler; a failure is retried on the next check
Window identity from observation times A window is known by its resetsAt; reset times within ±2 min are the same window The endpoint's reset time jitters by 1 ms between calls
Countdown 2d5h14m or 3.5h ⏳ 14m / ⏳ 3h12m / ⏳ 4d in the panel, 2d 5h 14m in the report More compact panel
English only English and Simplified Chinese (/quota lang)

Not ported: the 20+ other providers, the Web / Desktop / GUI surfaces, the settings page, the remote provider catalog, the export file, multiple accounts, session token counts.

Known limitations

  • Copilot's monthly credits and the MCP allowance are shown but never alert.
  • The floating panel is drawn over the chat, not beside it: it covers the right end of 4 chat lines. At the top right those scroll out from under it; at the bottom right they are the newest lines, so pick top right or above the editor in /quota config when long replies matter to you. It floats only in pi's fullscreen mode (the default); in --tui-mode regular the panel stays above the editor.
  • While the panel floats, pi's /settings cannot switch the TUI mode (pi refuses while any overlay is open: "Close active overlays before changing TUI mode"). Run /quota hide first and /quota show after, or pick above the editor.
  • Copilot and MCP windows have no fixed length, so they have no pace; Zhipu does not report a window start either, so it is taken as "reset time − window length".
  • Sent alerts are remembered in one small file without a lock: when several pi sessions check at the very same moment, a warning may very rarely repeat once.
  • Z.ai global (zai) is not supported.

Development

npm test                            # node --test, no install needed (Node ≥ 22.19)
npm install && npm run typecheck    # optional: strict tsc; installs pi as the peer dependency for its types
pi -e .                             # try it in a real session

License

MIT. Parts are adapted from opencode-quota (MIT); see LICENSE.