A pi extension that displays your active model provider's subscription quota usage in the status bar. Supports z.ai (GLM Coding Plan) and OpenAI Codex subscriptions.
Shows subscription quota usage in pi's footer status bar for your active model provider:
- z.ai (GLM) — 5-hour and weekly quotas with dynamic reset times
- OpenAI Codex — Quota windows derived from the API (for example 5-hour/weekly subscriptions or a 30-day Free-plan window)
Displays as a percentage used (e.g., 5h: 16% | week: 4%).
The status bar updates live every 60 seconds during long agent runs.
The status bar also shows:
- Plan level (when available)
- Time until quota reset (relative or absolute as appropriate)
Example outputs:
5h 16% ↻ 2h14 · 1w 4% ↻ Mo
30d 17% ↻ Aug 9
- z.ai (GLM):
https://api.z.ai/api/monitor/usage/quota/limitwith API key from~/.pi/agent/auth.json→zai.key - OpenAI Codex:
https://chatgpt.com/backend-api/wham/usageusing~/.pi/agent/auth.json→openai-codexOAuth state.limit_window_secondsdetermines whether a window is rendered as hours, a week, or days.
Example response:
{
"code": 200,
"data": {
"limits": [
{
"type": "TOKENS_LIMIT",
"unit": 3,
"percentage": 16,
"nextResetTime": 1777819631597
},
{
"type": "TOKENS_LIMIT",
"unit": 6,
"percentage": 4,
"nextResetTime": 1778262784969
},
{
"type": "TIME_LIMIT",
"unit": 5,
"percentage": 0,
"nextResetTime": 1780336384978
}
],
"level": "lite"
}
}Unit mapping (discovered from z.ai frontend source):
unit |
Meaning |
|---|---|
| 3 | 5 Hours Quota (TOKENS_LIMIT) |
| 6 | Weekly Quota (TOKENS_LIMIT) |
| 5 | Monthly Web Search/Reader/Zread (TIME_LIMIT) — parsed but not displayed in v1 |
- Fetches quota data immediately on pi startup (
session_startevent) - Starts 60-second periodic refresh when agent begins (
agent_startevent) - Stops periodic refresh and fetches quota after each agent turn (
agent_endevent) - Live updates every 60 seconds during long agent runs
- Updates the status bar immediately with provider-specific formatting
- Falls back gracefully on errors (shows last known state or hides)
- All fetches are fire-and-forget (non-blocking) with a 5-second timeout
Uses ctx.ui.setStatus("pi-usage", ...) to render a provider-neutral status bar entry:
5h 16% ↻ 2h14 · 1w 4% ↻ Mo
30d 17% ↻ Aug 9
↻shows when the quota resets (relative or absolute as appropriate)- Plan level shown on the left (when available)
- Missing quota types are omitted from the display
- Status entry is hidden for unsupported providers
No configuration needed. The extension reads provider credentials from ~/.pi/agent/auth.json:
{
"zai": {
"type": "api_key",
"key": "your-zai-api-key-here"
},
"openai-codex": {
"type": "oauth",
"access": "access-token",
"refresh": "refresh-token",
"expires": 1777819631597,
"accountId": "account-id"
}
}Required fields:
zai.keyfor z.ai (GLM) usageopenai-codex.access,refresh,expires, andaccountIdfor Codex usage
The extension will hide the status bar entry if required credentials are missing for the active provider.
Environment variable (for testing):
Set PI_AUTH_DIR to override the auth file path:
export PI_AUTH_DIR=/path/to/test/auth/dirThis is useful for testing without affecting your actual pi configuration.
pi install npm:@unfixed3854/pi-usageThis automatically downloads and installs the extension. Restart pi to load it.
-
Create the extensions directory if it doesn't exist:
mkdir -p ~/.pi/agent/extensions/pi-usage -
Copy the extension files to the directory:
cp -r pi-usage/* ~/.pi/agent/extensions/pi-usage/
-
Restart pi to load the extension
The extension will automatically load and display your quota usage in the status bar.
Cause: Auth file is missing or required credentials are not configured for the active provider.
Fix: Ensure ~/.pi/agent/auth.json exists and contains valid credentials for your provider:
cat ~/.pi/agent/auth.jsonFor z.ai (GLM):
{
"zai": {
"type": "api_key",
"key": "sk-..."
}
}For OpenAI Codex:
{
"openai-codex": {
"type": "oauth",
"access": "access-token",
"refresh": "refresh-token",
"expires": 1777819631597,
"accountId": "account-id"
}
}If the file is missing, configure your provider credentials in pi settings.
Cause: API fetch failed or timed out, falling back to cached data.
Fix: Check the pi console for error messages. Common issues:
- Network connectivity problems
- API endpoint is temporarily unavailable
- Invalid API key or expired OAuth credentials
To force a refresh, trigger a new agent turn (ask a question in pi).
Cause: The API request timed out after 5 seconds.
Fix: This is usually temporary. The extension will retry on the next agent turn. If the issue persists:
- Check your network connection
- Verify the active provider endpoint is accessible
- Check if z.ai or ChatGPT services are operational
Cause: The extension files are not in the correct location or have syntax errors.
Fix: Verify the extension is installed correctly:
ls -la ~/.pi/agent/extensions/pi-usage/You should see:
index.ts
api.ts
auth.ts
format.ts
types.ts
package.json
tsconfig.json
Check the pi console for any error messages during startup.
Cause: The extension was not built or has type errors.
Fix: Run the typecheck to identify issues:
bun run typecheckFix any reported errors and rebuild the extension if necessary.
- Color coding — green/yellow/red as quota fills up (needs
ctx.ui.setStatuscolor support or ANSI codes) /pi-usagecommand — detailed breakdown withpi.registerCommand()- Token consumption per model — requires additional API data
- Web search quota (unit 5) — z.ai returns it but it is not displayed
- Configurable refresh interval — make the 60-second interval adjustable
- Detailed error display — show minimal error message instead of hiding status bar
The extension is structured with clear separation of concerns:
timer.ts— Periodic refresh controller with dependency injection (fully unit testable)api.ts— z.ai API client with timeout and error handlingcodex.ts— OpenAI Codex usage fetcher and parserauth.ts— provider credential reader from~/.pi/agent/auth.jsonformat.ts— Status bar formatting utilitiesusage.ts/router.ts— provider-neutral routing and usage snapshotstypes.ts— Shared TypeScript typesindex.ts— Extension entry point, wires everything together
All modules follow TDD with co-located tests (<module>.test.ts).