"use client"; import { useState } from "react"; import Link from "next/link"; import { IconLoader2, IconLock, IconSettings } from "@tabler/icons-react"; import { Badge } from "@kandev/ui/badge"; import { Button } from "@kandev/ui/button"; import { Card, CardContent } from "@kandev/ui/card"; import { Tooltip, TooltipContent, TooltipTrigger } from "@kandev/ui/tooltip"; import { AgentLogo } from "@/components/agent-logo"; import { AgentLoginDialog } from "@/components/settings/agent-login-dialog"; import { HostShellDialog } from "@/components/settings/host-shell-dialog"; import type { Agent, AgentDiscovery } from "@/lib/types/http"; type Props = { agent: AgentDiscovery; savedAgent: Agent | undefined; displayName: string; /** Capability status from the host utility probe ("ok", "auth_required", etc.). */ capabilityStatus?: string; /** * Called when the auth/shell dialog closes so the page can refresh * discovery + availability. Without this the yellow lock stays put even * after a successful sign-in, making the recovery flow look broken. */ onAuthComplete?: () => void; }; /** * Card rendered under "Installed Agents" - links to the agent profile * editor and surfaces a yellow lock icon when the capability probe reports * `auth_required`. Clicking the lock opens a PTY login dialog if the agent * type has a registered LoginCommand. */ export function InstalledAgentCard({ agent, savedAgent, displayName, capabilityStatus, onAuthComplete, }: Props) { const configured = Boolean(savedAgent && savedAgent.profiles.length > 0); const hasAgentRecord = Boolean(savedAgent); const [loginOpen, setLoginOpen] = useState(false); const [shellOpen, setShellOpen] = useState(false); const authRequired = capabilityStatus === "auth_required"; const probing = capabilityStatus === "probing"; const loginAvailable = Boolean(agent.login_command); // Either we have a registered login command (open the dedicated login PTY) // or we don't (open a plain host shell so the user can explore via // ` --help`, run their own auth recipe, etc.). const handleAuthClick = () => { if (loginAvailable) setLoginOpen(true); else setShellOpen(true); }; return (

{displayName}

{agent.supports_mcp && MCP} {configured && Configured} {probing && ( Checking agent capabilities and authentication... )} {authRequired && ( {loginAvailable ? "Authentication required - click to open login terminal" : "Authentication required - click to open a shell and sign in"} )}
{/* Reserve two lines so cards align regardless of path length. */}

{agent.matched_path ? `Detected at ${agent.matched_path}` : ""}

); } function AuthDialogs({ agent, loginOpen, setLoginOpen, shellOpen, setShellOpen, loginAvailable, onAuthComplete, }: { agent: AgentDiscovery; loginOpen: boolean; setLoginOpen: (open: boolean) => void; shellOpen: boolean; setShellOpen: (open: boolean) => void; loginAvailable: boolean; onAuthComplete?: () => void; }) { if (loginAvailable) { return ( ); } return ; }