@andy8647/pi-balance

Pi extension that displays provider account balance in the status bar.

Packages

Package details

extension

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-balance and adds:

  • Kimi coding plan support — 5-hour rate limit and 7-day quota display (via the /usages endpoint), plus booster wallet balance
  • Stable DeepSeek currency detection for multi-currency balance_infos
  • Zero-build packaging — ships TypeScript source directly (pi loads .ts extensions 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:

  1. On session start — it fetches your balance immediately
  2. On model switch — it re-fetches for the new provider
  3. 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 /balance menu 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 rescan after 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 to codex app-server --listen stdio:// when available; the CLI fallback can be toggled in the /balance menu.
  • 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 begins
  • model_select — re-fetch when you switch models/providers
  • agent_end — refresh balance after each conversation and record the delta (▲▼) the bubble shows
  • session_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.

📄 License

MIT