Skip to content

Instantly share code, notes, and snippets.

@airtonix
Last active March 4, 2026 22:28
Show Gist options
  • Select an option

  • Save airtonix/25b4aee6f4a6a775aff028adfdb9936f to your computer and use it in GitHub Desktop.

Select an option

Save airtonix/25b4aee6f4a6a775aff028adfdb9936f to your computer and use it in GitHub Desktop.
pi extension: /limits - Display usage limits for all authenticated providers via sub-core

sub-limits

Display usage limits for all authenticated providers via pi-sub-core.

Example Output

Provider Usage Limits
────────────────────────────────────────

● Anthropic (Claude)
   Daily: ███████░░░░░░░░ 47% (resets in 3h)
   Weekly: █████░░░░░░░░░░ 33%
   Extra Usage: On

● GitHub Copilot
   Month: ██████████░░░░░ 67% (250/375 requests)

● Google Gemini
   Pro: ████░░░░░░░░░░░ 25%
   Flash: ██░░░░░░░░░░░░░ 12%

○ Kiro
   ⚠ Required CLI tool not found

Requirements

pi install npm:@marckrenn/pi-sub-core
  • Providers must be configured in ~/.pi/agent/auth.json

Usage

/limits

Supported Providers

  • Anthropic (Claude) - 5h/week windows, extra usage status
  • GitHub Copilot - Monthly quota, requests remaining
  • Google Gemini - Pro/Flash quotas
  • Antigravity - Model quotas
  • OpenAI Codex - Primary/secondary windows
  • AWS Kiro - Credits
  • z.ai - Token limits

Installation

# Download from gist
gh gist clone 25b4aee6f4a6a775aff028adfdb9936f ~/.pi/agent/extensions/sub-limits

# Reload pi
/reload

How It Works

The extension uses the sub-core:request event to fetch usage entries:

