import { isAtomCommandInterrupted, squashAtomCommandFailure, type AtomCommandResult, } from "@t3tools/client-runtime/state/runtime"; import { ANTIGRAVITY_AUTH_METHODS, type AntigravityAuthMethod, type EnvironmentId, type ProviderAuthState, type ProviderInstanceId, type ServerProvider, } from "@t3tools/contracts"; import { useRef, useState } from "react"; import { writeTextToClipboard } from "../../hooks/useCopyToClipboard"; import { ensureLocalApi } from "../../localApi"; import { useEnvironmentQuery } from "../../state/query"; import { serverEnvironment } from "../../state/server"; import { useAtomCommand } from "../../state/use-atom-command"; import { Button } from "../ui/button"; import { Input } from "../ui/input"; interface ProviderSetupSectionProps { readonly environmentId: EnvironmentId; readonly environmentLabel: string; readonly instanceId: ProviderInstanceId; readonly provider: ServerProvider | undefined; readonly binaryPath?: string | undefined; readonly authMethod?: AntigravityAuthMethod | undefined; readonly enabled: boolean; readonly readOnly: boolean; readonly onEnable: () => void; } const AUTH_PHASE_LABELS: Record = { idle: "Sign in with your Google account.", starting: "Starting Google sign-in.", waiting: "Waiting for Google sign-in.", verifying: "Checking Google sign-in and available models.", succeeded: "Google sign-in complete.", failed: "Google sign-in failed.", cancelled: "Google sign-in cancelled.", }; /** API key methods skip the browser, so the phases read as a credential check. */ const CREDENTIAL_PHASE_LABELS: Record = { idle: "Connect with the credentials in the provider settings.", starting: "Checking credentials.", waiting: "Checking credentials.", verifying: "Checking credentials and available models.", succeeded: "Connected.", failed: "Could not connect with the configured credentials.", cancelled: "Connection cancelled.", }; /** Read the configured method from the instance config. Unknown values fall back to personal. */ export function readAntigravityAuthMethod(config: unknown): AntigravityAuthMethod { const value = config !== null && typeof config === "object" && "authMethod" in config ? config.authMethod : undefined; return ( ANTIGRAVITY_AUTH_METHODS.find((method) => method.value === value)?.value ?? "oauth-personal" ); } /** Setup state belongs to the selected environment and is never saved in client settings. */ export function ProviderSetupSection(props: ProviderSetupSectionProps) { return (

Antigravity runs on {props.environmentLabel}.

{!props.enabled ? (
Enable it to use it in threads. {!props.readOnly ? ( ) : null}
) : null} {props.readOnly ? (

This connection cannot change provider setup.

) : props.provider?.setup === undefined ? (

Update this environment to install Antigravity and sign in with Google here.

) : ( )}
); } function ProviderSetupActions({ environmentId, environmentLabel, instanceId, provider, enabled, binaryPath, authMethod, }: Pick< ProviderSetupSectionProps, "environmentId" | "environmentLabel" | "instanceId" | "enabled" | "binaryPath" > & { readonly provider: ServerProvider; readonly authMethod: AntigravityAuthMethod; }) { const target = { environmentId, input: { instanceId } }; const usesBrowser = authMethod === "oauth-personal" || authMethod === "oauth-business"; const phaseLabels = usesBrowser ? AUTH_PHASE_LABELS : CREDENTIAL_PHASE_LABELS; const methodLabel = ANTIGRAVITY_AUTH_METHODS.find((method) => method.value === authMethod)?.label ?? "Google account"; const authQuery = useEnvironmentQuery(serverEnvironment.providerAuthState(target)); const installQuery = useEnvironmentQuery(serverEnvironment.providerInstallState(target)); const auth = authQuery.data; const installation = installQuery.data; const commandOptions = { reportFailure: false, reportDefect: false }; const startAuth = useAtomCommand(serverEnvironment.startProviderAuth, commandOptions); const completeAuth = useAtomCommand(serverEnvironment.completeProviderAuth, commandOptions); const cancelAuth = useAtomCommand(serverEnvironment.cancelProviderAuth, commandOptions); const logoutAuth = useAtomCommand(serverEnvironment.logoutProviderAuth, commandOptions); const startInstall = useAtomCommand(serverEnvironment.startProviderInstall, commandOptions); const cancelInstall = useAtomCommand(serverEnvironment.cancelProviderInstall, commandOptions); const removeInstall = useAtomCommand( serverEnvironment.removeProviderInstallation, commandOptions, ); const [pendingLabel, setPendingLabel] = useState(null); const pendingRef = useRef(false); const [error, setError] = useState(null); const [callbackDraft, setCallbackDraft] = useState({ flowId: null as string | null, value: "" }); const [copiedFlowId, setCopiedFlowId] = useState(null); const callbackUrl = callbackDraft.flowId === auth?.flowId ? callbackDraft.value : ""; const authActive = auth?.phase === "starting" || auth?.phase === "waiting" || auth?.phase === "verifying"; const installActive = installation?.phase === "downloading" || installation?.phase === "extracting" || installation?.phase === "verifying"; const usesCustomBinary = Boolean(binaryPath?.trim()); const installed = provider.installed || (!usesCustomBinary && installation?.installedVersion != null); const authenticated = provider.auth.status === "authenticated"; const authStatusMessage = auth === null ? "Reading sign-in status." : authActive || auth.phase === "failed" || auth.phase === "cancelled" ? (auth.message ?? phaseLabels[auth.phase]) : authenticated ? usesBrowser ? "Signed in with Google." : "Connected." : auth.phase === "idle" && auth.message ? auth.message : phaseLabels.idle; const authorizationUrl = auth?.phase === "waiting" ? auth.authorizationUrl : null; const queryError = authQuery.error ?? installQuery.error; const actionsDisabled = pendingLabel !== null || queryError !== null; const installationStatusMessage = installation?.phase === "downloading" ? `Downloading ${(installation.downloadedBytes / 1_000_000).toFixed(1)} MB${installation.totalBytes === null ? "" : ` of ${(installation.totalBytes / 1_000_000).toFixed(1)} MB`}.` : installation?.phase === "extracting" ? "Extracting Antigravity." : installation?.phase === "verifying" ? "Checking the downloaded runtime." : installed ? "Antigravity is installed." : usesCustomBinary ? enabled ? "The configured Antigravity runtime is unavailable." : "The configured Antigravity runtime has not been checked." : "Install the official Antigravity runtime before signing in."; async function runCommand( label: string, request: () => Promise>, ): Promise { if (pendingRef.current) return false; pendingRef.current = true; setPendingLabel(label); setError(null); try { const result = await request(); if (result._tag === "Failure") { if (!isAtomCommandInterrupted(result)) { const failure = squashAtomCommandFailure(result); setError(failure instanceof Error ? failure.message : "Provider setup failed."); } return false; } return true; } catch { setError("Provider setup failed. Try again."); return false; } finally { pendingRef.current = false; setPendingLabel(null); } } async function openSignInPage() { if (!authorizationUrl) return; try { await ensureLocalApi().shell.openExternal(authorizationUrl); setError(null); } catch { setError("Could not open the sign-in page. Copy the link and open it in your browser."); } } async function copySignInLink() { if (!authorizationUrl) return; try { await writeTextToClipboard(authorizationUrl, "Google sign-in link"); setCopiedFlowId(auth?.flowId ?? null); setError(null); } catch { setError("Could not copy the sign-in link. Use Open sign-in page."); } } async function submitCallback() { const flowId = auth?.flowId; if (!flowId || !callbackUrl.trim() || auth.phase !== "waiting") return; const accepted = await runCommand("Checking redirect", () => completeAuth({ environmentId, input: { instanceId, flowId, callbackUrl } }), ); if (accepted) { setCallbackDraft({ flowId: null, value: "" }); } } async function signOut() { const confirmed = await ensureLocalApi().dialogs.confirm( `${usesBrowser ? "Sign out of Google" : "Disconnect"} for ${provider.displayName ?? "Antigravity"} on ${environmentLabel}? This stops its running threads. Thread history is kept.`, ); if (confirmed) { await runCommand("Signing out", () => logoutAuth(target)); } } async function removeRuntime() { const confirmed = await ensureLocalApi().dialogs.confirm( `Remove the downloaded Antigravity runtime from ${environmentLabel}? Google sign-in and thread history are kept.`, ); if (confirmed) { await runCommand("Removing runtime", () => removeInstall(target)); } } return (

Runtime

{installationStatusMessage}

{installation?.phase === "downloading" && installation.totalBytes !== null && installation.totalBytes > 0 ? ( ) : null} {installation?.message && installation.message !== installationStatusMessage ? (

{installation.message}

) : null} {usesCustomBinary ? (

This instance uses the binary path below. Installing a managed runtime does not change that path.

) : null} {!installed && !usesCustomBinary && !installActive && installation?.totalBytes ? (

Downloads {Math.ceil(installation.totalBytes / 1_000_000)} MB from Google.

) : null} {!installed && !provider.setup?.canInstall ? (

Automatic installation is unavailable here. Set an existing binary path below or use a supported remote environment.

) : null}
{installActive && installation.operationId ? ( ) : !installActive && provider.setup?.canInstall ? ( ) : null} {installation?.canRemove && !installActive ? ( ) : null}

{methodLabel}

{authStatusMessage}

{authorizationUrl ? ( <>
{auth?.expiresAt ? (

Link expires at{" "} .

) : null}
{ event.preventDefault(); void submitCallback(); }} > setCallbackDraft({ flowId: auth?.flowId ?? null, value: event.target.value }) } />
) : auth?.phase === "waiting" ? (

Sign-in is open in another client. Complete or cancel it there.

) : null}
{authActive && auth?.flowId ? ( ) : !authActive && !authenticated && provider.setup?.canAuthenticate ? ( ) : null} {!authActive && provider.setup?.canAuthenticate ? ( ) : null}
{pendingLabel ?

{pendingLabel}.

: null} {error || queryError ? (

{error ?? queryError}

{queryError ? ( ) : null}
) : null}
); }