diff --git a/packages/pi-coding-agent/src/cli/args.ts b/packages/pi-coding-agent/src/cli/args.ts index f529771b2..bd8ad3913 100644 --- a/packages/pi-coding-agent/src/cli/args.ts +++ b/packages/pi-coding-agent/src/cli/args.ts @@ -338,7 +338,6 @@ ${chalk.bold("Environment Variables:")} PI_PACKAGE_DIR - Override package directory (for Nix/Guix store paths) PI_OFFLINE - Disable startup network operations when set to 1/true/yes PI_SHARE_VIEWER_URL - Base URL for /share command (default: https://pi.dev/session/) - PI_AI_ANTIGRAVITY_VERSION - Override Antigravity User-Agent version (e.g., 1.23.0) ${chalk.bold("Available Tools (default: read, bash, edit, write):")} read - Read file contents diff --git a/packages/pi-coding-agent/src/utils/proxy-server.ts b/packages/pi-coding-agent/src/utils/proxy-server.ts index b4a76b4c1..114501e97 100644 --- a/packages/pi-coding-agent/src/utils/proxy-server.ts +++ b/packages/pi-coding-agent/src/utils/proxy-server.ts @@ -33,8 +33,8 @@ const PROXY_FAMILY_PRIORITY: Array<{ match: RegExp; providers: string[] }> = [ { match: /^kimi-/i, providers: ["kimi-coding", "opencode", "opencode-go"] }, // Gemini/Gemma: google direct > vertex (enterprise) > CLI (OAuth) > copilot { match: /^gemini-|^gemma-/i, providers: ["google", "google-vertex", "google-gemini-cli", "github-copilot"] }, - // Claude: anthropic direct > opencode > google-antigravity > copilot - { match: /^claude-/i, providers: ["anthropic", "opencode", "google-antigravity", "github-copilot"] }, + // Claude: anthropic direct > opencode > copilot + { match: /^claude-/i, providers: ["anthropic", "opencode", "github-copilot"] }, // GPT/OpenAI: openai direct > azure > copilot { match: /^gpt-|^o[0-9]|^codex-/i, providers: ["openai", "azure-openai-responses", "github-copilot"] }, ]; diff --git a/src/onboarding.ts b/src/onboarding.ts index 2861299f6..5d4ca6e16 100644 --- a/src/onboarding.ts +++ b/src/onboarding.ts @@ -70,7 +70,6 @@ const LLM_PROVIDER_IDS = [ 'github-copilot', 'openai-codex', 'google-gemini-cli', - 'google-antigravity', 'google', 'groq', 'xai', @@ -360,7 +359,6 @@ async function runLlmStep(p: ClackModule, pc: PicoModule, authStorage: AuthStora { value: 'github-copilot', label: 'GitHub Copilot' }, { value: 'openai-codex', label: 'ChatGPT Plus/Pro (Codex)' }, { value: 'google-gemini-cli', label: 'Google Gemini CLI' }, - { value: 'google-antigravity', label: 'Antigravity (Gemini 3, Claude, GPT-OSS)' }, ], }) if (p.isCancel(provider)) return false diff --git a/src/pi-migration.ts b/src/pi-migration.ts index 2eed3a74e..05fec7dfa 100644 --- a/src/pi-migration.ts +++ b/src/pi-migration.ts @@ -18,7 +18,6 @@ const LLM_PROVIDER_IDS = [ 'github-copilot', 'openai-codex', 'google-gemini-cli', - 'google-antigravity', 'google', 'groq', 'xai', diff --git a/src/resources/extensions/sf-usage-bar/index.ts b/src/resources/extensions/sf-usage-bar/index.ts index 787b569f0..64a0c979b 100644 --- a/src/resources/extensions/sf-usage-bar/index.ts +++ b/src/resources/extensions/sf-usage-bar/index.ts @@ -402,202 +402,6 @@ async function fetchGeminiUsage(_modelRegistry: any): Promise { } } -// ============================================================================ -// Antigravity Usage -// ============================================================================ - -type AntigravityAuth = { - accessToken: string; - refreshToken?: string; - expiresAt?: number; - projectId?: string; -}; - -function loadAntigravityAuthFromAuthJson(): AntigravityAuth | undefined { - const data = loadAuthJson(); - if (!data) return undefined; - - // Provider is called "google-antigravity" in sf/pi. - const cred = data["google-antigravity"] ?? data["antigravity"] ?? data["anti-gravity"]; - if (!cred) return undefined; - - const accessToken = typeof cred.access === "string" ? cred.access : undefined; - if (!accessToken) return undefined; - - return { - accessToken, - refreshToken: typeof cred.refresh === "string" ? cred.refresh : undefined, - expiresAt: typeof cred.expires === "number" ? cred.expires : undefined, - projectId: typeof cred.projectId === "string" ? cred.projectId : typeof cred.project_id === "string" ? cred.project_id : undefined, - }; -} - -async function loadAntigravityAuth(modelRegistry: any): Promise { - // Prefer model registry auth storage first (may auto-refresh). - try { - const accessToken = await Promise.resolve(modelRegistry?.authStorage?.getApiKey?.("google-antigravity")); - const raw = await Promise.resolve(modelRegistry?.authStorage?.get?.("google-antigravity")); - - const projectId = typeof raw?.projectId === "string" ? raw.projectId : undefined; - const refreshToken = typeof raw?.refresh === "string" ? raw.refresh : undefined; - const expiresAt = typeof raw?.expires === "number" ? raw.expires : undefined; - - if (typeof accessToken === "string" && accessToken.length > 0) { - return { accessToken, projectId, refreshToken, expiresAt }; - } - } catch {} - - // Fallback to auth.json - const fromAuth = loadAntigravityAuthFromAuthJson(); - if (fromAuth) return fromAuth; - - // Last resort: env var (won't have projectId; request will likely fail) - if (process.env.ANTIGRAVITY_API_KEY) { - return { accessToken: process.env.ANTIGRAVITY_API_KEY }; - } - - return undefined; -} - -async function refreshAntigravityAccessToken(refreshToken: string): Promise<{ accessToken: string; expiresAt?: number } | null> { - try { - const controller = new AbortController(); - setTimeout(() => controller.abort(), 5000); - - // From the reference snippet in CodexBar issue #129. - const clientId = "1071006060591-tmhssin2h21lcre235vtolojh4g403ep.apps.googleusercontent.com"; - const clientSecret = "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"; - - const res = await fetch("https://oauth2.googleapis.com/token", { - method: "POST", - headers: { "Content-Type": "application/x-www-form-urlencoded" }, - body: new URLSearchParams({ - client_id: clientId, - client_secret: clientSecret, - refresh_token: refreshToken, - grant_type: "refresh_token", - }).toString(), - signal: controller.signal, - }); - - if (!res.ok) return null; - const data = (await res.json()) as any; - const accessToken = typeof data.access_token === "string" ? data.access_token : undefined; - if (!accessToken) return null; - const expiresIn = typeof data.expires_in === "number" ? data.expires_in : undefined; - return { - accessToken, - expiresAt: expiresIn ? Date.now() + expiresIn * 1000 : undefined, - }; - } catch { - return null; - } -} - -async function fetchAntigravityUsage(modelRegistry: any): Promise { - const auth = await loadAntigravityAuth(modelRegistry); - if (!auth?.accessToken) { - return { provider: "antigravity", displayName: "Antigravity", windows: [], error: "No credentials" }; - } - - if (!auth.projectId) { - return { provider: "antigravity", displayName: "Antigravity", windows: [], error: "Missing projectId" }; - } - - let accessToken = auth.accessToken; - - // Refresh if likely expired. - if (auth.refreshToken && auth.expiresAt && auth.expiresAt < Date.now() + 5 * 60 * 1000) { - const refreshed = await refreshAntigravityAccessToken(auth.refreshToken); - if (refreshed?.accessToken) accessToken = refreshed.accessToken; - } - - const fetchModels = async (token: string): Promise => { - const controller = new AbortController(); - setTimeout(() => controller.abort(), 5000); - - return fetch("https://cloudcode-pa.googleapis.com/v1internal:fetchAvailableModels", { - method: "POST", - headers: { - Authorization: `Bearer ${token}`, - "Content-Type": "application/json", - "User-Agent": "antigravity/1.12.4", - "X-Goog-Api-Client": "google-cloud-sdk vscode_cloudshelleditor/0.1", - Accept: "application/json", - }, - body: JSON.stringify({ project: auth.projectId }), - signal: controller.signal, - }); - }; - - try { - let res = await fetchModels(accessToken); - - if ((res.status === 401 || res.status === 403) && auth.refreshToken) { - const refreshed = await refreshAntigravityAccessToken(auth.refreshToken); - if (refreshed?.accessToken) { - accessToken = refreshed.accessToken; - res = await fetchModels(accessToken); - } - } - - if (res.status === 401 || res.status === 403) { - return { provider: "antigravity", displayName: "Antigravity", windows: [], error: "Unauthorized" }; - } - - if (!res.ok) { - return { provider: "antigravity", displayName: "Antigravity", windows: [], error: `HTTP ${res.status}` }; - } - - const data = (await res.json()) as any; - const models: Record = data.models || {}; - - const getQuotaInfo = (modelKeys: string[]): { usedPercent: number; resetDescription?: string } | null => { - for (const key of modelKeys) { - const qi = models?.[key]?.quotaInfo; - if (!qi) continue; - // In practice (CodexBar issue #129), some models only provide resetTime. - // Treat missing remainingFraction as 0% remaining (100% used), which matches Antigravity's behavior when quota is exhausted. - const remainingFraction = typeof qi.remainingFraction === "number" ? qi.remainingFraction : 0; - const usedPercent = Math.min(100, Math.max(0, (1 - remainingFraction) * 100)); - const resetTime = qi.resetTime ? new Date(qi.resetTime) : undefined; - return { usedPercent, resetDescription: resetTime ? formatReset(resetTime) : undefined }; - } - return null; - }; - - // Quota groups from the reference snippet in CodexBar issue #129. - const windows: RateWindow[] = []; - - const claudeOrGptOss = getQuotaInfo([ - "claude-sonnet-4-5", - "claude-sonnet-4-5-thinking", - "claude-opus-4-5-thinking", - "gpt-oss-120b-medium", - ]); - if (claudeOrGptOss) { - windows.push({ label: "Claude", usedPercent: claudeOrGptOss.usedPercent, resetDescription: claudeOrGptOss.resetDescription }); - } - - const gemini3Pro = getQuotaInfo(["gemini-3-pro-high", "gemini-3-pro-low", "gemini-3-pro-preview"]); - if (gemini3Pro) { - windows.push({ label: "G3 Pro", usedPercent: gemini3Pro.usedPercent, resetDescription: gemini3Pro.resetDescription }); - } - - const gemini3Flash = getQuotaInfo(["gemini-3-flash"]); - if (gemini3Flash) { - windows.push({ label: "G3 Flash", usedPercent: gemini3Flash.usedPercent, resetDescription: gemini3Flash.resetDescription }); - } - - if (windows.length === 0) { - return { provider: "antigravity", displayName: "Antigravity", windows: [], error: "No quota data" }; - } - - return { provider: "antigravity", displayName: "Antigravity", windows }; - } catch (e) { - return { provider: "antigravity", displayName: "Antigravity", windows: [], error: String(e) }; - } -} // ============================================================================ // Codex (OpenAI) Usage @@ -954,12 +758,11 @@ class UsageComponent { Promise.race([p, new Promise((r) => setTimeout(() => r(fallback), ms))]); // Fetch usage and status in parallel - const [claude, copilot, gemini, codex, antigravity, kiro, zai, claudeStatus, copilotStatus, geminiStatus, codexStatus] = await Promise.all([ + const [claude, copilot, gemini, codex, kiro, zai, claudeStatus, copilotStatus, geminiStatus, codexStatus] = await Promise.all([ timeout(fetchClaudeUsage(), 6000, { provider: "anthropic", displayName: "Claude", windows: [], error: "Timeout" }), timeout(fetchCopilotUsage(this.modelRegistry), 6000, { provider: "copilot", displayName: "Copilot", windows: [], error: "Timeout" }), timeout(fetchGeminiUsage(this.modelRegistry), 6000, { provider: "gemini", displayName: "Gemini", windows: [], error: "Timeout" }), timeout(fetchCodexUsage(this.modelRegistry), 6000, { provider: "codex", displayName: "Codex", windows: [], error: "Timeout" }), - timeout(fetchAntigravityUsage(this.modelRegistry), 6000, { provider: "antigravity", displayName: "Antigravity", windows: [], error: "Timeout" }), timeout(fetchKiroUsage(), 6000, { provider: "kiro", displayName: "Kiro", windows: [], error: "Timeout" }), timeout(fetchZaiUsage(), 6000, { provider: "zai", displayName: "z.ai", windows: [], error: "Timeout" }), timeout(fetchProviderStatus("anthropic"), 3000, { indicator: "unknown" as const }), @@ -975,7 +778,7 @@ class UsageComponent { codex.status = codexStatus; // Filter out providers with no data and no error (not configured) - const allUsages = [claude, copilot, gemini, codex, antigravity, kiro, zai]; + const allUsages = [claude, copilot, gemini, codex, kiro, zai]; this.usages = allUsages.filter(u => u.windows.length > 0 || u.error !== "No credentials" && u.error !== "kiro-cli not found" && u.error !== "No API key"); this.loading = false; this.tui.requestRender(); diff --git a/src/resources/extensions/sf/doctor-providers.ts b/src/resources/extensions/sf/doctor-providers.ts index 9283350f3..4c036e64c 100644 --- a/src/resources/extensions/sf/doctor-providers.ts +++ b/src/resources/extensions/sf/doctor-providers.ts @@ -193,7 +193,6 @@ const CLI_AUTH_PROVIDERS = new Set([ "claude-code", "openai-codex", "google-gemini-cli", - "google-antigravity", ]); function checkLlmProviders(): ProviderCheckResult[] { diff --git a/src/resources/extensions/sf/key-manager.ts b/src/resources/extensions/sf/key-manager.ts index 05f5db45a..2b1a62c61 100644 --- a/src/resources/extensions/sf/key-manager.ts +++ b/src/resources/extensions/sf/key-manager.ts @@ -39,7 +39,6 @@ export const PROVIDER_REGISTRY: ProviderInfo[] = [ { id: "github-copilot", label: "GitHub Copilot", category: "llm", envVar: "GITHUB_TOKEN", hasOAuth: true }, { id: "openai-codex", label: "ChatGPT Plus/Pro (Codex)",category: "llm", hasOAuth: true }, { id: "google-gemini-cli",label: "Google Gemini CLI", category: "llm", hasOAuth: true }, - { id: "google-antigravity",label: "Antigravity", category: "llm", hasOAuth: true }, { id: "google", label: "Google (Gemini)", category: "llm", envVar: "GEMINI_API_KEY", dashboardUrl: "aistudio.google.com/apikey" }, { id: "groq", label: "Groq", category: "llm", envVar: "GROQ_API_KEY", dashboardUrl: "console.groq.com" }, { id: "xai", label: "xAI (Grok)", category: "llm", envVar: "XAI_API_KEY", dashboardUrl: "console.x.ai" }, diff --git a/src/tests/integration/web-onboarding-contract.test.ts b/src/tests/integration/web-onboarding-contract.test.ts index fb89badc7..f02076355 100644 --- a/src/tests/integration/web-onboarding-contract.test.ts +++ b/src/tests/integration/web-onboarding-contract.test.ts @@ -339,7 +339,6 @@ test("boot and onboarding routes expose locked required state plus explicitly sk "github-copilot", "openai-codex", "google-gemini-cli", - "google-antigravity", "google", "groq", "xai", diff --git a/src/web/onboarding-service.ts b/src/web/onboarding-service.ts index 7f207a893..44b6644f9 100644 --- a/src/web/onboarding-service.ts +++ b/src/web/onboarding-service.ts @@ -147,7 +147,6 @@ const REQUIRED_PROVIDER_CATALOG: RequiredProviderCatalogEntry[] = [ { id: "github-copilot", label: "GitHub Copilot", supportsApiKey: false, supportsOAuth: true }, { id: "openai-codex", label: "ChatGPT Plus/Pro (Codex Subscription)", supportsApiKey: false, supportsOAuth: true }, { id: "google-gemini-cli", label: "Google Cloud Code Assist (Gemini CLI)", supportsApiKey: false, supportsOAuth: true }, - { id: "google-antigravity", label: "Antigravity (Gemini 3, Claude, GPT-OSS)", supportsApiKey: false, supportsOAuth: true }, { id: "google", label: "Google (Gemini API)", supportsApiKey: true, supportsOAuth: false }, { id: "groq", label: "Groq", supportsApiKey: true, supportsOAuth: false }, { id: "xai", label: "xAI (Grok)", supportsApiKey: true, supportsOAuth: false },