Feat: Show Gemini Usage in usage dropdown and mobile sidebar

This commit is contained in:
eclipxe
2026-01-25 09:44:03 -08:00
committed by gsxdsm
parent 7765a12868
commit 7d5bc722fa
17 changed files with 1374 additions and 61 deletions

View File

@@ -98,6 +98,10 @@ import {
type ZaiQuotaLimit,
type ZaiUsage,
type ZaiUsageResponse,
type GeminiQuotaBucket,
type GeminiTierQuota,
type GeminiUsage,
type GeminiUsageResponse,
} from './types';
// Import utility functions from modular utils files
@@ -181,6 +185,10 @@ export type {
ZaiQuotaLimit,
ZaiUsage,
ZaiUsageResponse,
GeminiQuotaBucket,
GeminiTierQuota,
GeminiUsage,
GeminiUsageResponse,
};
// Re-export values from ./types for backward compatibility
@@ -210,7 +218,7 @@ export { defaultBackgroundSettings, defaultTerminalState, MAX_INIT_OUTPUT_LINES
// - Terminal types (./types/terminal-types.ts)
// - ClaudeModel, Feature, FileTreeNode, ProjectAnalysis (./types/project-types.ts)
// - InitScriptState, AutoModeActivity, AppState, AppActions (./types/state-types.ts)
// - Claude/Codex usage types (./types/usage-types.ts)
// - Claude/Codex/Zai/Gemini usage types (./types/usage-types.ts)
// The following utility functions have been moved to ./utils/:
// - Theme utilities: THEME_STORAGE_KEY, getStoredTheme, getStoredFontSans, getStoredFontMono, etc. (./utils/theme-utils.ts)
// - Shortcut utilities: parseShortcut, formatShortcut, DEFAULT_KEYBOARD_SHORTCUTS (./utils/shortcut-utils.ts)
@@ -220,6 +228,9 @@ export { defaultBackgroundSettings, defaultTerminalState, MAX_INIT_OUTPUT_LINES
// - defaultBackgroundSettings (./defaults/background-settings.ts)
// - defaultTerminalState (./defaults/terminal-defaults.ts)
// Type definitions are imported from ./types/state-types.ts
// AppActions interface is defined in ./types/state-types.ts
const initialState: AppState = {
projects: [],
currentProject: null,

View File

@@ -127,6 +127,22 @@ export interface ZaiAuthStatus {
error?: string;
}
// Gemini Auth Method
export type GeminiAuthMethod =
| 'cli_login' // Gemini CLI is installed and authenticated
| 'api_key_env' // GOOGLE_API_KEY or GEMINI_API_KEY environment variable
| 'api_key' // Manually stored API key
| 'none';
// Gemini Auth Status
export interface GeminiAuthStatus {
authenticated: boolean;
method: GeminiAuthMethod;
hasApiKey?: boolean;
hasEnvApiKey?: boolean;
error?: string;
}
// Claude Auth Method - all possible authentication sources
export type ClaudeAuthMethod =
| 'oauth_token_env'
@@ -200,6 +216,7 @@ export interface SetupState {
// Gemini CLI state
geminiCliStatus: GeminiCliStatus | null;
geminiAuthStatus: GeminiAuthStatus | null;
// Copilot SDK state
copilotCliStatus: CopilotCliStatus | null;
@@ -243,6 +260,7 @@ export interface SetupActions {
// Gemini CLI
setGeminiCliStatus: (status: GeminiCliStatus | null) => void;
setGeminiAuthStatus: (status: GeminiAuthStatus | null) => void;
// Copilot SDK
setCopilotCliStatus: (status: CopilotCliStatus | null) => void;
@@ -284,6 +302,7 @@ const initialState: SetupState = {
opencodeCliStatus: null,
geminiCliStatus: null,
geminiAuthStatus: null,
copilotCliStatus: null,
@@ -363,6 +382,7 @@ export const useSetupStore = create<SetupState & SetupActions>()((set, get) => (
// Gemini CLI
setGeminiCliStatus: (status) => set({ geminiCliStatus: status }),
setGeminiAuthStatus: (status) => set({ geminiAuthStatus: status }),
// Copilot SDK
setCopilotCliStatus: (status) => set({ copilotCliStatus: status }),

View File

@@ -82,3 +82,55 @@ export interface ZaiUsage {
// Response type for z.ai usage API (can be success or error)
export type ZaiUsageResponse = ZaiUsage | { error: string; message?: string };
// Gemini Usage types - uses internal Google Cloud quota API
export interface GeminiQuotaBucket {
/** Model ID this quota applies to */
modelId: string;
/** Remaining fraction (0-1) */
remainingFraction: number;
/** ISO-8601 reset time */
resetTime: string;
}
/** Simplified quota info for a model tier (Flash or Pro) */
export interface GeminiTierQuota {
/** Used percentage (0-100) */
usedPercent: number;
/** Remaining percentage (0-100) */
remainingPercent: number;
/** Reset time as human-readable string */
resetText?: string;
/** ISO-8601 reset time */
resetTime?: string;
}
export interface GeminiUsage {
/** Whether the user is authenticated (via CLI or API key) */
authenticated: boolean;
/** Authentication method: 'cli_login' | 'api_key' | 'api_key_env' | 'none' */
authMethod: string;
/** Usage percentage (100 - remainingFraction * 100) - overall most constrained */
usedPercent: number;
/** Remaining percentage - overall most constrained */
remainingPercent: number;
/** Reset time as human-readable string */
resetText?: string;
/** ISO-8601 reset time */
resetTime?: string;
/** Model ID with lowest remaining quota */
constrainedModel?: string;
/** Flash tier quota (aggregated from all flash models) */
flashQuota?: GeminiTierQuota;
/** Pro tier quota (aggregated from all pro models) */
proQuota?: GeminiTierQuota;
/** Raw quota buckets for detailed view */
quotaBuckets?: GeminiQuotaBucket[];
/** When this data was last fetched */
lastUpdated: string;
/** Optional error message */
error?: string;
}
// Response type for Gemini usage API (can be success or error)
export type GeminiUsageResponse = GeminiUsage | { error: string; message?: string };