"use client"; import { useEffect, useMemo, useRef, useState } from "react"; import { Label } from "@kandev/ui/label"; import { Select, SelectContent, SelectItem, SelectTrigger, SelectValue } from "@kandev/ui/select"; import { fetchGitHubCLIAccounts } from "@/lib/api/domains/github-api"; import type { GitHubCLIAccount } from "@/lib/types/github"; function GitHubCLIAccountNotice({ loadError, loading, hasAccounts, }: { loadError: string | null; loading: boolean; hasAccounts: boolean; }) { if (loading || hasAccounts) return null; if (loadError) { return (

Could not load GitHub CLI accounts. {loadError}

); } return (

Sign in with gh auth login, then reopen this dialog.

); } function accountPlaceholder(loading: boolean, loadError: string | null) { if (loading) return "Loading accounts..."; if (loadError) return "Accounts unavailable"; return "No gh accounts found"; } export function GitHubCLIForm({ workspaceId, onAccountChange, disabled, }: { workspaceId: string; onAccountChange: (account: GitHubCLIAccount | null) => void; disabled?: boolean; }) { const [accounts, setAccounts] = useState([]); const [selected, setSelected] = useState(""); const [loadError, setLoadError] = useState(null); const [loading, setLoading] = useState(true); const onAccountChangeRef = useRef(onAccountChange); onAccountChangeRef.current = onAccountChange; useEffect(() => { let current = true; setAccounts([]); setSelected(""); setLoadError(null); setLoading(true); onAccountChangeRef.current(null); fetchGitHubCLIAccounts(workspaceId, { cache: "no-store" }) .then((items) => { if (!current) return; setAccounts(items); const preferred = items.find((item) => item.selected) ?? items.find((item) => item.active) ?? items[0]; setSelected(preferred ? `${preferred.host}\n${preferred.login}` : ""); }) .catch((error) => { if (!current) return; setAccounts([]); setLoadError( error instanceof Error ? error.message : "Unexpected response from the server", ); }) .finally(() => current && setLoading(false)); return () => { current = false; }; }, [workspaceId]); const account = useMemo(() => { const [host, login] = selected.split("\n"); return accounts.find((item) => item.host === host && item.login === login); }, [accounts, selected]); useEffect(() => { onAccountChangeRef.current(account ?? null); }, [account]); return (

Choose the exact account. Kandev does not silently follow the CLI's active-account change.

0} />
); }