pi.events.emit("sub-core:request", {
  type: "entries",
  force: true,
  reply: (payload) => {
    // payload.entries: ProviderUsageEntry[]
  }
});
/**
* sub-limits - Display usage limits for all authenticated providers
*
* Requires: pi-sub-core extension installed and running
*/
import type { ExtensionAPI, ExtensionCommandContext } from "@mariozechner/pi-coding-agent";
// Types from sub-core
type StatusIndicator = "none" | "minor" | "major" | "critical" | "maintenance" | "unknown";
interface ProviderStatus {
indicator: StatusIndicator;
description?: string;
}
interface RateWindow {
label: string;
usedPercent: number;
resetDescription?: string;
resetAt?: string;
}
interface UsageError {
code: string;
message: string;
httpStatus?: number;
}
interface UsageSnapshot {
provider: string;
displayName: string;
windows: RateWindow[];
extraUsageEnabled?: boolean;
fiveHourUsage?: number;
error?: UsageError;
status?: ProviderStatus;
requestsSummary?: string;
requestsRemaining?: number;
requestsEntitlement?: number;
}
interface ProviderUsageEntry {
provider: string;
usage?: UsageSnapshot;
}
type SubCoreEntriesRequest = {
type: "entries";
force?: boolean;
reply: (payload: { entries: ProviderUsageEntry[] }) => void;
};
export default function subLimitsExtension(pi: ExtensionAPI): void {
pi.registerCommand("limits", {
description: "Show usage limits for all authenticated providers (via sub-core)",
handler: async (_args, ctx) => {
await showLimits(pi, ctx);
},
});
}
async function showLimits(pi: ExtensionAPI, ctx: ExtensionCommandContext): Promise<void> {
const entries = await fetchUsageEntries(pi, ctx);
if (!entries) {
return;
}
if (entries.length === 0) {
ctx.ui.notify("No providers found.\nMake sure sub-core is installed and auth.json is configured.", "warning");
return;
}
const output = formatUsageReport(entries);
ctx.ui.notify(output, "info");
}
function formatUsageReport(entries: ProviderUsageEntry[]): string {
const lines: string[] = ["Provider Usage Limits", "─".repeat(40)];
for (const entry of entries) {
const usage = entry.usage;
if (!usage) {
const name = entry.provider.charAt(0).toUpperCase() + entry.provider.slice(1);
lines.push(`\n${name}: No credentials`);
continue;
}
const statusIcon = getStatusIcon(usage.status?.indicator);
const providerName = usage.displayName || entry.provider;
lines.push(`\n${statusIcon} ${providerName}`);
if (usage.error) {
lines.push(` ⚠ ${formatError(usage.error)}`);
continue;
}
// Rate windows
for (const window of usage.windows) {
const bar = renderProgressBar(window.usedPercent);
const pct = `${Math.round(window.usedPercent)}%`;
let line = ` ${window.label}: ${bar} ${pct}`;
if (window.resetDescription) {
line += ` (${window.resetDescription})`;
}
lines.push(line);
}
// Extra info
if (usage.requestsSummary) {
lines.push(` ${usage.requestsSummary}`);
}
if (usage.fiveHourUsage !== undefined) {
lines.push(` 5h Usage: $${usage.fiveHourUsage.toFixed(2)}`);
}
if (usage.extraUsageEnabled !== undefined) {
const status = usage.extraUsageEnabled ? "On" : "Off";
lines.push(` Extra Usage: ${status}`);
}
}
return lines.join("\n");
}
function renderProgressBar(percent: number): string {
const width = 15;
const filled = Math.round((percent / 100) * width);
const empty = width - filled;
return "█".repeat(filled) + "░".repeat(empty);
}
function getStatusIcon(indicator?: StatusIndicator): string {
switch (indicator) {
case "none":
return "●"; // green/ok
case "minor":
return "◐"; // partial issue
case "major":
case "critical":
return "○"; // major issue
case "maintenance":
return "◑"; // maintenance
default:
return "●";
}
}
function formatError(error: UsageError): string {
switch (error.code) {
case "NO_CREDENTIALS":
return "No credentials configured";
case "NO_CLI":
return "Required CLI tool not found";
case "NOT_LOGGED_IN":
return "Not logged in";
case "FETCH_FAILED":
return "Failed to fetch usage data";
case "HTTP_ERROR":
return `API error (${error.httpStatus ?? "unknown"})`;
case "API_ERROR":
return "API returned an error";
case "TIMEOUT":
return "Request timed out";
default:
return error.message || "Unknown error";
}
}
function isSubCoreAvailable(pi: ExtensionAPI): boolean {
try {
const events = pi.events as { listenerCount?: (event: string) => number };
if (typeof events.listenerCount === "function") {
return events.listenerCount("sub-core:request") > 0;
}
return true;
} catch {
return true;
}
}
async function fetchUsageEntries(
pi: ExtensionAPI,
ctx: ExtensionCommandContext
): Promise<ProviderUsageEntry[] | null> {
if (!isSubCoreAvailable(pi)) {
ctx.ui.notify(
"sub-core extension not loaded.\n\nInstall: pi install npm:@marckrenn/pi-sub-core\nThen run: /reload",
"warning"
);
return null;
}
return new Promise((resolve) => {
let responded = false;
const timeout = setTimeout(() => {
if (!responded) {
responded = true;
ctx.ui.notify("sub-core timed out.\nTry again or check provider credentials.", "warning");
resolve(null);
}
}, 5000);
const request: SubCoreEntriesRequest = {
type: "entries",
force: true,
reply: (payload) => {
if (!responded) {
responded = true;
clearTimeout(timeout);
resolve(payload.entries ?? []);
}
},
};
try {
pi.events.emit("sub-core:request", request);
} catch (err) {
if (!responded) {
responded = true;
clearTimeout(timeout);
ctx.ui.notify(`Error: ${err}`, "error");
resolve(null);
}
}
});
}
{
"name": "sub-limits",
"version": "1.0.0",
"description": "Display usage limits for all authenticated providers via sub-core",
"type": "module",
"main": "index.ts",
"keywords": ["pi-extension", "usage", "limits", "sub-core"],
"pi": {
"extensions": ["index.ts"]
},
"dependencies": {},
"peerDependencies": {
"@mariozechner/pi-coding-agent": "*",
"@mariozechner/pi-tui": "*"
}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment