diff --git a/app/electron/services/claude-cli-detector.js b/app/electron/services/claude-cli-detector.js index ba18e915..2a8f193c 100644 --- a/app/electron/services/claude-cli-detector.js +++ b/app/electron/services/claude-cli-detector.js @@ -611,7 +611,39 @@ class ClaudeCliDetector { } send("Opening system terminal for authentication...\n"); - return await new Promise((resolve, reject) => { + // Helper function to check if a command exists asynchronously + const commandExists = (cmd) => { + return new Promise((resolve) => { + require("child_process").exec( + `which ${cmd}`, + { timeout: 1000 }, + (error) => { + resolve(!error); + } + ); + }); + }; + + // For Linux, find available terminal first (async) + let linuxTerminal = null; + if (platform !== "win32" && platform !== "darwin") { + const terminals = [ + ["gnome-terminal", ["--", claudePath, "setup-token"]], + ["konsole", ["-e", claudePath, "setup-token"]], + ["xterm", ["-e", claudePath, "setup-token"]], + ["x-terminal-emulator", ["-e", `${claudePath} setup-token`]], + ]; + + for (const [term, termArgs] of terminals) { + const exists = await commandExists(term); + if (exists) { + linuxTerminal = { command: term, args: termArgs }; + break; + } + } + } + + return new Promise((resolve, reject) => { // Open command in external terminal since Claude CLI requires TTY let command, args; @@ -629,27 +661,8 @@ class ClaudeCliDetector { 'tell application "Terminal" to activate', ]; } else { - // Linux: Try common terminal emulators - const terminals = [ - ["gnome-terminal", ["--", claudePath, "setup-token"]], - ["konsole", ["-e", claudePath, "setup-token"]], - ["xterm", ["-e", claudePath, "setup-token"]], - ["x-terminal-emulator", ["-e", `${claudePath} setup-token`]], - ]; - - // Try to find an available terminal - for (const [term, termArgs] of terminals) { - try { - execSync(`which ${term}`, { stdio: "ignore" }); - command = term; - args = termArgs; - break; - } catch { - // Terminal not found, try next - } - } - - if (!command) { + // Linux: Use the terminal we found earlier + if (!linuxTerminal) { reject({ success: false, error: @@ -658,6 +671,8 @@ class ClaudeCliDetector { }); return; } + command = linuxTerminal.command; + args = linuxTerminal.args; } console.log( diff --git a/app/src/components/views/setup-view/components/auth-method-selector.tsx b/app/src/components/views/setup-view/components/auth-method-selector.tsx index 283bba10..75d06e52 100644 --- a/app/src/components/views/setup-view/components/auth-method-selector.tsx +++ b/app/src/components/views/setup-view/components/auth-method-selector.tsx @@ -14,33 +14,68 @@ interface AuthMethodSelectorProps { onSelect: (methodId: string) => void; } +// Map badge colors to complete Tailwind class names +const getBadgeClasses = (badgeColor: string) => { + const colorMap: Record = { + "brand-500": { + border: "hover:border-brand-500/50", + bg: "hover:bg-brand-500/5", + text: "text-brand-500", + }, + "green-500": { + border: "hover:border-green-500/50", + bg: "hover:bg-green-500/5", + text: "text-green-500", + }, + "blue-500": { + border: "hover:border-blue-500/50", + bg: "hover:bg-blue-500/5", + text: "text-blue-500", + }, + "purple-500": { + border: "hover:border-purple-500/50", + bg: "hover:bg-purple-500/5", + text: "text-purple-500", + }, + }; + + return colorMap[badgeColor] || { + border: "hover:border-brand-500/50", + bg: "hover:bg-brand-500/5", + text: "text-brand-500", + }; +}; + export function AuthMethodSelector({ options, onSelect, }: AuthMethodSelectorProps) { return (
- {options.map((option) => ( -
- - ))} + + ); + })} ); }