Big News: Socket raises $60M Series C at a $1B valuation to secure software supply chains for AI-driven development.Announcement
Sign In

opencode-usage-plugin

Package Overview
Dependencies
Maintainers
1
Versions
11
Alerts
File Explorer

Advanced tools

Socket logo

Install Socket

Detect and block malicious and high-risk dependencies

Install

opencode-usage-plugin - npm Package Compare versions

Comparing version
0.0.1
to
0.0.2-dev
+113
-77
dist/index.js
// src/index.ts
import { tool } from "@opencode-ai/plugin";
import { fileURLToPath } from "node:url";
import { readdir, readFile as readFile2 } from "node:fs/promises";
import path from "path";

@@ -28,12 +25,32 @@ // src/providers/common/logger.ts

debug: async (message, extra) => {
await client.app.log({ service, level: "debug", message, extra });
await client.app.log({
service,
level: "debug",
message,
...extra ?? {}
});
},
info: async (message, extra) => {
await client.app.log({ service, level: "info", message, extra });
await client.app.log({
service,
level: "info",
message,
...extra ?? {}
});
},
warn: async (message, extra) => {
await client.app.log({ service, level: "warn", message, extra });
await client.app.log({
service,
level: "warn",
message,
...extra ?? {}
});
},
error: async (message, extra) => {
await client.app.log({ service, level: "error", message, extra });
await client.app.log({
service,
level: "error",
message,
...extra ?? {}
});
}

