/* Copyright 2026 Marimo. All rights reserved. */ import { useAtom } from "jotai"; import { CheckIcon, CopyIcon, Loader2Icon, XIcon } from "lucide-react"; import { memo, useState } from "react"; import { Button, buttonVariants } from "@/components/ui/button"; import { Label } from "@/components/ui/label"; import { ExternalLink } from "@/components/ui/links"; import { toast } from "@/components/ui/use-toast"; import { copyToClipboard } from "@/utils/copy"; import { Logger } from "@/utils/Logger"; import { getCopilotClient } from "./client"; import { copilotSignedInState, isGitHubCopilotSignedInState } from "./state"; import type { GitHubCopilotStatus } from "./types"; export const CopilotConfig = memo(() => { const [copilotSignedIn, copilotChangeSignIn] = useAtom( isGitHubCopilotSignedInState, ); const [step, setStep] = useAtom(copilotSignedInState); const [localData, setLocalData] = useState<{ url: string; code: string }>(); const [loading, setLoading] = useState(false); const trySignIn = async (evt: React.MouseEvent) => { evt.preventDefault(); setLoading(true); try { const result = await initiateSignIn(); // Validate the response has required fields if (!result?.verificationUri || !result.userCode) { Logger.error("Copilot#trySignIn: Invalid response from sign-in", { result, }); setStep("connectionError"); toast({ title: "GitHub Copilot Connection Error", description: "Unable to connect to GitHub Copilot. Please check your settings and try again.", variant: "danger", }); return; } const { verificationUri, status, userCode } = result; if (isSignedIn(status)) { copilotChangeSignIn(true); } else { setStep("signingIn"); setLocalData({ url: verificationUri, code: userCode }); } } catch (error) { Logger.error("Copilot#trySignIn: Error during sign-in", error); setStep("connectionError"); toast({ title: "GitHub Copilot Connection Error", description: error instanceof Error ? error.message : "Unable to connect to GitHub Copilot. Please check your settings and try again.", variant: "danger", }); } finally { setLoading(false); } }; const tryFinishSignIn = async (evt: React.MouseEvent) => { evt.preventDefault(); if (!localData) { return; } setLoading(true); try { const result = await handleSignInConfirmation(localData.code); if (result.success) { copilotChangeSignIn(true); setStep("signedIn"); } else if (result.error === "connection") { setStep("connectionError"); toast({ title: "GitHub Copilot Connection Error", description: "Lost connection during sign-in. Please try again.", variant: "danger", action: , }); } else { setStep("signInFailed"); } } finally { setLoading(false); } }; const signOut = async (evt: React.MouseEvent) => { evt.preventDefault(); await handleSignOut(); copilotChangeSignIn(false); setStep("signedOut"); }; const renderBody = () => { // If we don't have a step set, infer it from the current state const resolvedStep = step ?? (copilotSignedIn ? "signedIn" : "connecting"); switch (resolvedStep) { case "connecting": return ; case "signedOut": return ( ); case "signingIn": return (