@andy8647/pi-balance
Pi extension that displays provider account balance in the status bar.
Package details
Install @andy8647/pi-balance from npm and Pi will load the resources declared by the package manifest.
$ pi install npm:@andy8647/pi-balance- Package
@andy8647/pi-balance- Version
1.1.0- Published
- Oct 28, 2026
- Downloads
- 809/mo · 431/wk
- Author
- andy8647
- License
- MIT
- Types
- extension
- Size
- 136.4 KB
- Dependencies
- 0 dependencies · 2 peers
Pi manifest JSON
{
"image": "https://raw.githubusercontent.com/Andy8647/pi-balance/main/assets/preview.png",
"extensions": [
"./src/index.ts"
]
}Security note
Pi packages can execute code and influence agent behavior. Review the source before installing third-party packages.
README
📋 Features
pi-balance is an extension for the pi coding agent that automatically fetches and displays your AI provider's API credit balance in the pi status bar.
Note: This repository is a fork of DragonYH/pi-balance — all credit for the original extension goes to @DragonYH. This fork is published as
@andy8647/pi-balanceand adds:
- Kimi coding plan support — 5-hour rate limit and 7-day quota display (via the
/usagesendpoint), plus booster wallet balance- Stable DeepSeek currency detection for multi-currency
balance_infos- Zero-build packaging — ships TypeScript source directly (pi loads
.tsextensions natively), no install-time compilation
- ✅ Auto-detects your currently active model provider
- ✅ Event-driven refresh — balance updates automatically after each conversation; the pill shows the number, the bubble shows the change since the last check (▲▼)
- ✅ Live updates on provider/model switch
- ✅ Multi-provider support — DeepSeek, Moonshot/Kimi, OpenRouter, Sub2Api, OpenAI Codex (and compatible APIs)
- ✅ Zero configuration for balance APIs — supported balance APIs work from existing model headers
- ✅ Graceful fallback — quietly hides when balance info is unavailable
- ✅ i18n support — English and Simplified Chinese, with
/balance lang <zh-CN|en>command
📦 Installation
Option 1: Install from npm (Recommended)
pi install npm:@andy8647/pi-balance
Option 2: Install from GitHub
pi install git:github.com/Andy8647/pi-balance
Option 3: Local Development
git clone https://github.com/Andy8647/pi-balance.git
cd pi-balance
npm install
pi install ./
Verify Installation
Restart pi. You should see the balance indicator appear in the status bar once you connect to a supported provider.
🔌 Supported Providers
| Provider | Balance Endpoint | Display |
|---|---|---|
| DeepSeek | /user/balance |
¥ (CNY) balance |
| Moonshot / Kimi | /v1/users/me/balance |
¥ (CNY) available balance |
| Sub2Api | /usage |
$ (USD) remaining balance |
| Compatible APIs | /usage, /v1/usage |
$ (USD) remaining balance |
| OpenAI Codex | ChatGPT Codex usage API / codex app-server |
5-hour usage remaining; the 7-day window, reset countdown, and reset credits are in the bubble |
| OpenRouter | /v1/credits |
$ (USD) remaining credits |
The extension automatically detects which provider you're using based on your current model configuration — no manual setup required.
🚀 Usage
Once installed, pi-balance works completely automatically:
- On session start — it fetches your balance immediately
- On model switch — it re-fetches for the new provider
- After each conversation (
agent_end) — refreshes and records the delta (▲▼) for the bubble
The balance is displayed in the status bar at the bottom of your pi terminal:
DeepSeek: ¥49.87
If the extension cannot determine your balance (e.g., unsupported provider or network issue), the status bar entry is gracefully hidden.
/balance Command
Run /balance to open an interactive configuration menu. You can:
- View support status for configured providers
- Expand/collapse providers to toggle display and extra options
- Enable/disable Sub2Api sub-providers inline (with auto-discovery)
- Toggle Codex CLI fallback on/off
- Refresh the current status immediately
You can also use command arguments directly:
/balance status
/balance refresh
/balance enable deepseek
/balance disable moonshot
/balance toggle codex
/balance toggle openrouter
/balance toggle sub2api
/balance sub2api # Open Sub2Api sub-provider menu
/balance sub2api rescan # Re-scan for new Sub2Api providers
/balance lang zh-CN # Switch to Simplified Chinese
/balance lang en # Switch to English
Configuration Notes
- Provider display toggles are saved by the
/balancemenu and apply on the next refresh. - Custom Sub2Api providers are discovered from your pi model configuration (
~/.pi/agent/models.json) and can be enabled/disabled individually from the main menu or/balance sub2api. Use/balance sub2api rescanafter changing model configuration. - OpenAI Codex usage is shown only while the active model provider is
openai-codex. The extension first reuses pi's Codex subscription auth headers and can fall back tocodex app-server --listen stdio://when available; the CLI fallback can be toggled in the/balancemenu. - The menu caches support states intelligently: expanding/collapsing providers is instant (no recomputation), while config changes trigger automatic refresh.
- Network requests time out quickly and failures are hidden from the status bar instead of interrupting your session.
- With pi-starline, clicking the balance pill opens a bubble with the balance (and, on DeepSeek, how much of it was granted vs paid for), the change since the last check and when it was fetched, plus Refresh and Open /balance. Nothing changes without pi-starline.
🧠 How It Works
┌─────────────────────────────────────────────────────────────┐
│ pi Coding Agent │
│ ┌───────────────────────────────────────────────────────┐ │
│ │ │ │
│ │ [Chat Interface] │ │
│ │ │ │
│ ├───────────────────────────────────────────────────────┤ │
│ │ Status Bar: DeepSeek: ¥49.87 ◉ Connected │ │
│ └───────────────────────────────────────────────────────┘ │
│ │
│ ┌─ Extension: pi-balance ───────────────────────────────┐ │
│ │ session_start ──► fetchBalance() ──► setStatus() │ │
│ │ model_select ──► fetchBalance() ──► setStatus() │ │
│ │ agent_end ────► refreshBalance(showDelta) │ │
│ └────────────────────────────────────────────────────────┘ │
└─────────────────────────────────────────────────────────────┘
Events Handled
session_start— initial balance fetch when a session beginsmodel_select— re-fetch when you switch models/providersagent_end— refresh balance after each conversation and record the delta (▲▼) the bubble showssession_shutdown— cleanup and clear status
🏗️ Project Structure
pi-balance/
├── src/
│ ├── index.ts # Entry point, commands, lifecycle
│ ├── types.ts # Type definitions and constants
│ ├── config.ts # Config load/persist/toggle
│ ├── utils.ts # Helpers (fetch, JSON, type guards)
│ ├── menu.ts # Dynamic menu builder with caching
│ ├── starline-pill.ts # Clickable pill when pi-starline is installed
│ └── providers/
│ ├── types.ts # BalanceProvider interface
│ ├── registry.ts # Singleton provider registry
│ ├── deepseek.ts # DeepSeek provider
│ ├── moonshot.ts # Moonshot/Kimi provider
│ ├── openrouter.ts # OpenRouter provider
│ ├── sub2api.ts # Sub2Api + auto-discovery
│ └── codex.ts # OpenAI Codex + CLI fallback
│ └── i18n/
│ ├── index.ts # t() function + language detection
│ ├── zh-CN.ts # Chinese translations
│ └── en.ts # English translations
├── tests/
│ └── index.test.ts
├── LICENSE # MIT license
├── README.md # English documentation
├── README.zh-CN.md # Chinese documentation
├── package.json # Node.js and pi package manifest
└── tsconfig.json # TypeScript configuration
🛠️ For Developers
Type-Checking
npm run typecheck
Test
npm test
Publish Checklist
This project publishes through GitHub Actions when a version tag is pushed.
Before publishing, verify the package contents:
npm pack --dry-run
Then create and push a tag that matches package.json:
git tag vX.Y.Z
git push origin vX.Y.Z
Before pushing the tag, configure npm Trusted Publishing for this package:
- Publisher: GitHub Actions
- Owner:
Andy8647 - Repository:
pi-balance - Workflow:
publish.yml - Environment:
npm-publish
Adding a New Provider
The extension uses a pluggable provider architecture. To add support for a new provider, create a module in src/providers/ that implements the BalanceProvider interface, then import it in src/index.ts to trigger auto-registration:
// src/providers/yourprovider.ts
import type { BalanceProvider } from "./types.js";
import { registry } from "./registry.js";
import type {
BalanceResult,
BalanceConfig,
FetchContext,
ProviderSupport,
} from "../types.js";
import { getJson } from "../utils.js";
export const yourProvider: BalanceProvider = {
key: "yourprovider",
definition: {
key: "yourprovider",
label: "YourProvider",
color: "#FFD700",
},
shouldTry(model, baseUrl) {
return baseUrl.includes("yourprovider.com");
},
async fetchBalance(
ctx: FetchContext,
signal?: AbortSignal,
): Promise<BalanceResult | undefined> {
const data = await getJson(`${ctx.baseUrl}/your/endpoint`, ctx.headers, signal);
const amount = data?.credits_remaining;
return typeof amount === "number" ? { amount, unit: "$" } : undefined;
},
async getSupport(
ctx: ExtensionContext,
config: BalanceConfig,
): Promise<ProviderSupport> {
return {
provider: this.definition,
configured: true,
details: ["Configured"],
};
},
};
registry.register(yourProvider);
Then add one import in src/index.ts:
import "./providers/yourprovider.js";
That's it — the provider auto-registers, appears in the /balance menu, and participates in balance fetching. No other code changes needed.
