"use client"; import { useState, useEffect } from "react"; import { Button } from "@/components/ui/button"; import { Input } from "@/components/ui/input"; import { Label } from "@/components/ui/label"; import { Card, CardContent, CardDescription, CardHeader, CardTitle, } from "@/components/ui/card"; import { useSetupStore } from "@/store/setup-store"; import { useAppStore } from "@/store/app-store"; import { getElectronAPI } from "@/lib/electron"; import { CheckCircle2, Loader2, Terminal, Key, ArrowRight, ArrowLeft, ExternalLink, Copy, AlertCircle, RefreshCw, Download, } from "lucide-react"; import { toast } from "sonner"; import { StatusBadge, TerminalOutput } from "../components"; import { useCliStatus, useCliInstallation, useTokenSave, } from "../hooks"; interface CodexSetupStepProps { onNext: () => void; onBack: () => void; onSkip: () => void; } export function CodexSetupStep({ onNext, onBack, onSkip, }: CodexSetupStepProps) { const { codexCliStatus, codexAuthStatus, setCodexCliStatus, setCodexAuthStatus, setCodexInstallProgress, } = useSetupStore(); const { setApiKeys, apiKeys } = useAppStore(); const [showApiKeyInput, setShowApiKeyInput] = useState(false); const [apiKey, setApiKey] = useState(""); // Use custom hooks const { isChecking, checkStatus } = useCliStatus({ cliType: "codex", statusApi: () => getElectronAPI().setup?.getCodexStatus() || Promise.reject(), setCliStatus: setCodexCliStatus, setAuthStatus: setCodexAuthStatus, }); const { isInstalling, installProgress, install } = useCliInstallation({ cliType: "codex", installApi: () => getElectronAPI().setup?.installCodex() || Promise.reject(), onProgressEvent: getElectronAPI().setup?.onInstallProgress, onSuccess: checkStatus, }); const { isSaving: isSavingKey, saveToken: saveApiKeyToken } = useTokenSave({ provider: "openai", onSuccess: () => { setCodexAuthStatus({ authenticated: true, method: "api_key", apiKeyValid: true, }); setApiKeys({ ...apiKeys, openai: apiKey }); setShowApiKeyInput(false); checkStatus(); }, }); // Sync install progress to store useEffect(() => { setCodexInstallProgress({ isInstalling, output: installProgress.output, }); }, [isInstalling, installProgress, setCodexInstallProgress]); // Check status on mount useEffect(() => { checkStatus(); }, [checkStatus]); const copyCommand = (command: string) => { navigator.clipboard.writeText(command); toast.success("Command copied to clipboard"); }; const isAuthenticated = codexAuthStatus?.authenticated || apiKeys.openai; const getAuthMethodLabel = () => { if (!isAuthenticated) return null; if (apiKeys.openai) return "API Key (Manual)"; if (codexAuthStatus?.method === "api_key") return "API Key (Auth File)"; if (codexAuthStatus?.method === "env") return "API Key (Environment)"; if (codexAuthStatus?.method === "cli_verified") return "CLI Login (ChatGPT)"; return "Authenticated"; }; return (
OpenAI's GPT-5.1 Codex for advanced code generation
npm install -g @openai/codex
Requires Node.js to be installed. If the auto-install fails, try running the command manually in your terminal.
Authenticate via CLI
Run this command in your terminal:
codex auth login
Get your API key from{" "}
platform.openai.com
Codex is ready to use!
{getAuthMethodLabel() && `Authenticated via ${getAuthMethodLabel()}. `} You can proceed to complete setup