@@ -119,14 +136,2 @@ };

};
var parseProvider = (input) => {
if (!input) {
return null;
}
const normalized = input.trim().toLowerCase();
for (const [providerId, aliases] of Object.entries(PROVIDER_ALIASES)) {
if (aliases.includes(normalized)) {
return providerId;
}
}
return null;
};
var getProviderAliases = (provider) => {

@@ -664,49 +669,81 @@ return PROVIDER_ALIASES[provider];

// src/types.ts
// src/types/provider.ts
var PROVIDERS = ["openai", "google", "zai-coding-plan"];
// src/index.ts
var parseFrontmatter = (content) => {
const match = content.match(/^---\n([\s\S]*?)\n---\n([\s\S]*)$/);
if (!match) {
return { frontmatter: {}, body: content.trim() };
// src/toast/filter.ts
var FLAGSHIP_PATTERNS = [
/claude[-\s]*opus[-\s]*4[-\s.]?5/i,
/gemini[-\s]*3[-\s.]?pro/i,
/gemini[-\s]*3[-\s.]?flash/i
];
var isFlagshipModel = (modelName) => {
return FLAGSHIP_PATTERNS.some((pattern) => pattern.test(modelName));
};
var filterFlagshipModels = (models) => {
if (!models) {
return {};
}
const [, yamlContent, body] = match;
const frontmatter = {};
for (const line of yamlContent.split("\n")) {
const colonIndex = line.indexOf(":");
if (colonIndex === -1) {
continue;
const filtered = {};
for (const [modelName, modelData] of Object.entries(models)) {
if (isFlagshipModel(modelName)) {
filtered[modelName] = modelData;
}
const key = line.slice(0, colonIndex).trim();
const value = line.slice(colonIndex + 1).trim();
if (key === "description") {
frontmatter.description = value;
}
}
return { frontmatter, body: body.trim() };
return filtered;
};
var loadCommands = async () => {
const commands = [];
const __filename = fileURLToPath(import.meta.url);
const __dirname = path.dirname(__filename);
const commandDir = path.join(__dirname, "command");
const walkDir = async (dir, baseDir = dir) => {
const entries = await readdir(dir, { withFileTypes: true });
for (const entry of entries) {
const fullPath = path.join(dir, entry.name);
if (entry.isDirectory()) {
await walkDir(fullPath, baseDir);
} else if (entry.name.endsWith(".md")) {
const content = await readFile2(fullPath, "utf-8");
const { frontmatter, body } = parseFrontmatter(content);
const relativePath = path.relative(baseDir, fullPath);
const name = relativePath.replace(/\.md$/, "").replace(/\//g, "-");
commands.push({ name, frontmatter, template: body });
// src/toast/format.ts
var formatProviderLine = (provider, usage) => {
if (!usage) {
return `${provider}: Not configured`;
}
const globalWindows = Object.values(usage.windows);
if (globalWindows.length > 0) {
const window = globalWindows[0];
const used = window.usedPercent ?? 0;
const reset = window.resetAfterFormatted ?? "N/A";
return `${provider}: ${used}% used \u2022 resets in ${reset}`;
}
if (usage.models) {
const models = Object.entries(usage.models);
if (models.length === 1) {
const [modelName, modelData] = models[0];
const window = Object.values(modelData.windows)[0];
const used = window.usedPercent ?? 0;
const reset = window.resetAfterFormatted ?? "N/A";
return `${provider}: ${modelName} ${used}% \u2022 resets in ${reset}`;
}
if (models.length > 1) {
const parts = [];
for (const [modelName, modelData] of models) {
const window = Object.values(modelData.windows)[0];
const used = window.usedPercent ?? 0;
parts.push(`${modelName} ${used}%`);
}
return `${provider}: ${parts.join(", ")}`;
}
}
return `${provider}: No usage data`;
};
var formatUsageToast = (results) => {
const lines = [];
for (const result of results) {
let usage = result.usage;
if (result.provider === "google" && usage?.models) {
usage = {
...usage,
models: filterFlagshipModels(usage.models)
};
}
const line = formatProviderLine(result.provider, usage);
lines.push(line);
}
return {
title: "Usage",
message: lines.join("\n"),
variant: "info"
};
await walkDir(commandDir);
return commands;
};
// src/index.ts
var fetchUsage = async (provider, logger) => {

@@ -724,16 +761,17 @@ switch (provider) {

const logger = createLogger(client);
const commands = await loadCommands();
const usageTool = tool({
description: "Fetch subscription usage for OpenAI, Google, and z.ai providers.",
args: {
provider: tool.schema.string().optional().describe(
"Provider to check: openai, google, or zai-coding-plan. Aliases: codex, antigravity, zai."
)
},
async execute(args) {
const targetProvider = parseProvider(args.provider);
const providers = targetProvider ? [targetProvider] : PROVIDERS;
await logger.info(`Fetching usage for: ${providers.join(", ")}`);
const results = await Promise.all(providers.map((provider) => fetchUsage(provider, logger)));
return JSON.stringify(results, null, 2);
const usageToastTool = tool({
description: "Show subscription usage as toast for OpenAI, Google, and z.ai providers",
args: {},
async execute() {
await logger.info("Fetching usage for all providers");
const results = await Promise.all(PROVIDERS.map((provider) => fetchUsage(provider, logger)));
const toast = formatUsageToast(results);
await client.tui.showToast({
body: {
title: toast.title,
message: toast.message,
variant: toast.variant
}
});
return "Usage displayed";
}

@@ -743,12 +781,10 @@ });

tool: {
usage: usageTool
usage_toast: usageToastTool
},
async config(config) {
config.command = config.command ?? {};
for (const cmd of commands) {
config.command[cmd.name] = {
template: cmd.template,
description: cmd.frontmatter.description
};
}
config.command.usage = {
template: "Call the usage_toast tool.",
description: "Show subscription usage for OpenAI, Google, and z.ai providers"
};
}

@@ -755,0 +791,0 @@ };

{
"version": 3,
"sources": ["../src/index.ts", "../src/providers/common/logger.ts", "../src/providers/common/time.ts", "../src/providers/common/files.ts", "../src/providers/common/registry.ts", "../src/providers/google/auth.ts", "../src/providers/google/fetch.ts", "../src/providers/openai/auth.ts", "../src/providers/openai/fetch.ts", "../src/providers/zai-coding-plan/auth.ts", "../src/providers/zai-coding-plan/fetch.ts", "../src/types.ts"],
"sourcesContent": ["import type { Plugin } from '@opencode-ai/plugin';\nimport { tool } from '@opencode-ai/plugin';\nimport { fileURLToPath } from 'node:url';\nimport { readdir, readFile } from 'node:fs/promises';\nimport path from 'path';\n\nimport { createLogger, type Logger } from './providers/common/logger.ts';\nimport { fetchGoogleUsage } from './providers/google/fetch.ts';\nimport { fetchOpenaiUsage } from './providers/openai/fetch.ts';\nimport { fetchZaiUsage } from './providers/zai-coding-plan/fetch.ts';\nimport { parseProvider } from './providers/common/registry.ts';\nimport { PROVIDERS, type ProviderId, type ProviderResult } from './types.ts';\n\ninterface CommandFrontmatter {\n description?: string;\n}\n\ninterface ParsedCommand {\n name: string;\n frontmatter: CommandFrontmatter;\n template: string;\n}\n\ninterface UsageArgs {\n provider?: string;\n}\n\nconst parseFrontmatter = (content: string): { frontmatter: CommandFrontmatter; body: string } => {\n const match = content.match(/^---\\n([\\s\\S]*?)\\n---\\n([\\s\\S]*)$/);\n if (!match) {\n return { frontmatter: {}, body: content.trim() };\n }\n\n const [, yamlContent, body] = match;\n const frontmatter: CommandFrontmatter = {};\n\n for (const line of yamlContent.split('\\n')) {\n const colonIndex = line.indexOf(':');\n if (colonIndex === -1) {\n continue;\n }\n\n const key = line.slice(0, colonIndex).trim();\n const value = line.slice(colonIndex + 1).trim();\n if (key === 'description') {\n frontmatter.description = value;\n }\n }\n\n return { frontmatter, body: body.trim() };\n};\n\nconst loadCommands = async (): Promise<ParsedCommand[]> => {\n const commands: ParsedCommand[] = [];\n const __filename = fileURLToPath(import.meta.url);\n const __dirname = path.dirname(__filename);\n const commandDir = path.join(__dirname, 'command');\n\n const walkDir = async (dir: string, baseDir: string = dir): Promise<void> => {\n const entries = await readdir(dir, { withFileTypes: true });\n\n for (const entry of entries) {\n const fullPath = path.join(dir, entry.name);\n\n if (entry.isDirectory()) {\n await walkDir(fullPath, baseDir);\n } else if (entry.name.endsWith('.md')) {\n const content = await readFile(fullPath, 'utf-8');\n const { frontmatter, body } = parseFrontmatter(content);\n const relativePath = path.relative(baseDir, fullPath);\n const name = relativePath.replace(/\\.md$/, '').replace(/\\//g, '-');\n commands.push({ name, frontmatter, template: body });\n }\n }\n };\n\n await walkDir(commandDir);\n return commands;\n};\n\nconst fetchUsage = async (provider: ProviderId, logger: Logger): Promise<ProviderResult> => {\n switch (provider) {\n case 'openai':\n return fetchOpenaiUsage(logger);\n case 'google':\n return fetchGoogleUsage(logger);\n case 'zai-coding-plan':\n return fetchZaiUsage(logger);\n }\n};\n\nexport const UsagePlugin: Plugin = async ({ client }) => {\n const logger = createLogger(client);\n const commands = await loadCommands();\n\n const usageTool = tool({\n description: 'Fetch subscription usage for OpenAI, Google, and z.ai providers.',\n args: {\n provider: tool.schema\n .string()\n .optional()\n .describe(\n 'Provider to check: openai, google, or zai-coding-plan. Aliases: codex, antigravity, zai.'\n ),\n },\n async execute(args: UsageArgs) {\n const targetProvider = parseProvider(args.provider);\n const providers: ProviderId[] = targetProvider ? [targetProvider] : PROVIDERS;\n\n await logger.info(`Fetching usage for: ${providers.join(', ')}`);\n\n const results = await Promise.all(providers.map((provider) => fetchUsage(provider, logger)));\n\n return JSON.stringify(results, null, 2);\n },\n });\n\n return {\n tool: {\n usage: usageTool,\n },\n async config(config) {\n config.command = config.command ?? {};\n\n for (const cmd of commands) {\n config.command[cmd.name] = {\n template: cmd.template,\n description: cmd.frontmatter.description,\n };\n }\n },\n };\n};\n\nexport default UsagePlugin;\n", "export type LogLevel = 'debug' | 'info' | 'warn' | 'error';\n\nexport interface Logger {\n debug: (message: string, extra?: Record<string, unknown>) => Promise<void>;\n info: (message: string, extra?: Record<string, unknown>) => Promise<void>;\n warn: (message: string, extra?: Record<string, unknown>) => Promise<void>;\n error: (message: string, extra?: Record<string, unknown>) => Promise<void>;\n}\n\nexport const maskSecret = (secret: string): string => {\n if (!secret || typeof secret !== 'string' || secret.length <= 8) {\n return '***';\n }\n return `${secret.slice(0, 4)}...${secret.slice(-4)}`;\n};\n\nconst noOpLogger: Logger = {\n debug: async () => {},\n info: async () => {},\n warn: async () => {},\n error: async () => {},\n};\n\ninterface LogOptions {\n service: string;\n level: LogLevel;\n message: string;\n extra?: Record<string, unknown>;\n}\n\ninterface OpenCodeClient {\n app: {\n log: (_options: LogOptions) => Promise<boolean> | { ok: boolean };\n };\n}\n\nexport const createLogger = (client: unknown): Logger => {\n const service = 'opencode-usage';\n\n return {\n debug: async (message, extra) => {\n await (client as OpenCodeClient).app.log({ service, level: 'debug', message, extra });\n },\n info: async (message, extra) => {\n await (client as OpenCodeClient).app.log({ service, level: 'info', message, extra });\n },\n warn: async (message, extra) => {\n await (client as OpenCodeClient).app.log({ service, level: 'warn', message, extra });\n },\n error: async (message, extra) => {\n await (client as OpenCodeClient).app.log({ service, level: 'error', message, extra });\n },\n };\n};\n\nexport const noopLogger = noOpLogger;\n", "export const calculateResetAfterSeconds = (\n resetAt: number | null,\n now: number = Date.now()\n): number | null => {\n if (!resetAt) {\n return null;\n }\n\n const diffMs = resetAt - now;\n if (diffMs <= 0) {\n return 0;\n }\n\n return Math.floor(diffMs / 1000);\n};\n\nexport const calculateResetAt = (\n resetAfterSeconds: number | null,\n now: number = Date.now()\n): number | null => {\n if (resetAfterSeconds === null || resetAfterSeconds === undefined) {\n return null;\n }\n\n return now + resetAfterSeconds * 1000;\n};\n\nexport const formatDuration = (seconds: number): string => {\n if (seconds <= 0) {\n return '0s';\n }\n\n const weeks = Math.floor(seconds / 604800);\n const days = Math.floor((seconds % 604800) / 86400);\n const hours = Math.floor((seconds % 86400) / 3600);\n const minutes = Math.floor((seconds % 3600) / 60);\n const secs = seconds % 60;\n\n const parts: string[] = [];\n if (weeks > 0) parts.push(`${weeks}w`);\n if (days > 0) parts.push(`${days}d`);\n if (hours > 0) parts.push(`${hours}h`);\n if (minutes > 0) parts.push(`${minutes}m`);\n if (secs > 0 || parts.length === 0) parts.push(`${secs}s`);\n\n return parts.join(' ');\n};\n\nexport const formatResetAt = (resetAtMs: number): string => {\n return new Date(resetAtMs).toLocaleString(undefined, {\n weekday: 'long',\n year: 'numeric',\n month: 'long',\n day: 'numeric',\n hour: 'numeric',\n minute: 'numeric',\n second: 'numeric',\n timeZoneName: 'short',\n });\n};\n", "import { readFile } from 'node:fs/promises';\nimport { homedir } from 'node:os';\nimport { join } from 'node:path';\n\nimport type { Logger } from './logger.ts';\nimport type { OpenCodeAuth } from '../../types.ts';\n\nexport const xdgDataHome = (): string =>\n process.env.XDG_DATA_HOME ?? join(homedir(), '.local', 'share');\n\nexport const xdgConfigHome = (): string =>\n process.env.XDG_CONFIG_HOME ?? join(homedir(), '.config');\n\nexport const AUTH_PATHS = {\n opencode: (): string => join(xdgDataHome(), 'opencode', 'auth.json'),\n openaiPlugin: (): string => join(homedir(), '.opencode', 'auth', 'openai.json'),\n antigravityConfig: (): string => join(xdgConfigHome(), 'opencode', 'antigravity-accounts.json'),\n antigravityData: (): string => join(xdgDataHome(), 'opencode', 'antigravity-accounts.json'),\n} as const;\n\nexport const readJson = async <T>(filePath: string, logger?: Logger): Promise<T | null> => {\n try {\n const content = await readFile(filePath, 'utf-8');\n return JSON.parse(content) as T;\n } catch (error) {\n if (logger) {\n const message = error instanceof Error ? error.message : String(error);\n await logger.debug(`Auth file not found or invalid: ${filePath}`, { error: message });\n }\n return null;\n }\n};\n\nexport const loadOpenCodeAuth = async (logger?: Logger): Promise<OpenCodeAuth | null> => {\n return readJson<OpenCodeAuth>(AUTH_PATHS.opencode(), logger);\n};\n", "import type { ProviderAlias, ProviderId } from '../../types.ts';\n\nexport const PROVIDER_ALIASES: Record<ProviderId, ProviderAlias[]> = {\n openai: ['openai', 'codex', 'chatgpt'],\n google: ['google', 'antigravity'],\n 'zai-coding-plan': ['zai-coding-plan', 'zai', 'z.ai'],\n};\n\nexport const parseProvider = (input?: string): ProviderId | null => {\n if (!input) {\n return null;\n }\n\n const normalized = input.trim().toLowerCase();\n for (const [providerId, aliases] of Object.entries(PROVIDER_ALIASES)) {\n if (aliases.includes(normalized as ProviderAlias)) {\n return providerId as ProviderId;\n }\n }\n\n return null;\n};\n\nexport const getProviderAliases = (provider: ProviderId): ProviderAlias[] => {\n return PROVIDER_ALIASES[provider];\n};\n", "import type {\n AntigravityAccount,\n AntigravityAccountsFile,\n OpenCodeAuth,\n ProviderAuthData,\n} from '../../types.ts';\nimport type { Logger } from '../common/logger.ts';\nimport { AUTH_PATHS, loadOpenCodeAuth, readJson } from '../common/files.ts';\nimport { getProviderAliases } from '../common/registry.ts';\n\nexport interface GoogleAuthContext {\n refreshToken?: string;\n accessToken?: string;\n expires?: number;\n projectId?: string;\n email?: string;\n}\n\nconst toAuthData = (entry: OpenCodeAuth[string]): ProviderAuthData | null => {\n if (!entry) {\n return null;\n }\n\n if (typeof entry === 'string') {\n return { token: entry };\n }\n\n if (typeof entry === 'object') {\n return entry as ProviderAuthData;\n }\n\n return null;\n};\n\nconst loadOpenCodeAuthEntry = async (logger?: Logger): Promise<ProviderAuthData | null> => {\n const auth = await loadOpenCodeAuth(logger);\n if (!auth) {\n return null;\n }\n\n for (const alias of getProviderAliases('google')) {\n const entry = toAuthData(auth[alias]);\n if (entry) {\n return entry;\n }\n }\n\n return null;\n};\n\nconst toAuthContext = (entry: ProviderAuthData | null): GoogleAuthContext | null => {\n if (!entry) {\n return null;\n }\n\n const accessToken = entry.access ?? entry.token;\n let refreshToken = entry.refresh;\n let projectId: string | undefined = undefined;\n\n if (refreshToken && refreshToken.includes('|')) {\n const parts = refreshToken.split('|');\n refreshToken = parts[0];\n projectId = parts[1];\n }\n\n if (!accessToken && !refreshToken) {\n return null;\n }\n\n return {\n accessToken,\n refreshToken,\n expires: entry.expires,\n projectId,\n };\n};\n\nconst selectAccount = (accounts: AntigravityAccountsFile | null): AntigravityAccount | null => {\n if (!accounts?.accounts?.length) {\n return null;\n }\n\n const candidateIndex = accounts.activeIndex ?? 0;\n const account = accounts.accounts[candidateIndex] ?? accounts.accounts[0];\n return account ?? null;\n};\n\nconst loadAuthFromAccounts = async (logger?: Logger): Promise<GoogleAuthContext | null> => {\n const configAccounts = await readJson<AntigravityAccountsFile>(\n AUTH_PATHS.antigravityConfig(),\n logger\n );\n const account = selectAccount(configAccounts);\n if (account) {\n return {\n refreshToken: account.refreshToken,\n projectId: account.projectId ?? account.managedProjectId,\n email: account.email,\n };\n }\n\n const dataAccounts = await readJson<AntigravityAccountsFile>(\n AUTH_PATHS.antigravityData(),\n logger\n );\n const fallbackAccount = selectAccount(dataAccounts);\n if (!fallbackAccount) {\n return null;\n }\n\n return {\n refreshToken: fallbackAccount.refreshToken,\n projectId: fallbackAccount.projectId ?? fallbackAccount.managedProjectId,\n email: fallbackAccount.email,\n };\n};\n\nexport const getGoogleAuth = async (logger?: Logger): Promise<GoogleAuthContext | null> => {\n const openCodeAuth = await loadOpenCodeAuthEntry(logger);\n const authContext = toAuthContext(openCodeAuth);\n if (authContext) {\n return authContext;\n }\n\n return loadAuthFromAccounts(logger);\n};\n", "import type { ProviderResult, ProviderUsage, UsageWindow } from '../../types.ts';\nimport { maskSecret, type Logger, noopLogger } from '../common/logger.ts';\nimport { calculateResetAfterSeconds, formatDuration, formatResetAt } from '../common/time.ts';\nimport { getGoogleAuth } from './auth.ts';\n\nconst GOOGLE_CLIENT_ID =\n '1071006060591-tmhssin2h21lcre235vtolojh4g403ep.apps.googleusercontent.com';\nconst GOOGLE_CLIENT_SECRET = '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';\nconst DEFAULT_PROJECT_ID = 'rising-fact-p41fc';\nconst WINDOW_SECONDS = 5 * 60 * 60;\n\nconst ENDPOINTS: readonly string[] = [\n 'https://daily-cloudcode-pa.sandbox.googleapis.com',\n 'https://autopush-cloudcode-pa.sandbox.googleapis.com',\n 'https://cloudcode-pa.googleapis.com',\n];\n\nconst HEADERS = {\n 'User-Agent': 'antigravity/1.11.5 windows/amd64',\n 'X-Goog-Api-Client': 'google-cloud-sdk vscode_cloudshelleditor/0.1',\n 'Client-Metadata':\n '{\"ideType\":\"IDE_UNSPECIFIED\",\"platform\":\"PLATFORM_UNSPECIFIED\",\"pluginType\":\"GEMINI\"}',\n} as const;\n\ninterface TokenResponse {\n access_token: string;\n expires_in?: number;\n}\n\ninterface ModelUsageInfoResponse {\n displayName?: string;\n quotaInfo?: {\n remainingFraction?: number;\n resetTime?: string;\n };\n}\n\ninterface ModelsResponse {\n models?: Record<string, ModelUsageInfoResponse>;\n}\n\nconst refreshAccessToken = async (\n refreshToken: string,\n logger: Logger\n): Promise<TokenResponse | null> => {\n try {\n const response = await fetch('https://oauth2.googleapis.com/token', {\n method: 'POST',\n headers: { 'Content-Type': 'application/x-www-form-urlencoded' },\n body: new URLSearchParams({\n client_id: GOOGLE_CLIENT_ID,\n client_secret: GOOGLE_CLIENT_SECRET,\n refresh_token: refreshToken,\n grant_type: 'refresh_token',\n }),\n });\n\n if (!response.ok) {\n await logger.warn('Failed to refresh OAuth token for google', {\n status: response.status,\n token: maskSecret(refreshToken),\n });\n return null;\n }\n\n return (await response.json()) as TokenResponse;\n } catch (error) {\n const message = error instanceof Error ? error.message : String(error);\n await logger.warn(`Token refresh failed for google: ${message}`);\n return null;\n }\n};\n\nconst fetchModels = async (\n accessToken: string,\n projectId: string | undefined,\n logger: Logger\n): Promise<ModelsResponse | null> => {\n const body = projectId ? { project: projectId } : {};\n\n for (const endpoint of ENDPOINTS) {\n try {\n const response = await fetch(`${endpoint}/v1internal:fetchAvailableModels`, {\n method: 'POST',\n headers: {\n Authorization: `Bearer ${accessToken}`,\n 'Content-Type': 'application/json',\n ...HEADERS,\n },\n body: JSON.stringify(body),\n signal: AbortSignal.timeout(15000),\n });\n\n if (response.ok) {\n await logger.debug(`Fetched models from ${endpoint}`, { projectId });\n return (await response.json()) as ModelsResponse;\n }\n } catch {\n continue;\n }\n }\n\n await logger.error('Failed to fetch models from all google endpoints', { projectId });\n return null;\n};\n\nconst toWindow = (remainingFraction?: number, resetTime?: string): UsageWindow => {\n const remainingPercent =\n remainingFraction !== undefined ? Math.round(remainingFraction * 100) : null;\n const usedPercent = remainingPercent !== null ? Math.max(0, 100 - remainingPercent) : null;\n const resetAt = resetTime ? new Date(resetTime).getTime() : null;\n const resetAfterSeconds = calculateResetAfterSeconds(resetAt);\n\n return {\n usedPercent,\n remainingPercent,\n windowSeconds: WINDOW_SECONDS,\n resetAfterSeconds,\n resetAt,\n resetAtFormatted: resetAt ? formatResetAt(resetAt) : null,\n resetAfterFormatted: resetAfterSeconds !== null ? formatDuration(resetAfterSeconds) : null,\n };\n};\n\nconst buildUsage = (data: ModelsResponse): ProviderUsage => {\n const models: Record<string, { windows: Record<string, UsageWindow> }> = {};\n\n for (const [modelName, modelData] of Object.entries(data.models ?? {})) {\n const window = toWindow(modelData.quotaInfo?.remainingFraction, modelData.quotaInfo?.resetTime);\n models[modelName] = {\n windows: {\n '5h': window,\n },\n };\n }\n\n return {\n windows: {},\n models: Object.keys(models).length ? models : undefined,\n };\n};\n\nconst resolveAccessToken = async (\n refreshToken: string | undefined,\n accessToken: string | undefined,\n expires: number | undefined,\n logger: Logger\n): Promise<string | null> => {\n const now = Date.now();\n\n if (accessToken && (!expires || expires > now)) {\n return accessToken;\n }\n\n if (!refreshToken) {\n return null;\n }\n\n const refreshed = await refreshAccessToken(refreshToken, logger);\n return refreshed?.access_token ?? null;\n};\n\nexport const fetchGoogleUsage = async (logger: Logger = noopLogger): Promise<ProviderResult> => {\n const auth = await getGoogleAuth(logger);\n\n if (!auth) {\n await logger.warn('No auth configured for google');\n return {\n provider: 'google',\n ok: false,\n configured: false,\n error: 'Not configured - no accounts found',\n usage: null,\n };\n }\n\n const accessToken = await resolveAccessToken(\n auth.refreshToken,\n auth.accessToken,\n auth.expires,\n logger\n );\n\n if (!accessToken) {\n await logger.warn('Failed to refresh OAuth token for google', { email: auth.email });\n return {\n provider: 'google',\n ok: false,\n configured: true,\n error: 'Failed to refresh OAuth token',\n usage: null,\n };\n }\n\n const projectId = auth.projectId ?? DEFAULT_PROJECT_ID;\n const modelsData = await fetchModels(accessToken, projectId, logger);\n\n if (!modelsData) {\n await logger.error('Failed to fetch models from google API', { projectId });\n return {\n provider: 'google',\n ok: false,\n configured: true,\n error: 'Failed to fetch models from API',\n usage: null,\n };\n }\n\n await logger.info('google usage fetched successfully');\n\n return {\n provider: 'google',\n ok: true,\n configured: true,\n usage: buildUsage(modelsData),\n };\n};\n", "import type { Logger } from '../common/logger.ts';\nimport type { OpenCodeAuth, ProviderAuthData } from '../../types.ts';\nimport { AUTH_PATHS, loadOpenCodeAuth, readJson } from '../common/files.ts';\nimport { getProviderAliases } from '../common/registry.ts';\n\nconst toAuthData = (entry: OpenCodeAuth[string]): ProviderAuthData | null => {\n if (!entry) {\n return null;\n }\n\n if (typeof entry === 'string') {\n return { token: entry };\n }\n\n if (typeof entry === 'object') {\n return entry as ProviderAuthData;\n }\n\n return null;\n};\n\nconst hasAccessToken = (auth: ProviderAuthData | null): auth is ProviderAuthData => {\n return Boolean(auth?.access || auth?.token);\n};\n\nconst loadOpenCodeAuthEntry = async (logger?: Logger): Promise<ProviderAuthData | null> => {\n const auth = await loadOpenCodeAuth(logger);\n if (!auth) {\n return null;\n }\n\n for (const alias of getProviderAliases('openai')) {\n const entry = toAuthData(auth[alias]);\n if (entry && hasAccessToken(entry)) {\n return entry;\n }\n }\n\n return null;\n};\n\nexport const getOpenaiAuth = async (logger?: Logger): Promise<ProviderAuthData | null> => {\n const openCodeAuth = await loadOpenCodeAuthEntry(logger);\n if (openCodeAuth && hasAccessToken(openCodeAuth)) {\n return openCodeAuth;\n }\n\n const pluginAuth = await readJson<ProviderAuthData>(AUTH_PATHS.openaiPlugin(), logger);\n if (pluginAuth && hasAccessToken(pluginAuth)) {\n return pluginAuth;\n }\n\n return null;\n};\n", "import type { ProviderResult, ProviderUsage, UsageWindow } from '../../types.ts';\nimport { maskSecret, type Logger, noopLogger } from '../common/logger.ts';\nimport { calculateResetAfterSeconds, formatDuration, formatResetAt } from '../common/time.ts';\nimport { getOpenaiAuth } from './auth.ts';\n\ninterface OpenaiBackendWindow {\n used_percent: number;\n limit_window_seconds: number;\n reset_after_seconds: number;\n reset_at: number;\n}\n\ninterface OpenaiBackendResponse {\n plan_type: string;\n rate_limit: {\n allowed: boolean;\n limit_reached: boolean;\n primary_window?: OpenaiBackendWindow;\n secondary_window?: OpenaiBackendWindow;\n };\n}\n\nconst toWindow = (window?: OpenaiBackendWindow): UsageWindow | null => {\n if (!window) {\n return null;\n }\n\n const usedPercent = window.used_percent;\n const resetAt = window.reset_at ? window.reset_at * 1000 : null;\n const resetAfterSeconds = window.reset_after_seconds ?? calculateResetAfterSeconds(resetAt);\n\n return {\n usedPercent,\n remainingPercent: Math.max(0, 100 - usedPercent),\n windowSeconds: window.limit_window_seconds ?? null,\n resetAfterSeconds,\n resetAt,\n resetAtFormatted: resetAt ? formatResetAt(resetAt) : null,\n resetAfterFormatted: resetAfterSeconds !== null ? formatDuration(resetAfterSeconds) : null,\n };\n};\n\nexport const fetchOpenaiUsage = async (logger: Logger = noopLogger): Promise<ProviderResult> => {\n const auth = await getOpenaiAuth(logger);\n\n if (!auth) {\n await logger.warn('No auth configured for openai');\n return {\n provider: 'openai',\n ok: false,\n configured: false,\n error: 'Not configured - no OAuth token found',\n usage: null,\n };\n }\n\n const accessToken = auth.access ?? auth.token;\n if (!accessToken) {\n await logger.warn('Auth configured but access token missing for openai');\n return {\n provider: 'openai',\n ok: false,\n configured: false,\n error: 'Not configured - access token missing',\n usage: null,\n };\n }\n\n try {\n const response = await fetch('https://chatgpt.com/backend-api/wham/usage', {\n method: 'GET',\n headers: {\n Authorization: `Bearer ${accessToken}`,\n 'Content-Type': 'application/json',\n },\n });\n\n if (!response.ok) {\n await logger.error(`API error ${response.status} for openai`, {\n token: maskSecret(accessToken),\n });\n return {\n provider: 'openai',\n ok: false,\n configured: true,\n error: `API error: ${response.status}`,\n usage: null,\n };\n }\n\n const payload = (await response.json()) as OpenaiBackendResponse;\n const primary = toWindow(payload.rate_limit.primary_window);\n const secondary = toWindow(payload.rate_limit.secondary_window);\n\n const windows: Record<string, UsageWindow> = {};\n if (primary) {\n windows['5h'] = primary;\n }\n if (secondary) {\n windows['weekly'] = secondary;\n }\n\n const usage: ProviderUsage = {\n windows,\n };\n\n await logger.info('openai usage fetched successfully');\n\n return {\n provider: 'openai',\n ok: true,\n configured: true,\n usage,\n };\n } catch (error) {\n const message = error instanceof Error ? error.message : String(error);\n await logger.error(`Request failed for openai: ${message}`);\n return {\n provider: 'openai',\n ok: false,\n configured: true,\n error: `Request failed: ${message}`,\n usage: null,\n };\n }\n};\n", "import type { Logger } from '../common/logger.ts';\nimport type { OpenCodeAuth } from '../../types.ts';\nimport { loadOpenCodeAuth } from '../common/files.ts';\nimport { getProviderAliases } from '../common/registry.ts';\n\nconst resolveAuthValue = (entry: OpenCodeAuth[string]): string | null => {\n if (!entry) {\n return null;\n }\n\n if (typeof entry === 'string') {\n return entry;\n }\n\n if (typeof entry === 'object') {\n return entry.api_key ?? entry.token ?? entry.key ?? null;\n }\n\n return null;\n};\n\nexport const getZaiApiKey = async (logger?: Logger): Promise<string | null> => {\n if (process.env.ZAI_API_KEY) {\n return process.env.ZAI_API_KEY;\n }\n\n const auth = await loadOpenCodeAuth(logger);\n if (!auth) {\n return null;\n }\n\n for (const alias of getProviderAliases('zai-coding-plan')) {\n const value = resolveAuthValue(auth[alias]);\n if (value) {\n return value;\n }\n }\n\n return null;\n};\n", "import type { ProviderResult, ProviderUsage, UsageWindow } from '../../types.ts';\nimport { maskSecret, type Logger, noopLogger } from '../common/logger.ts';\nimport { calculateResetAfterSeconds, formatDuration, formatResetAt } from '../common/time.ts';\nimport { getZaiApiKey } from './auth.ts';\n\ninterface ZaiLimit {\n type: 'TIME_LIMIT' | 'TOKENS_LIMIT';\n unit: number;\n number: number;\n usage: number;\n currentValue: number;\n remaining: number;\n percentage: number;\n nextResetTime?: number;\n}\n\ninterface ZaiUsageResponse {\n code: number;\n msg: string;\n data?: {\n limits?: ZaiLimit[];\n };\n success: boolean;\n}\n\nconst normalizeTimestamp = (value: number): number => {\n return value < 1_000_000_000_000 ? value * 1000 : value;\n};\n\nconst TOKEN_WINDOW_SECONDS: Record<number, number> = {\n 3: 3600,\n};\n\nconst resolveWindowSeconds = (limit?: ZaiLimit): number | null => {\n if (!limit) {\n return null;\n }\n\n if (!limit.number) {\n return null;\n }\n\n const unitSeconds = TOKEN_WINDOW_SECONDS[limit.unit];\n if (!unitSeconds) {\n return null;\n }\n\n return unitSeconds * limit.number;\n};\n\nconst resolveWindowLabel = (windowSeconds: number | null): string => {\n if (!windowSeconds) {\n return 'tokens';\n }\n\n if (windowSeconds % 86400 === 0) {\n const days = windowSeconds / 86400;\n return days === 7 ? 'weekly' : `${days}d`;\n }\n\n if (windowSeconds % 3600 === 0) {\n return `${windowSeconds / 3600}h`;\n }\n\n return `${windowSeconds}s`;\n};\n\nconst toWindow = (limit?: ZaiLimit): UsageWindow | null => {\n if (!limit) {\n return null;\n }\n\n const usedPercent = limit.percentage ?? null;\n const remainingPercent = usedPercent !== null ? Math.max(0, 100 - usedPercent) : null;\n const resetAt = limit.nextResetTime ? normalizeTimestamp(limit.nextResetTime) : null;\n const resetAfterSeconds = calculateResetAfterSeconds(resetAt);\n\n return {\n usedPercent,\n remainingPercent,\n windowSeconds: resolveWindowSeconds(limit),\n resetAfterSeconds,\n resetAt,\n resetAtFormatted: resetAt ? formatResetAt(resetAt) : null,\n resetAfterFormatted: resetAfterSeconds !== null ? formatDuration(resetAfterSeconds) : null,\n };\n};\n\nexport const fetchZaiUsage = async (logger: Logger = noopLogger): Promise<ProviderResult> => {\n const apiKey = await getZaiApiKey(logger);\n\n if (!apiKey) {\n await logger.warn('No auth configured for zai-coding-plan');\n return {\n provider: 'zai-coding-plan',\n ok: false,\n configured: false,\n error: 'Not configured - no API key found',\n usage: null,\n };\n }\n\n try {\n const response = await fetch('https://api.z.ai/api/monitor/usage/quota/limit', {\n method: 'GET',\n headers: {\n Authorization: `Bearer ${apiKey}`,\n 'Content-Type': 'application/json',\n },\n });\n\n if (!response.ok) {\n await logger.error(`API error ${response.status} for zai-coding-plan`, {\n token: maskSecret(apiKey),\n });\n return {\n provider: 'zai-coding-plan',\n ok: false,\n configured: true,\n error: `API error: ${response.status}`,\n usage: null,\n };\n }\n\n const payload = (await response.json()) as ZaiUsageResponse;\n const limits = payload.data?.limits ?? [];\n const tokensLimit = limits.find((limit) => limit.type === 'TOKENS_LIMIT');\n\n const windows: Record<string, UsageWindow> = {};\n const window = toWindow(tokensLimit);\n if (window) {\n const label = resolveWindowLabel(window.windowSeconds);\n windows[label] = window;\n }\n\n const usage: ProviderUsage = {\n windows,\n };\n\n await logger.info('zai-coding-plan usage fetched successfully');\n\n return {\n provider: 'zai-coding-plan',\n ok: true,\n configured: true,\n usage,\n };\n } catch (error) {\n const message = error instanceof Error ? error.message : String(error);\n await logger.error(`Request failed for zai-coding-plan: ${message}`);\n return {\n provider: 'zai-coding-plan',\n ok: false,\n configured: true,\n error: `Request failed: ${message}`,\n usage: null,\n };\n }\n};\n", "export type ProviderId = 'openai' | 'google' | 'zai-coding-plan';\n\nexport type ProviderAlias = ProviderId | 'codex' | 'antigravity' | 'zai' | 'z.ai' | 'chatgpt';\n\nexport const PROVIDERS: ProviderId[] = ['openai', 'google', 'zai-coding-plan'];\n\nexport interface UsageWindow {\n usedPercent: number | null;\n remainingPercent: number | null;\n windowSeconds: number | null;\n resetAfterSeconds: number | null;\n resetAt: number | null;\n resetAtFormatted: string | null;\n resetAfterFormatted: string | null;\n}\n\nexport interface UsageWindows {\n windows: Record<string, UsageWindow>;\n}\n\nexport interface ProviderUsage extends UsageWindows {\n models?: Record<string, UsageWindows>;\n}\n\nexport interface ProviderResult {\n provider: ProviderId;\n ok: boolean;\n configured: boolean;\n error?: string;\n usage: ProviderUsage | null;\n}\n\nexport type OpenCodeAuth = Record<string, string | ProviderAuthData>;\n\nexport interface ProviderAuthData {\n type?: 'oauth' | 'api' | string;\n access?: string;\n refresh?: string;\n expires?: number;\n api_key?: string;\n token?: string;\n key?: string;\n accountId?: string;\n}\n\nexport interface AntigravityAccount {\n email: string;\n refreshToken: string;\n projectId?: string;\n addedAt: number | string;\n lastUsed?: number;\n rateLimitResetTimes?: Record<string, number>;\n managedProjectId?: string;\n}\n\nexport interface AntigravityAccountsFile {\n version?: number;\n accounts: AntigravityAccount[];\n activeIndex?: number;\n activeIndexByFamily?: Record<string, number>;\n}\n"],
"mappings": "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",
"names": ["readFile", "toAuthData", "loadOpenCodeAuthEntry", "toWindow", "toWindow", "readFile"]
"sources": ["../src/index.ts", "../src/providers/common/logger.ts", "../src/providers/common/time.ts", "../src/providers/common/files.ts", "../src/providers/common/registry.ts", "../src/providers/google/auth.ts", "../src/providers/google/fetch.ts", "../src/providers/openai/auth.ts", "../src/providers/openai/fetch.ts", "../src/providers/zai-coding-plan/auth.ts", "../src/providers/zai-coding-plan/fetch.ts", "../src/types/provider.ts", "../src/toast/filter.ts", "../src/toast/format.ts"],
"sourcesContent": ["import type { Plugin } from '@opencode-ai/plugin';\nimport { tool } from '@opencode-ai/plugin';\nimport { createLogger, type Logger } from './providers/common/logger.ts';\nimport { fetchGoogleUsage } from './providers/google/fetch.ts';\nimport { fetchOpenaiUsage } from './providers/openai/fetch.ts';\nimport { fetchZaiUsage } from './providers/zai-coding-plan/fetch.ts';\nimport { PROVIDERS, type ProviderId, type ProviderResult } from './types/index.ts';\nimport { formatUsageToast } from './toast/format.js';\n\nconst fetchUsage = async (provider: ProviderId, logger: Logger): Promise<ProviderResult> => {\n switch (provider) {\n case 'openai':\n return fetchOpenaiUsage(logger);\n case 'google':\n return fetchGoogleUsage(logger);\n case 'zai-coding-plan':\n return fetchZaiUsage(logger);\n }\n};\n\nexport const UsagePlugin: Plugin = async ({ client }) => {\n const logger = createLogger(client);\n\n const usageToastTool = tool({\n description: 'Show subscription usage as toast for OpenAI, Google, and z.ai providers',\n args: {},\n async execute() {\n await logger.info('Fetching usage for all providers');\n\n const results = await Promise.all(PROVIDERS.map((provider) => fetchUsage(provider, logger)));\n\n const toast = formatUsageToast(results);\n\n await client.tui.showToast({\n body: {\n title: toast.title,\n message: toast.message,\n variant: toast.variant,\n },\n });\n\n return 'Usage displayed';\n },\n });\n\n return {\n tool: {\n usage_toast: usageToastTool,\n },\n async config(config) {\n config.command = config.command ?? {};\n\n config.command.usage = {\n template: 'Call the usage_toast tool.',\n description: 'Show subscription usage for OpenAI, Google, and z.ai providers',\n };\n },\n };\n};\n\nexport default UsagePlugin;\n", "export type LogLevel = 'debug' | 'info' | 'warn' | 'error';\n\nexport interface Logger {\n debug: (message: string, extra?: Record<string, unknown>) => Promise<void>;\n info: (message: string, extra?: Record<string, unknown>) => Promise<void>;\n warn: (message: string, extra?: Record<string, unknown>) => Promise<void>;\n error: (message: string, extra?: Record<string, unknown>) => Promise<void>;\n}\n\nexport const maskSecret = (secret: string): string => {\n if (!secret || typeof secret !== 'string' || secret.length <= 8) {\n return '***';\n }\n return `${secret.slice(0, 4)}...${secret.slice(-4)}`;\n};\n\nconst noOpLogger = {\n debug: async () => {},\n info: async () => {},\n warn: async () => {},\n error: async () => {},\n};\n\ninterface LogOptions {\n service: string;\n level: LogLevel;\n message: string;\n}\n\ninterface OpenCodeClient {\n app: {\n log: (options: LogOptions) => Promise<boolean> | { ok: boolean };\n };\n}\n\nexport const createLogger = (client: unknown): Logger => {\n const service = 'opencode-usage';\n\n return {\n debug: async (message, extra) => {\n await (client as OpenCodeClient).app.log({\n service,\n level: 'debug',\n message,\n ...(extra ?? {}),\n });\n },\n info: async (message, extra) => {\n await (client as OpenCodeClient).app.log({\n service,\n level: 'info',\n message,\n ...(extra ?? {}),\n });\n },\n warn: async (message, extra) => {\n await (client as OpenCodeClient).app.log({\n service,\n level: 'warn',\n message,\n ...(extra ?? {}),\n });\n },\n error: async (message, extra) => {\n await (client as OpenCodeClient).app.log({\n service,\n level: 'error',\n message,\n ...(extra ?? {}),\n });\n },\n };\n};\n\nexport const noopLogger = noOpLogger as unknown as Logger;\n", "export const calculateResetAfterSeconds = (\n resetAt: number | null,\n now: number = Date.now()\n): number | null => {\n if (!resetAt) {\n return null;\n }\n\n const diffMs = resetAt - now;\n if (diffMs <= 0) {\n return 0;\n }\n\n return Math.floor(diffMs / 1000);\n};\n\nexport const calculateResetAt = (\n resetAfterSeconds: number | null,\n now: number = Date.now()\n): number | null => {\n if (resetAfterSeconds === null || resetAfterSeconds === undefined) {\n return null;\n }\n\n return now + resetAfterSeconds * 1000;\n};\n\nexport const formatDuration = (seconds: number): string => {\n if (seconds <= 0) {\n return '0s';\n }\n\n const weeks = Math.floor(seconds / 604800);\n const days = Math.floor((seconds % 604800) / 86400);\n const hours = Math.floor((seconds % 86400) / 3600);\n const minutes = Math.floor((seconds % 3600) / 60);\n const secs = seconds % 60;\n\n const parts: string[] = [];\n if (weeks > 0) parts.push(`${weeks}w`);\n if (days > 0) parts.push(`${days}d`);\n if (hours > 0) parts.push(`${hours}h`);\n if (minutes > 0) parts.push(`${minutes}m`);\n if (secs > 0 || parts.length === 0) parts.push(`${secs}s`);\n\n return parts.join(' ');\n};\n\nexport const formatResetAt = (resetAtMs: number): string => {\n return new Date(resetAtMs).toLocaleString(undefined, {\n weekday: 'long',\n year: 'numeric',\n month: 'long',\n day: 'numeric',\n hour: 'numeric',\n minute: 'numeric',\n second: 'numeric',\n timeZoneName: 'short',\n });\n};\n", "import { readFile } from 'node:fs/promises';\nimport { homedir } from 'node:os';\nimport { join } from 'node:path';\n\nimport type { Logger } from './logger.ts';\nimport type { OpenCodeAuth } from '../../types/index.ts';\n\nexport const xdgDataHome = (): string =>\n process.env.XDG_DATA_HOME ?? join(homedir(), '.local', 'share');\n\nexport const xdgConfigHome = (): string =>\n process.env.XDG_CONFIG_HOME ?? join(homedir(), '.config');\n\nexport const AUTH_PATHS = {\n opencode: (): string => join(xdgDataHome(), 'opencode', 'auth.json'),\n openaiPlugin: (): string => join(homedir(), '.opencode', 'auth', 'openai.json'),\n antigravityConfig: (): string => join(xdgConfigHome(), 'opencode', 'antigravity-accounts.json'),\n antigravityData: (): string => join(xdgDataHome(), 'opencode', 'antigravity-accounts.json'),\n} as const;\n\nexport const readJson = async <T>(filePath: string, logger?: Logger): Promise<T | null> => {\n try {\n const content = await readFile(filePath, 'utf-8');\n return JSON.parse(content) as T;\n } catch (error) {\n if (logger) {\n const message = error instanceof Error ? error.message : String(error);\n await logger.debug(`Auth file not found or invalid: ${filePath}`, { error: message });\n }\n return null;\n }\n};\n\nexport const loadOpenCodeAuth = async (logger?: Logger): Promise<OpenCodeAuth | null> => {\n return readJson<OpenCodeAuth>(AUTH_PATHS.opencode(), logger);\n};\n", "import type { ProviderAlias, ProviderId } from '../../types/index.ts';\n\nexport const PROVIDER_ALIASES: Record<ProviderId, ProviderAlias[]> = {\n openai: ['openai', 'codex', 'chatgpt'],\n google: ['google', 'antigravity'],\n 'zai-coding-plan': ['zai-coding-plan', 'zai', 'z.ai'],\n};\n\nexport const parseProvider = (input?: string): ProviderId | null => {\n if (!input) {\n return null;\n }\n\n const normalized = input.trim().toLowerCase();\n for (const [providerId, aliases] of Object.entries(PROVIDER_ALIASES)) {\n if (aliases.includes(normalized as ProviderAlias)) {\n return providerId as ProviderId;\n }\n }\n\n return null;\n};\n\nexport const getProviderAliases = (provider: ProviderId): ProviderAlias[] => {\n return PROVIDER_ALIASES[provider];\n};\n", "import type {\n AntigravityAccount,\n AntigravityAccountsFile,\n OpenCodeAuth,\n ProviderAuthData,\n} from '../../types/index.ts';\nimport type { Logger } from '../common/logger.ts';\nimport { AUTH_PATHS, loadOpenCodeAuth, readJson } from '../common/files.ts';\nimport { getProviderAliases } from '../common/registry.ts';\n\nexport interface GoogleAuthContext {\n refreshToken?: string;\n accessToken?: string;\n expires?: number;\n projectId?: string;\n email?: string;\n}\n\nconst toAuthData = (entry: OpenCodeAuth[string]): ProviderAuthData | null => {\n if (!entry) {\n return null;\n }\n\n if (typeof entry === 'string') {\n return { token: entry };\n }\n\n if (typeof entry === 'object') {\n return entry as ProviderAuthData;\n }\n\n return null;\n};\n\nconst loadOpenCodeAuthEntry = async (logger?: Logger): Promise<ProviderAuthData | null> => {\n const auth = await loadOpenCodeAuth(logger);\n if (!auth) {\n return null;\n }\n\n for (const alias of getProviderAliases('google')) {\n const entry = toAuthData(auth[alias]);\n if (entry) {\n return entry;\n }\n }\n\n return null;\n};\n\nconst toAuthContext = (entry: ProviderAuthData | null): GoogleAuthContext | null => {\n if (!entry) {\n return null;\n }\n\n const accessToken = entry.access ?? entry.token;\n let refreshToken = entry.refresh;\n let projectId: string | undefined = undefined;\n\n if (refreshToken && refreshToken.includes('|')) {\n const parts = refreshToken.split('|');\n refreshToken = parts[0];\n projectId = parts[1];\n }\n\n if (!accessToken && !refreshToken) {\n return null;\n }\n\n return {\n accessToken,\n refreshToken,\n expires: entry.expires,\n projectId,\n };\n};\n\nconst selectAccount = (accounts: AntigravityAccountsFile | null): AntigravityAccount | null => {\n if (!accounts?.accounts?.length) {\n return null;\n }\n\n const candidateIndex = accounts.activeIndex ?? 0;\n const account = accounts.accounts[candidateIndex] ?? accounts.accounts[0];\n return account ?? null;\n};\n\nconst loadAuthFromAccounts = async (logger?: Logger): Promise<GoogleAuthContext | null> => {\n const configAccounts = await readJson<AntigravityAccountsFile>(\n AUTH_PATHS.antigravityConfig(),\n logger\n );\n const account = selectAccount(configAccounts);\n if (account) {\n return {\n refreshToken: account.refreshToken,\n projectId: account.projectId ?? account.managedProjectId,\n email: account.email,\n };\n }\n\n const dataAccounts = await readJson<AntigravityAccountsFile>(\n AUTH_PATHS.antigravityData(),\n logger\n );\n const fallbackAccount = selectAccount(dataAccounts);\n if (!fallbackAccount) {\n return null;\n }\n\n return {\n refreshToken: fallbackAccount.refreshToken,\n projectId: fallbackAccount.projectId ?? fallbackAccount.managedProjectId,\n email: fallbackAccount.email,\n };\n};\n\nexport const getGoogleAuth = async (logger?: Logger): Promise<GoogleAuthContext | null> => {\n const openCodeAuth = await loadOpenCodeAuthEntry(logger);\n const authContext = toAuthContext(openCodeAuth);\n if (authContext) {\n return authContext;\n }\n\n return loadAuthFromAccounts(logger);\n};\n", "import type { ProviderResult, ProviderUsage, UsageWindow } from '../../types/index.ts';\nimport { maskSecret, type Logger, noopLogger } from '../common/logger.ts';\nimport { calculateResetAfterSeconds, formatDuration, formatResetAt } from '../common/time.ts';\nimport { getGoogleAuth } from './auth.ts';\n\nconst GOOGLE_CLIENT_ID =\n '1071006060591-tmhssin2h21lcre235vtolojh4g403ep.apps.googleusercontent.com';\nconst GOOGLE_CLIENT_SECRET = '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';\nconst DEFAULT_PROJECT_ID = 'rising-fact-p41fc';\nconst WINDOW_SECONDS = 5 * 60 * 60;\n\nconst ENDPOINTS: readonly string[] = [\n 'https://daily-cloudcode-pa.sandbox.googleapis.com',\n 'https://autopush-cloudcode-pa.sandbox.googleapis.com',\n 'https://cloudcode-pa.googleapis.com',\n];\n\nconst HEADERS = {\n 'User-Agent': 'antigravity/1.11.5 windows/amd64',\n 'X-Goog-Api-Client': 'google-cloud-sdk vscode_cloudshelleditor/0.1',\n 'Client-Metadata':\n '{\"ideType\":\"IDE_UNSPECIFIED\",\"platform\":\"PLATFORM_UNSPECIFIED\",\"pluginType\":\"GEMINI\"}',\n} as const;\n\ninterface TokenResponse {\n access_token: string;\n expires_in?: number;\n}\n\ninterface ModelUsageInfoResponse {\n displayName?: string;\n quotaInfo?: {\n remainingFraction?: number;\n resetTime?: string;\n };\n}\n\ninterface ModelsResponse {\n models?: Record<string, ModelUsageInfoResponse>;\n}\n\nconst refreshAccessToken = async (\n refreshToken: string,\n logger: Logger\n): Promise<TokenResponse | null> => {\n try {\n const response = await fetch('https://oauth2.googleapis.com/token', {\n method: 'POST',\n headers: { 'Content-Type': 'application/x-www-form-urlencoded' },\n body: new URLSearchParams({\n client_id: GOOGLE_CLIENT_ID,\n client_secret: GOOGLE_CLIENT_SECRET,\n refresh_token: refreshToken,\n grant_type: 'refresh_token',\n }),\n });\n\n if (!response.ok) {\n await logger.warn('Failed to refresh OAuth token for google', {\n status: response.status,\n token: maskSecret(refreshToken),\n });\n return null;\n }\n\n return (await response.json()) as TokenResponse;\n } catch (error) {\n const message = error instanceof Error ? error.message : String(error);\n await logger.warn(`Token refresh failed for google: ${message}`);\n return null;\n }\n};\n\nconst fetchModels = async (\n accessToken: string,\n projectId: string | undefined,\n logger: Logger\n): Promise<ModelsResponse | null> => {\n const body = projectId ? { project: projectId } : {};\n\n for (const endpoint of ENDPOINTS) {\n try {\n const response = await fetch(`${endpoint}/v1internal:fetchAvailableModels`, {\n method: 'POST',\n headers: {\n Authorization: `Bearer ${accessToken}`,\n 'Content-Type': 'application/json',\n ...HEADERS,\n },\n body: JSON.stringify(body),\n signal: AbortSignal.timeout(15000),\n });\n\n if (response.ok) {\n await logger.debug(`Fetched models from ${endpoint}`, { projectId });\n return (await response.json()) as ModelsResponse;\n }\n } catch {\n continue;\n }\n }\n\n await logger.error('Failed to fetch models from all google endpoints', { projectId });\n return null;\n};\n\nconst toWindow = (remainingFraction?: number, resetTime?: string): UsageWindow => {\n const remainingPercent =\n remainingFraction !== undefined ? Math.round(remainingFraction * 100) : null;\n const usedPercent = remainingPercent !== null ? Math.max(0, 100 - remainingPercent) : null;\n const resetAt = resetTime ? new Date(resetTime).getTime() : null;\n const resetAfterSeconds = calculateResetAfterSeconds(resetAt);\n\n return {\n usedPercent,\n remainingPercent,\n windowSeconds: WINDOW_SECONDS,\n resetAfterSeconds,\n resetAt,\n resetAtFormatted: resetAt ? formatResetAt(resetAt) : null,\n resetAfterFormatted: resetAfterSeconds !== null ? formatDuration(resetAfterSeconds) : null,\n };\n};\n\nconst buildUsage = (data: ModelsResponse): ProviderUsage => {\n const models: Record<string, { windows: Record<string, UsageWindow> }> = {};\n\n for (const [modelName, modelData] of Object.entries(data.models ?? {})) {\n const window = toWindow(modelData.quotaInfo?.remainingFraction, modelData.quotaInfo?.resetTime);\n models[modelName] = {\n windows: {\n '5h': window,\n },\n };\n }\n\n return {\n windows: {},\n models: Object.keys(models).length ? models : undefined,\n };\n};\n\nconst resolveAccessToken = async (\n refreshToken: string | undefined,\n accessToken: string | undefined,\n expires: number | undefined,\n logger: Logger\n): Promise<string | null> => {\n const now = Date.now();\n\n if (accessToken && (!expires || expires > now)) {\n return accessToken;\n }\n\n if (!refreshToken) {\n return null;\n }\n\n const refreshed = await refreshAccessToken(refreshToken, logger);\n return refreshed?.access_token ?? null;\n};\n\nexport const fetchGoogleUsage = async (logger: Logger = noopLogger): Promise<ProviderResult> => {\n const auth = await getGoogleAuth(logger);\n\n if (!auth) {\n await logger.warn('No auth configured for google');\n return {\n provider: 'google',\n ok: false,\n configured: false,\n error: 'Not configured - no accounts found',\n usage: null,\n };\n }\n\n const accessToken = await resolveAccessToken(\n auth.refreshToken,\n auth.accessToken,\n auth.expires,\n logger\n );\n\n if (!accessToken) {\n await logger.warn('Failed to refresh OAuth token for google', { email: auth.email });\n return {\n provider: 'google',\n ok: false,\n configured: true,\n error: 'Failed to refresh OAuth token',\n usage: null,\n };\n }\n\n const projectId = auth.projectId ?? DEFAULT_PROJECT_ID;\n const modelsData = await fetchModels(accessToken, projectId, logger);\n\n if (!modelsData) {\n await logger.error('Failed to fetch models from google API', { projectId });\n return {\n provider: 'google',\n ok: false,\n configured: true,\n error: 'Failed to fetch models from API',\n usage: null,\n };\n }\n\n await logger.info('google usage fetched successfully');\n\n return {\n provider: 'google',\n ok: true,\n configured: true,\n usage: buildUsage(modelsData),\n };\n};\n", "import type { Logger } from '../common/logger.ts';\nimport type { OpenCodeAuth, ProviderAuthData } from '../../types/index.ts';\nimport { AUTH_PATHS, loadOpenCodeAuth, readJson } from '../common/files.ts';\nimport { getProviderAliases } from '../common/registry.ts';\n\nconst toAuthData = (entry: OpenCodeAuth[string]): ProviderAuthData | null => {\n if (!entry) {\n return null;\n }\n\n if (typeof entry === 'string') {\n return { token: entry };\n }\n\n if (typeof entry === 'object') {\n return entry as ProviderAuthData;\n }\n\n return null;\n};\n\nconst hasAccessToken = (auth: ProviderAuthData | null): auth is ProviderAuthData => {\n return Boolean(auth?.access || auth?.token);\n};\n\nconst loadOpenCodeAuthEntry = async (logger?: Logger): Promise<ProviderAuthData | null> => {\n const auth = await loadOpenCodeAuth(logger);\n if (!auth) {\n return null;\n }\n\n for (const alias of getProviderAliases('openai')) {\n const entry = toAuthData(auth[alias]);\n if (entry && hasAccessToken(entry)) {\n return entry;\n }\n }\n\n return null;\n};\n\nexport const getOpenaiAuth = async (logger?: Logger): Promise<ProviderAuthData | null> => {\n const openCodeAuth = await loadOpenCodeAuthEntry(logger);\n if (openCodeAuth && hasAccessToken(openCodeAuth)) {\n return openCodeAuth;\n }\n\n const pluginAuth = await readJson<ProviderAuthData>(AUTH_PATHS.openaiPlugin(), logger);\n if (pluginAuth && hasAccessToken(pluginAuth)) {\n return pluginAuth;\n }\n\n return null;\n};\n", "import type { ProviderResult, ProviderUsage, UsageWindow } from '../../types/index.ts';\nimport { maskSecret, type Logger, noopLogger } from '../common/logger.ts';\nimport { calculateResetAfterSeconds, formatDuration, formatResetAt } from '../common/time.ts';\nimport { getOpenaiAuth } from './auth.ts';\n\ninterface OpenaiBackendWindow {\n used_percent: number;\n limit_window_seconds: number;\n reset_after_seconds: number;\n reset_at: number;\n}\n\ninterface OpenaiBackendResponse {\n plan_type: string;\n rate_limit: {\n allowed: boolean;\n limit_reached: boolean;\n primary_window?: OpenaiBackendWindow;\n secondary_window?: OpenaiBackendWindow;\n };\n}\n\nconst toWindow = (window?: OpenaiBackendWindow): UsageWindow | null => {\n if (!window) {\n return null;\n }\n\n const usedPercent = window.used_percent;\n const resetAt = window.reset_at ? window.reset_at * 1000 : null;\n const resetAfterSeconds = window.reset_after_seconds ?? calculateResetAfterSeconds(resetAt);\n\n return {\n usedPercent,\n remainingPercent: Math.max(0, 100 - usedPercent),\n windowSeconds: window.limit_window_seconds ?? null,\n resetAfterSeconds,\n resetAt,\n resetAtFormatted: resetAt ? formatResetAt(resetAt) : null,\n resetAfterFormatted: resetAfterSeconds !== null ? formatDuration(resetAfterSeconds) : null,\n };\n};\n\nexport const fetchOpenaiUsage = async (logger: Logger = noopLogger): Promise<ProviderResult> => {\n const auth = await getOpenaiAuth(logger);\n\n if (!auth) {\n await logger.warn('No auth configured for openai');\n return {\n provider: 'openai',\n ok: false,\n configured: false,\n error: 'Not configured - no OAuth token found',\n usage: null,\n };\n }\n\n const accessToken = auth.access ?? auth.token;\n if (!accessToken) {\n await logger.warn('Auth configured but access token missing for openai');\n return {\n provider: 'openai',\n ok: false,\n configured: false,\n error: 'Not configured - access token missing',\n usage: null,\n };\n }\n\n try {\n const response = await fetch('https://chatgpt.com/backend-api/wham/usage', {\n method: 'GET',\n headers: {\n Authorization: `Bearer ${accessToken}`,\n 'Content-Type': 'application/json',\n },\n });\n\n if (!response.ok) {\n await logger.error(`API error ${response.status} for openai`, {\n token: maskSecret(accessToken),\n });\n return {\n provider: 'openai',\n ok: false,\n configured: true,\n error: `API error: ${response.status}`,\n usage: null,\n };\n }\n\n const payload = (await response.json()) as OpenaiBackendResponse;\n const primary = toWindow(payload.rate_limit.primary_window);\n const secondary = toWindow(payload.rate_limit.secondary_window);\n\n const windows: Record<string, UsageWindow> = {};\n if (primary) {\n windows['5h'] = primary;\n }\n if (secondary) {\n windows['weekly'] = secondary;\n }\n\n const usage: ProviderUsage = {\n windows,\n };\n\n await logger.info('openai usage fetched successfully');\n\n return {\n provider: 'openai',\n ok: true,\n configured: true,\n usage,\n };\n } catch (error) {\n const message = error instanceof Error ? error.message : String(error);\n await logger.error(`Request failed for openai: ${message}`);\n return {\n provider: 'openai',\n ok: false,\n configured: true,\n error: `Request failed: ${message}`,\n usage: null,\n };\n }\n};\n", "import type { Logger } from '../common/logger.ts';\nimport type { OpenCodeAuth } from '../../types/index.ts';\nimport { loadOpenCodeAuth } from '../common/files.ts';\nimport { getProviderAliases } from '../common/registry.ts';\n\nconst resolveAuthValue = (entry: OpenCodeAuth[string]): string | null => {\n if (!entry) {\n return null;\n }\n\n if (typeof entry === 'string') {\n return entry;\n }\n\n if (typeof entry === 'object') {\n return entry.api_key ?? entry.token ?? entry.key ?? null;\n }\n\n return null;\n};\n\nexport const getZaiApiKey = async (logger?: Logger): Promise<string | null> => {\n if (process.env.ZAI_API_KEY) {\n return process.env.ZAI_API_KEY;\n }\n\n const auth = await loadOpenCodeAuth(logger);\n if (!auth) {\n return null;\n }\n\n for (const alias of getProviderAliases('zai-coding-plan')) {\n const value = resolveAuthValue(auth[alias]);\n if (value) {\n return value;\n }\n }\n\n return null;\n};\n", "import type { ProviderResult, ProviderUsage, UsageWindow } from '../../types/index.ts';\nimport { maskSecret, type Logger, noopLogger } from '../common/logger.ts';\nimport { calculateResetAfterSeconds, formatDuration, formatResetAt } from '../common/time.ts';\nimport { getZaiApiKey } from './auth.ts';\n\ninterface ZaiLimit {\n type: 'TIME_LIMIT' | 'TOKENS_LIMIT';\n unit: number;\n number: number;\n usage: number;\n currentValue: number;\n remaining: number;\n percentage: number;\n nextResetTime?: number;\n}\n\ninterface ZaiUsageResponse {\n code: number;\n msg: string;\n data?: {\n limits?: ZaiLimit[];\n };\n success: boolean;\n}\n\nconst normalizeTimestamp = (value: number): number => {\n return value < 1_000_000_000_000 ? value * 1000 : value;\n};\n\nconst TOKEN_WINDOW_SECONDS: Record<number, number> = {\n 3: 3600,\n};\n\nconst resolveWindowSeconds = (limit?: ZaiLimit): number | null => {\n if (!limit) {\n return null;\n }\n\n if (!limit.number) {\n return null;\n }\n\n const unitSeconds = TOKEN_WINDOW_SECONDS[limit.unit];\n if (!unitSeconds) {\n return null;\n }\n\n return unitSeconds * limit.number;\n};\n\nconst resolveWindowLabel = (windowSeconds: number | null): string => {\n if (!windowSeconds) {\n return 'tokens';\n }\n\n if (windowSeconds % 86400 === 0) {\n const days = windowSeconds / 86400;\n return days === 7 ? 'weekly' : `${days}d`;\n }\n\n if (windowSeconds % 3600 === 0) {\n return `${windowSeconds / 3600}h`;\n }\n\n return `${windowSeconds}s`;\n};\n\nconst toWindow = (limit?: ZaiLimit): UsageWindow | null => {\n if (!limit) {\n return null;\n }\n\n const usedPercent = limit.percentage ?? null;\n const remainingPercent = usedPercent !== null ? Math.max(0, 100 - usedPercent) : null;\n const resetAt = limit.nextResetTime ? normalizeTimestamp(limit.nextResetTime) : null;\n const resetAfterSeconds = calculateResetAfterSeconds(resetAt);\n\n return {\n usedPercent,\n remainingPercent,\n windowSeconds: resolveWindowSeconds(limit),\n resetAfterSeconds,\n resetAt,\n resetAtFormatted: resetAt ? formatResetAt(resetAt) : null,\n resetAfterFormatted: resetAfterSeconds !== null ? formatDuration(resetAfterSeconds) : null,\n };\n};\n\nexport const fetchZaiUsage = async (logger: Logger = noopLogger): Promise<ProviderResult> => {\n const apiKey = await getZaiApiKey(logger);\n\n if (!apiKey) {\n await logger.warn('No auth configured for zai-coding-plan');\n return {\n provider: 'zai-coding-plan',\n ok: false,\n configured: false,\n error: 'Not configured - no API key found',\n usage: null,\n };\n }\n\n try {\n const response = await fetch('https://api.z.ai/api/monitor/usage/quota/limit', {\n method: 'GET',\n headers: {\n Authorization: `Bearer ${apiKey}`,\n 'Content-Type': 'application/json',\n },\n });\n\n if (!response.ok) {\n await logger.error(`API error ${response.status} for zai-coding-plan`, {\n token: maskSecret(apiKey),\n });\n return {\n provider: 'zai-coding-plan',\n ok: false,\n configured: true,\n error: `API error: ${response.status}`,\n usage: null,\n };\n }\n\n const payload = (await response.json()) as ZaiUsageResponse;\n const limits = payload.data?.limits ?? [];\n const tokensLimit = limits.find((limit) => limit.type === 'TOKENS_LIMIT');\n\n const windows: Record<string, UsageWindow> = {};\n const window = toWindow(tokensLimit);\n if (window) {\n const label = resolveWindowLabel(window.windowSeconds);\n windows[label] = window;\n }\n\n const usage: ProviderUsage = {\n windows,\n };\n\n await logger.info('zai-coding-plan usage fetched successfully');\n\n return {\n provider: 'zai-coding-plan',\n ok: true,\n configured: true,\n usage,\n };\n } catch (error) {\n const message = error instanceof Error ? error.message : String(error);\n await logger.error(`Request failed for zai-coding-plan: ${message}`);\n return {\n provider: 'zai-coding-plan',\n ok: false,\n configured: true,\n error: `Request failed: ${message}`,\n usage: null,\n };\n }\n};\n", "export type ProviderId = 'openai' | 'google' | 'zai-coding-plan';\n\nexport type ProviderAlias = ProviderId | 'codex' | 'antigravity' | 'zai' | 'z.ai' | 'chatgpt';\n\nexport type ProviderIdValues = 'openai' | 'google' | 'zai-coding-plan';\n\nexport const PROVIDERS: ProviderIdValues[] = ['openai', 'google', 'zai-coding-plan'];\n\nexport type OpenCodeAuth = Record<string, string | ProviderAuthData>;\n\nexport interface ProviderAuthData {\n type?: 'oauth' | 'api' | string;\n access?: string;\n refresh?: string;\n expires?: number;\n api_key?: string;\n token?: string;\n key?: string;\n accountId?: string;\n}\n", "import type { UsageWindows } from '../types/index.js';\n\nconst FLAGSHIP_PATTERNS: RegExp[] = [\n /claude[-\\s]*opus[-\\s]*4[-\\s.]?5/i,\n /gemini[-\\s]*3[-\\s.]?pro/i,\n /gemini[-\\s]*3[-\\s.]?flash/i,\n];\n\nexport const isFlagshipModel = (modelName: string): boolean => {\n return FLAGSHIP_PATTERNS.some((pattern) => pattern.test(modelName));\n};\n\nexport const filterFlagshipModels = (\n models?: Record<string, UsageWindows>\n): Record<string, UsageWindows> => {\n if (!models) {\n return {};\n }\n\n const filtered: Record<string, UsageWindows> = {};\n\n for (const [modelName, modelData] of Object.entries(models)) {\n if (isFlagshipModel(modelName)) {\n filtered[modelName] = modelData;\n }\n }\n\n return filtered;\n};\n", "import type { ProviderResult, ProviderUsage } from '../types/index.js';\nimport type { ToastUsageResult } from '../types/toast.js';\nimport { filterFlagshipModels } from './filter.js';\n\nconst formatProviderLine = (provider: string, usage: ProviderUsage | null): string => {\n if (!usage) {\n return `${provider}: Not configured`;\n }\n\n const globalWindows = Object.values(usage.windows);\n if (globalWindows.length > 0) {\n const window = globalWindows[0];\n const used = window.usedPercent ?? 0;\n const reset = window.resetAfterFormatted ?? 'N/A';\n return `${provider}: ${used}% used \u2022 resets in ${reset}`;\n }\n\n if (usage.models) {\n const models = Object.entries(usage.models);\n if (models.length === 1) {\n const [modelName, modelData] = models[0];\n const window = Object.values(modelData.windows)[0];\n const used = window.usedPercent ?? 0;\n const reset = window.resetAfterFormatted ?? 'N/A';\n return `${provider}: ${modelName} ${used}% \u2022 resets in ${reset}`;\n }\n\n if (models.length > 1) {\n const parts: string[] = [];\n for (const [modelName, modelData] of models) {\n const window = Object.values(modelData.windows)[0];\n const used = window.usedPercent ?? 0;\n parts.push(`${modelName} ${used}%`);\n }\n return `${provider}: ${parts.join(', ')}`;\n }\n }\n\n return `${provider}: No usage data`;\n};\n\nexport const formatUsageToast = (results: ProviderResult[]): ToastUsageResult => {\n const lines: string[] = [];\n\n for (const result of results) {\n let usage = result.usage;\n\n if (result.provider === 'google' && usage?.models) {\n usage = {\n ...usage,\n models: filterFlagshipModels(usage.models),\n };\n }\n\n const line = formatProviderLine(result.provider, usage);\n lines.push(line);\n }\n\n return {\n title: 'Usage',\n message: lines.join('\\n'),\n variant: 'info',\n };\n};\n"],
"mappings": "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",
"names": ["toAuthData", "loadOpenCodeAuthEntry", "toWindow", "toWindow"]
}
{
"name": "opencode-usage-plugin",
"version": "0.0.1",
"version": "0.0.2-dev",
"description": "OpenCode plugin to display subscription usages for OpenAI, Google, and z.ai",

@@ -38,7 +38,6 @@ "author": {

"dist/index.js.map",
"dist/index.d.ts",
"dist/command"
"dist/index.d.ts"
],
"scripts": {
"build": "npx esbuild src/index.ts --bundle --platform=node --format=esm --outfile=dist/index.js --external:@opencode-ai/plugin --external:path --external:@types/node --sourcemap && npx tsc --emitDeclarationOnly && cp -r src/command dist/",
"build": "npx esbuild src/index.ts --bundle --platform=node --format=esm --outfile=dist/index.js --external:@opencode-ai/plugin --external:path --external:@types/node --sourcemap && npx tsc --emitDeclarationOnly",
"prepublishOnly": "npm run build",

@@ -45,0 +44,0 @@ "test": "vitest run",

---
description: Show remaining usage for AI coding providers (OpenAI, Google, z.ai)
---
Call the `usage` tool.
If $ARGUMENTS is empty, fetch usage for all configured providers.
If $ARGUMENTS is provided, it should be one of: openai, google, zai-coding-plan (aliases: codex, antigravity, zai).
The tool returns a JSON string with a list of provider results:
- `provider`, `ok`, `configured`, `error`
- `usage.windows` for global windows
- `usage.models[model].windows` for per-model windows
Each window includes:
- `remainingPercent` - remaining usage percentage
- `resetAfterFormatted` - human-readable time remaining (e.g., "2w 3d 5h 10m 30s")
- `resetAtFormatted` - exact reset datetime (e.g., "Thursday, January 16, 2026, 2:30:45 PM EST")
- `windowSeconds` - size of the usage window
Parse the JSON, then return a short markdown summary per provider.
Include remaining percent, reset time remaining, reset datetime, window size, and any errors.