"use client";
import { jsx as _jsx, jsxs as _jsxs, Fragment as _Fragment } from "react/jsx-runtime";
import { useCallback, useEffect, useMemo, useRef, useState } from "react";
import { cn } from "@stigmer/theme";
import { getUserMessage, isRetryableError } from "@stigmer/sdk";
import { timestampDate } from "@bufbuild/protobuf/wkt";
import { OAuthConnectionHealth } from "@stigmer/protos/ai/stigmer/agentic/mcpserver/v1/io_pb";
import { ValidationState } from "@stigmer/protos/ai/stigmer/agentic/mcpserver/v1/status_pb";
import { ApiResourceVisibility } from "@stigmer/protos/ai/stigmer/commons/apiresource/enum_pb";
import { useMcpServer } from "./useMcpServer";
import { useMcpServerConnect } from "./useMcpServerConnect";
import { useMcpServerCredentials } from "./useMcpServerCredentials";
import { useMcpServerOAuthConnect } from "./useMcpServerOAuthConnect";
import { useDisconnectOAuth } from "./useDisconnectOAuth";
import { useOrgOAuthApp } from "./useOrgOAuthApp";
import { OAuthAppForm } from "./OAuthAppForm";
import { ErrorMessage } from "../error/ErrorMessage";
import { EnvVarForm } from "../environment/EnvVarForm";
import { VisibilityToggle } from "../library/VisibilityToggle";
import { Tabs } from "../internal/Tabs";
/**
 * Detail view for an MCP Server integration.
 *
 * Fetches the server via {@link useMcpServer} internally and renders
 * its full configuration: validation banner (if invalid), header,
 * a **Connect bar** with a single Connect/Reconnect action, and a
 * **tabbed capabilities panel** (Tools, Policies, and optionally
 * Resources) showing read-only discovered data.
 *
 * The Connect bar above the tabs is the single entry point for
 * capability discovery and tool approval classification. It handles
 * credential gating inline — when credentials are missing, the form
 * slides in below the bar.
 *
 * Handles loading, error, and not-found states automatically.
 * Zero Console dependencies — safe for platform builder embedding.
 * All visual properties flow through `--stgm-*` design tokens.
 *
 * @example
 * ```tsx
 * // Minimal — self-contained, fetches its own data
 * <McpServerDetailView org="acme" slug="github" />
 * ```
 */
export function McpServerDetailView({ org, slug, onResourceLoad, onVisibilityChange, isVisibilityPending, defaultCapabilityTab = "tools", defaultShowCredentialForm = false, credentialPoolValues, activeOrg, className, }) {
    const { mcpServer, isLoading, error, refetch } = useMcpServer(org, slug);
    const credentials = useMcpServerCredentials(activeOrg ?? org, mcpServer ?? null);
    const connection = useMcpServerConnect();
    const oauth = useMcpServerOAuthConnect();
    const disconnectOAuth = useDisconnectOAuth();
    const orgOAuthApp = useOrgOAuthApp(mcpServer?.metadata?.id ?? null, activeOrg ?? org);
    const [showCredentialForm, setShowCredentialForm] = useState(defaultShowCredentialForm);
    const [showByoaForm, setShowByoaForm] = useState(false);
    const [capabilityTab, setCapabilityTab] = useState(defaultCapabilityTab);
    const byoaDialogRef = useRef(null);
    const onResourceLoadRef = useRef(onResourceLoad);
    onResourceLoadRef.current = onResourceLoad;
    useEffect(() => {
        if (mcpServer?.metadata?.name) {
            onResourceLoadRef.current?.({ name: mcpServer.metadata.name, id: mcpServer.metadata.id });
        }
    }, [mcpServer]);
    const handleOAuthSignIn = useCallback(async () => {
        if (!mcpServer?.metadata?.id)
            return;
        const envKeys = Object.keys(mcpServer.spec?.env ?? {});
        try {
            await oauth.startOAuth(mcpServer.metadata.id, activeOrg ?? org, envKeys);
            credentials.refetch();
            refetch();
        }
        catch {
            // error state is managed by the oauth hook
        }
    }, [mcpServer, oauth, credentials, refetch]);
    const handleConnectClick = useCallback(async () => {
        if (!mcpServer?.metadata?.id)
            return;
        if (credentials.authMode === "oauth" &&
            !credentials.isOAuthConnected &&
            !credentials.manualOverride) {
            handleOAuthSignIn();
            return;
        }
        if (!credentials.isReady) {
            setShowCredentialForm(true);
            return;
        }
        const envKeys = Object.keys(mcpServer.spec?.env ?? {});
        try {
            await connection.connect(mcpServer.metadata.id, activeOrg ?? org, undefined, envKeys);
            refetch();
        }
        catch {
            // error state is managed by the hook
        }
    }, [mcpServer, credentials.authMode, credentials.isOAuthConnected, credentials.manualOverride, credentials.isReady, connection, refetch, handleOAuthSignIn]);
    const handleCredentialSubmit = useCallback(async (values, options) => {
        try {
            if (options.saveForFuture) {
                await credentials.saveCredentials(values);
                credentials.refetch();
            }
            setShowCredentialForm(false);
            if (mcpServer?.metadata?.id) {
                const envKeys = Object.keys(mcpServer.spec?.env ?? {});
                const connectOrg = activeOrg ?? org;
                if (options.saveForFuture) {
                    await connection.connect(mcpServer.metadata.id, connectOrg, undefined, envKeys);
                }
                else {
                    await connection.connect(mcpServer.metadata.id, connectOrg, values, envKeys);
                }
                refetch();
            }
        }
        catch {
            // error state is managed by the hooks
        }
    }, [credentials, mcpServer, connection, refetch]);
    const handleDisconnect = useCallback(async () => {
        if (!mcpServer?.metadata?.id)
            return;
        try {
            await disconnectOAuth.disconnect(mcpServer.metadata.id, activeOrg ?? org);
            credentials.refetch();
            refetch();
        }
        catch {
            // error state is managed by the disconnect hook
        }
    }, [mcpServer, disconnectOAuth, credentials, refetch, activeOrg, org]);
    // BYOA dialog lifecycle — native <dialog> toggle
    useEffect(() => {
        const dialog = byoaDialogRef.current;
        if (!dialog)
            return;
        if (showByoaForm && !dialog.open) {
            dialog.showModal();
        }
        else if (!showByoaForm && dialog.open) {
            dialog.close();
        }
    }, [showByoaForm]);
    const handleByoaDialogCancel = useCallback((e) => {
        e.preventDefault();
        setShowByoaForm(false);
        orgOAuthApp.clearErrors();
    }, [orgOAuthApp]);
    const handleByoaSubmit = useCallback(async (clientId, clientSecret) => {
        await orgOAuthApp.setOrgOAuthApp(clientId, clientSecret);
        setShowByoaForm(false);
        orgOAuthApp.refetch();
        credentials.refetch();
        refetch();
    }, [orgOAuthApp, credentials, refetch]);
    const handleRemoveOrgApp = useCallback(async () => {
        await orgOAuthApp.deleteOrgOAuthApp();
        orgOAuthApp.refetch();
        credentials.refetch();
        refetch();
    }, [orgOAuthApp, credentials, refetch]);
    const spec = mcpServer?.spec;
    const status = mcpServer?.status;
    const hasSource = spec && (spec.repositoryUrl || spec.githubStars > 0);
    const specAudit = status?.audit?.specAudit;
    const capabilities = status?.discoveredCapabilities;
    const pinnedPolicies = spec?.pinnedToolApprovals ?? [];
    const classifiedPolicies = status?.toolApprovals ?? [];
    const totalPolicyCount = pinnedPolicies.length + classifiedPolicies.length;
    const tools = capabilities?.tools ?? [];
    const resourceTemplates = capabilities?.resourceTemplates ?? [];
    const hasDiscoveredTools = tools.length > 0;
    const capabilityTabs = useMemo(() => {
        const items = [
            { id: "tools", label: "Tools", badge: tools.length },
            { id: "policies", label: "Policies", badge: totalPolicyCount },
        ];
        if (resourceTemplates.length > 0) {
            items.push({
                id: "resources",
                label: "Resources",
                badge: resourceTemplates.length,
            });
        }
        return items;
    }, [tools.length, totalPolicyCount, resourceTemplates.length]);
    const combinedError = connection.error ?? oauth.error;
    const combinedClearError = useCallback(() => {
        connection.clearError();
        oauth.clearError();
    }, [connection, oauth]);
    if (isLoading)
        return _jsx(LoadingSkeleton, { className: className });
    if (error)
        return _jsx(ErrorMessage, { error: error, retry: refetch, className: className });
    if (!mcpServer)
        return _jsx(NotFoundState, { className: className });
    return (_jsxs("div", { className: cn("flex flex-col gap-6", className), children: [status?.validationState === ValidationState.invalid &&
                status.validationMessage && (_jsx(ValidationBanner, { message: status.validationMessage })), _jsx(Header, { server: mcpServer, createdAt: specAudit?.createdAt ? timestampDate(specAudit.createdAt) : null, updatedAt: specAudit?.updatedAt ? timestampDate(specAudit.updatedAt) : null, lastDiscoveredAt: capabilities?.lastDiscoveredAt
                    ? timestampDate(capabilities.lastDiscoveredAt)
                    : null, onVisibilityChange: onVisibilityChange, isVisibilityPending: isVisibilityPending }), hasSource && _jsx(SourceSection, { spec: spec }), spec?.serverType.case && (_jsx(ServerConfigSection, { serverType: spec.serverType })), spec?.env && Object.keys(spec.env).length > 0 && (_jsx(EnvSection, { data: spec.env, oauthTargetEnvVar: credentials.oauthTargetEnvVar })), _jsxs(Section, { title: "Connection", children: [_jsx(ConnectBar, { isConnecting: connection.isConnecting || oauth.isInProgress, connectionError: combinedError, onConnect: handleConnectClick, onClearConnectionError: combinedClearError, hasDiscoveredTools: hasDiscoveredTools, toolCount: tools.length, policyCount: totalPolicyCount, credentialsLoading: credentials.isLoading, oauthPhase: oauth.phase, authMode: credentials.authMode, isOAuthConnected: credentials.isOAuthConnected, connectionHealth: credentials.connectionHealth, canDisconnect: credentials.canDisconnect, onDisconnect: handleDisconnect, isDisconnecting: disconnectOAuth.isDisconnecting, disconnectError: disconnectOAuth.error, onClearDisconnectError: disconnectOAuth.clearError, serverName: mcpServer?.metadata?.name ?? slug, accessTokenExpiresAt: credentials.accessTokenExpiresAt, tokenLifetimeHint: credentials.tokenLifetimeHint, isVendorApprovalPending: credentials.isVendorApprovalPending, isVendorApprovalBlocked: credentials.isVendorApprovalBlocked, vendorApprovalDocsUrl: credentials.vendorApprovalDocsUrl, canBringOwnApp: credentials.canBringOwnApp, isOrgOAuthApp: credentials.isOrgOAuthApp, onBringOwnApp: () => setShowByoaForm(true), onRemoveOrgApp: handleRemoveOrgApp, isRemovingOrgApp: orgOAuthApp.isDeleting, removeOrgAppError: orgOAuthApp.deleteError, onClearRemoveOrgAppError: orgOAuthApp.clearErrors, manualOverride: credentials.manualOverride, onManualOverride: () => {
                            credentials.setManualOverride(true);
                            setShowCredentialForm(true);
                        }, onBackToOAuth: () => {
                            credentials.setManualOverride(false);
                            setShowCredentialForm(false);
                        }, onCancelOAuth: oauth.clearError }), showCredentialForm && credentials.missingVariables.length > 0 && (_jsx("div", { className: "border-b border-border p-4", "data-cursor-target": "credential-form", children: _jsx(EnvVarForm, { title: "Credentials Required", description: "Enter the credentials needed to connect to this MCP server. Toggle \"Save for future runs\" to persist them in your personal environment, or leave it off for one-time use.", variables: credentials.missingVariables, onSubmit: (values, options) => handleCredentialSubmit(values, options), onCancel: () => setShowCredentialForm(false), isSubmitting: credentials.isSaving, poolValues: credentialPoolValues, className: "w-full max-w-md" }) }))] }), _jsxs("dialog", { ref: byoaDialogRef, onCancel: handleByoaDialogCancel, className: cn("m-auto w-full max-w-md rounded-lg border border-border bg-background p-6 shadow-lg", "backdrop:bg-black/50"), children: [_jsx("h3", { className: "mb-4 text-base font-semibold text-foreground", children: "Use your own OAuth app" }), _jsx(OAuthAppForm, { providerName: mcpServer?.metadata?.name ?? slug, vendorDocsUrl: credentials.vendorApprovalDocsUrl, onSubmit: handleByoaSubmit, onCancel: () => {
                            setShowByoaForm(false);
                            orgOAuthApp.clearErrors();
                        }, isSubmitting: orgOAuthApp.isSetting, error: orgOAuthApp.setError })] }), _jsx(Section, { title: "Capabilities", children: _jsxs(Tabs, { tabs: capabilityTabs, activeTab: capabilityTab, onTabChange: (id) => setCapabilityTab(id), "aria-label": "MCP server capabilities", children: [capabilityTab === "tools" && (_jsx(ToolsTabContent, { tools: tools })), capabilityTab === "policies" && (_jsx(PoliciesTabContent, { pinnedPolicies: pinnedPolicies, classifiedPolicies: classifiedPolicies, hasDiscoveredTools: hasDiscoveredTools })), capabilityTab === "resources" && (_jsx(ResourceTemplatesList, { templates: resourceTemplates }))] }) }), spec && spec.tags.length > 0 && _jsx(TagsSection, { tags: spec.tags })] }));
}
// ---------------------------------------------------------------------------
// ConnectBar — single entry point for capability discovery
// ---------------------------------------------------------------------------
/** Maps an OAuthConnectionHealth enum to pill display properties. */
function healthPillProps(health, isVendorApprovalPending) {
    if (isVendorApprovalPending) {
        return {
            pillClass: "bg-amber-500/10 text-amber-600 dark:text-amber-400",
            dotClass: "bg-amber-500",
            label: "Pending approval",
        };
    }
    switch (health) {
        case OAuthConnectionHealth.OAUTH_CONNECTION_HEALTH_HEALTHY:
            return {
                pillClass: "bg-success/10 text-success",
                dotClass: "bg-success",
                label: "Connected",
            };
        case OAuthConnectionHealth.OAUTH_CONNECTION_HEALTH_TOKEN_EXPIRED_REFRESHABLE:
            return {
                pillClass: "bg-amber-500/10 text-amber-600 dark:text-amber-400",
                dotClass: "bg-amber-500",
                label: "Token expired",
            };
        case OAuthConnectionHealth.OAUTH_CONNECTION_HEALTH_TOKEN_EXPIRED:
            return {
                pillClass: "bg-destructive-subtle text-destructive",
                dotClass: "bg-destructive",
                label: "Re-auth needed",
            };
        default:
            return {
                pillClass: "bg-muted text-muted-foreground",
                dotClass: "bg-muted-foreground",
                label: "Not connected",
            };
    }
}
/** Health-aware status detail text shown alongside the pill. */
function healthStatusText(health, accessTokenExpiresAt, tokenLifetimeHint) {
    switch (health) {
        case OAuthConnectionHealth.OAUTH_CONNECTION_HEALTH_HEALTHY: {
            const expiryLabel = formatTokenExpiry(accessTokenExpiresAt);
            if (expiryLabel)
                return `Tokens refresh automatically \u00B7 ${expiryLabel}`;
            const hint = tokenLifetimeHint && tokenLifetimeHint !== "never"
                ? ` \u00B7 Session lasts ~${tokenLifetimeHint}`
                : "";
            return `Tokens refresh automatically${hint}`;
        }
        case OAuthConnectionHealth.OAUTH_CONNECTION_HEALTH_TOKEN_EXPIRED_REFRESHABLE:
            return "Will refresh automatically on next use";
        case OAuthConnectionHealth.OAUTH_CONNECTION_HEALTH_TOKEN_EXPIRED:
            return "Token expired \u2014 sign in again to reconnect";
        default:
            return "Not connected yet";
    }
}
function ConnectBar({ isConnecting, connectionError, onConnect, onClearConnectionError, hasDiscoveredTools, toolCount, policyCount, credentialsLoading, oauthPhase, authMode, isOAuthConnected, connectionHealth, canDisconnect, onDisconnect, isDisconnecting, disconnectError, onClearDisconnectError, serverName, accessTokenExpiresAt, tokenLifetimeHint, isVendorApprovalPending, isVendorApprovalBlocked, vendorApprovalDocsUrl, canBringOwnApp, isOrgOAuthApp, onBringOwnApp, onRemoveOrgApp, isRemovingOrgApp, removeOrgAppError, onClearRemoveOrgAppError, manualOverride, onManualOverride, onBackToOAuth, onCancelOAuth, }) {
    const [disconnectPhase, setDisconnectPhase] = useState("idle");
    const [removeOrgAppPhase, setRemoveOrgAppPhase] = useState("idle");
    const isOAuthBusy = oauthPhase === "initiating" ||
        oauthPhase === "awaiting-callback" ||
        oauthPhase === "completing" ||
        oauthPhase === "connecting";
    const showOAuthPrimary = authMode === "oauth" && !isOAuthConnected && !manualOverride;
    const needsReAuth = connectionHealth === OAuthConnectionHealth.OAUTH_CONNECTION_HEALTH_TOKEN_EXPIRED;
    const oauthSignInDisabled = isVendorApprovalBlocked && showOAuthPrimary && !isOrgOAuthApp;
    const anyBusy = isConnecting || isOAuthBusy || isDisconnecting || isRemovingOrgApp;
    const buttonLabel = (() => {
        if (isOAuthBusy)
            return oauthPhaseLabel(oauthPhase);
        if (isConnecting)
            return "Connecting...";
        if (isOrgOAuthApp && showOAuthPrimary)
            return "Sign in with your app";
        if (showOAuthPrimary || needsReAuth)
            return "Sign in to connect";
        if (hasDiscoveredTools)
            return "Reconnect";
        return "Connect";
    })();
    const buttonIcon = (() => {
        if (isOAuthBusy || isConnecting)
            return _jsx(Spinner, {});
        if (showOAuthPrimary || needsReAuth)
            return _jsx(OAuthIcon, { className: "size-3.5" });
        if (hasDiscoveredTools)
            return _jsx(RefreshIcon, { className: "size-3.5" });
        return _jsx(ConnectIcon, { className: "size-3.5" });
    })();
    const statusText = (() => {
        if (authMode === "oauth" && isOAuthConnected) {
            const base = healthStatusText(connectionHealth, accessTokenExpiresAt, tokenLifetimeHint);
            return isOrgOAuthApp ? `${base} \u00B7 Using your OAuth app` : base;
        }
        if (isOrgOAuthApp && showOAuthPrimary)
            return "Using your OAuth app";
        if (manualOverride)
            return "Entering token manually";
        if (hasDiscoveredTools)
            return formatConnectionSummary(toolCount, policyCount);
        return "Not connected yet";
    })();
    const pill = healthPillProps(connectionHealth, isVendorApprovalPending && !isOAuthConnected);
    const showDisconnectLink = canDisconnect && !anyBusy && !manualOverride && disconnectPhase === "idle";
    const showRemoveOrgAppLink = isOrgOAuthApp && !anyBusy && removeOrgAppPhase === "idle";
    // Inline disconnect confirmation replaces the main bar content
    if (disconnectPhase === "confirming" || disconnectPhase === "disconnecting") {
        return (_jsxs("div", { className: "flex flex-col", children: [_jsxs("div", { className: "flex items-center gap-2 px-3 py-2", children: [_jsx(WarningIcon, { className: "size-3.5 shrink-0 text-destructive" }), _jsxs("p", { className: "flex-1 text-xs text-foreground", children: ["Remove OAuth credentials for ", _jsx("span", { className: "font-medium", children: serverName }), "? You can reconnect at any time."] }), _jsxs("div", { className: "flex shrink-0 items-center gap-1.5", children: [_jsxs("button", { type: "button", disabled: isDisconnecting, onClick: async () => {
                                        setDisconnectPhase("disconnecting");
                                        try {
                                            await onDisconnect();
                                            setDisconnectPhase("idle");
                                        }
                                        catch {
                                            setDisconnectPhase("confirming");
                                        }
                                    }, className: cn("inline-flex items-center gap-1 rounded-md px-2.5 py-1 text-xs font-medium", "bg-destructive text-destructive-foreground hover:bg-destructive-hover", "disabled:pointer-events-none disabled:opacity-50"), children: [isDisconnecting && _jsx(Spinner, {}), "Disconnect"] }), _jsx("button", { type: "button", disabled: isDisconnecting, onClick: () => {
                                        setDisconnectPhase("idle");
                                        onClearDisconnectError();
                                    }, className: cn("inline-flex items-center rounded-md px-2.5 py-1 text-xs font-medium", "border border-border bg-background text-foreground hover:bg-accent hover:text-accent-foreground", "disabled:pointer-events-none disabled:opacity-50"), children: "Cancel" })] })] }), disconnectError && (_jsxs("div", { className: "flex items-start gap-2 border-t border-destructive/20 bg-destructive-subtle px-3 py-2", children: [_jsx(WarningIcon, { className: "mt-0.5 size-3.5 shrink-0 text-destructive" }), _jsx("p", { className: "flex-1 text-xs text-destructive", children: getUserMessage(disconnectError) }), _jsx("button", { type: "button", onClick: onClearDisconnectError, className: "shrink-0 text-xs text-destructive-muted hover:text-destructive", "aria-label": "Dismiss error", children: "Dismiss" })] }))] }));
    }
    // Inline "remove custom app" confirmation
    if (removeOrgAppPhase === "confirming" || removeOrgAppPhase === "removing") {
        return (_jsxs("div", { className: "flex flex-col", children: [_jsxs("div", { className: "flex items-center gap-2 px-3 py-2", children: [_jsx(WarningIcon, { className: "size-3.5 shrink-0 text-destructive" }), _jsxs("p", { className: "flex-1 text-xs text-foreground", children: ["Remove your custom OAuth app for", " ", _jsx("span", { className: "font-medium", children: serverName }), "? The server will revert to the platform's OAuth app."] }), _jsxs("div", { className: "flex shrink-0 items-center gap-1.5", children: [_jsxs("button", { type: "button", disabled: isRemovingOrgApp, onClick: async () => {
                                        setRemoveOrgAppPhase("removing");
                                        try {
                                            await onRemoveOrgApp();
                                            setRemoveOrgAppPhase("idle");
                                        }
                                        catch {
                                            setRemoveOrgAppPhase("confirming");
                                        }
                                    }, className: cn("inline-flex items-center gap-1 rounded-md px-2.5 py-1 text-xs font-medium", "bg-destructive text-destructive-foreground hover:bg-destructive-hover", "disabled:pointer-events-none disabled:opacity-50"), children: [isRemovingOrgApp && _jsx(Spinner, {}), "Remove"] }), _jsx("button", { type: "button", disabled: isRemovingOrgApp, onClick: () => {
                                        setRemoveOrgAppPhase("idle");
                                        onClearRemoveOrgAppError();
                                    }, className: cn("inline-flex items-center rounded-md px-2.5 py-1 text-xs font-medium", "border border-border bg-background text-foreground hover:bg-accent hover:text-accent-foreground", "disabled:pointer-events-none disabled:opacity-50"), children: "Cancel" })] })] }), removeOrgAppError && (_jsxs("div", { className: "flex items-start gap-2 border-t border-destructive/20 bg-destructive-subtle px-3 py-2", children: [_jsx(WarningIcon, { className: "mt-0.5 size-3.5 shrink-0 text-destructive" }), _jsx("p", { className: "flex-1 text-xs text-destructive", children: getUserMessage(removeOrgAppError) }), _jsx("button", { type: "button", onClick: onClearRemoveOrgAppError, className: "shrink-0 text-xs text-destructive-muted hover:text-destructive", "aria-label": "Dismiss error", children: "Dismiss" })] }))] }));
    }
    return (_jsxs("div", { className: "flex flex-col", children: [_jsxs("div", { className: "flex items-center justify-between px-3 py-2", children: [_jsxs("div", { className: "flex items-center gap-2", children: [authMode === "oauth" && !manualOverride && (_jsxs("span", { className: cn("inline-flex items-center gap-1.5 rounded-full px-2 py-0.5 text-[10px] font-medium", pill.pillClass), children: [_jsx("span", { className: cn("size-1.5 rounded-full", pill.dotClass), "aria-hidden": "true" }), pill.label] })), _jsx("span", { className: "text-xs text-muted-foreground", children: oauthSignInDisabled ? "OAuth sign-in is pending vendor approval" : statusText }), showDisconnectLink && (_jsx("button", { type: "button", onClick: () => setDisconnectPhase("confirming"), className: "text-[11px] text-muted-foreground underline decoration-muted-foreground/40 underline-offset-2 hover:text-foreground hover:decoration-foreground", children: "Disconnect" })), showRemoveOrgAppLink && (_jsx("button", { type: "button", onClick: () => setRemoveOrgAppPhase("confirming"), className: "text-[11px] text-muted-foreground underline decoration-muted-foreground/40 underline-offset-2 hover:text-foreground hover:decoration-foreground", children: "Remove custom app" }))] }), _jsxs("button", { type: "button", onClick: onConnect, disabled: anyBusy || credentialsLoading || oauthSignInDisabled, "data-cursor-target": "connect-button", className: cn("inline-flex items-center gap-1.5 rounded-md px-2.5 py-1 text-xs font-medium", showOAuthPrimary || needsReAuth
                            ? "bg-primary text-primary-foreground hover:bg-primary-hover"
                            : "border border-border bg-background text-foreground hover:bg-accent hover:text-accent-foreground", "disabled:pointer-events-none disabled:opacity-50"), children: [buttonIcon, buttonLabel] })] }), oauthPhase === "awaiting-callback" && (_jsx("div", { className: "flex items-center gap-3 border-t border-border px-3 py-1.5", children: _jsx("button", { type: "button", onClick: onCancelOAuth, className: "text-[11px] text-muted-foreground underline decoration-muted-foreground/40 underline-offset-2 hover:text-foreground hover:decoration-foreground", children: "Cancel sign-in" }) })), oauthSignInDisabled && (_jsxs("div", { className: "flex items-start gap-2 border-t border-amber-500/20 bg-amber-500/5 px-3 py-2", children: [_jsx(WarningIcon, { className: "mt-0.5 size-3.5 shrink-0 text-amber-600 dark:text-amber-400" }), _jsxs("div", { className: "flex-1 text-xs text-amber-700 dark:text-amber-300", children: [_jsxs("p", { children: ["The platform's OAuth app is awaiting vendor approval.", canBringOwnApp
                                        ? " You can use your own OAuth app or enter a token manually."
                                        : " You can still connect by entering your own token manually."] }), canBringOwnApp && (_jsx("button", { type: "button", onClick: onBringOwnApp, "data-cursor-target": "byoa-cta-button", className: "mt-1.5 inline-flex items-center gap-1 rounded-md bg-amber-600 px-2.5 py-1 text-[11px] font-medium text-white hover:bg-amber-700 dark:bg-amber-500 dark:text-amber-950 dark:hover:bg-amber-400", children: "Use your own OAuth app" })), vendorApprovalDocsUrl && !canBringOwnApp && (_jsxs("a", { href: vendorApprovalDocsUrl, target: "_blank", rel: "noopener noreferrer", className: "mt-1 inline-flex items-center gap-1 underline decoration-amber-600/40 underline-offset-2 hover:decoration-amber-600 dark:decoration-amber-400/40 dark:hover:decoration-amber-400", children: ["Learn how to bring your own token", _jsx(ExternalLinkIcon, { className: "size-3 shrink-0" })] }))] })] })), authMode === "oauth" && !isOAuthConnected && !isOAuthBusy && !isConnecting && (_jsx("div", { className: "flex items-center gap-3 border-t border-border px-3 py-1.5", children: manualOverride ? (_jsx("button", { type: "button", onClick: onBackToOAuth, className: "text-[11px] text-muted-foreground underline decoration-muted-foreground/40 underline-offset-2 hover:text-foreground hover:decoration-foreground", children: isVendorApprovalPending ? "Back to OAuth status" : "Sign in with OAuth instead" })) : (_jsxs(_Fragment, { children: [_jsx("button", { type: "button", onClick: onManualOverride, className: "text-[11px] text-muted-foreground underline decoration-muted-foreground/40 underline-offset-2 hover:text-foreground hover:decoration-foreground", children: "Enter token manually" }), canBringOwnApp && !isVendorApprovalBlocked && (_jsx("button", { type: "button", onClick: onBringOwnApp, className: "text-[11px] text-muted-foreground underline decoration-muted-foreground/40 underline-offset-2 hover:text-foreground hover:decoration-foreground", children: "Use your own OAuth app" }))] })) })), connectionError && (_jsxs("div", { className: "flex items-start gap-2 border-t border-destructive/20 bg-destructive-subtle px-3 py-2", role: "alert", children: [_jsx(WarningIcon, { className: "mt-0.5 size-3.5 shrink-0 text-destructive" }), _jsx("p", { className: "flex-1 text-xs text-destructive", children: getUserMessage(connectionError) }), _jsxs("div", { className: "flex shrink-0 items-center gap-2", children: [isRetryableError(connectionError) && (_jsx("button", { type: "button", onClick: () => {
                                    onClearConnectionError();
                                    onConnect();
                                }, className: "text-xs font-medium text-destructive underline underline-offset-2 hover:no-underline", children: "Try again" })), _jsx("button", { type: "button", onClick: onClearConnectionError, className: "text-xs text-destructive-muted hover:text-destructive", "aria-label": "Dismiss error", children: "Dismiss" })] })] }))] }));
}
function oauthPhaseLabel(phase) {
    switch (phase) {
        case "initiating":
            return "Starting sign-in...";
        case "awaiting-callback":
            return "Waiting for authorization...";
        case "completing":
            return "Completing sign-in...";
        case "connecting":
            return "Discovering tools...";
        default:
            return "Connecting...";
    }
}
function formatConnectionSummary(toolCount, policyCount) {
    const toolLabel = `${toolCount} tool${toolCount !== 1 ? "s" : ""}`;
    if (policyCount === 0)
        return toolLabel;
    const policyLabel = `${policyCount} ${policyCount !== 1 ? "policies" : "policy"}`;
    return `${toolLabel}, ${policyLabel}`;
}
function formatTokenExpiry(expiresAtSeconds) {
    if (expiresAtSeconds === BigInt(0))
        return null;
    const nowSeconds = BigInt(Math.floor(Date.now() / 1000));
    const remainingSeconds = expiresAtSeconds - nowSeconds;
    if (remainingSeconds <= BigInt(0))
        return "Token expired";
    const minutes = Number(remainingSeconds / BigInt(60));
    if (minutes < 1)
        return "Expires in <1 min";
    if (minutes < 60)
        return `Expires in ${minutes} min`;
    const hours = Math.floor(minutes / 60);
    if (hours < 24)
        return `Expires in ${hours}h ${minutes % 60}m`;
    const days = Math.floor(hours / 24);
    return `Expires in ${days}d`;
}
// ---------------------------------------------------------------------------
// Internal section components
// ---------------------------------------------------------------------------
function ValidationBanner({ message }) {
    return (_jsxs("div", { role: "alert", className: "flex items-start gap-2.5 rounded-lg border border-destructive/30 bg-destructive-subtle px-4 py-3", children: [_jsx(WarningIcon, { className: "mt-0.5 size-4 shrink-0 text-destructive" }), _jsxs("div", { className: "min-w-0 flex-1", children: [_jsx("p", { className: "text-sm font-medium text-destructive", children: "Invalid Configuration" }), _jsx("p", { className: "mt-0.5 text-xs text-destructive-muted", children: message })] })] }));
}
function Header({ server, createdAt, updatedAt, lastDiscoveredAt, onVisibilityChange, isVisibilityPending, }) {
    const meta = server.metadata;
    const spec = server.spec;
    const status = server.status;
    const displayName = meta?.name || meta?.slug || "Untitled";
    const isPublic = meta?.visibility === ApiResourceVisibility.visibility_public;
    return (_jsxs("div", { className: "flex items-start gap-3", children: [spec?.iconUrl ? (_jsx("img", { src: spec.iconUrl, alt: "", className: "mt-0.5 size-8 shrink-0 rounded object-cover" })) : (_jsx(McpServerIcon, { className: "mt-1 size-6 shrink-0 text-muted-foreground" })), _jsxs("div", { className: "min-w-0 flex-1", children: [_jsxs("div", { className: "flex items-center gap-2", children: [_jsx("h2", { className: "truncate text-lg font-semibold text-foreground", children: displayName }), onVisibilityChange && meta ? (_jsx(VisibilityToggle, { visibility: meta.visibility, onVisibilityChange: onVisibilityChange, isPending: isVisibilityPending })) : (isPublic && (_jsx("span", { className: "shrink-0 rounded-full bg-muted px-2 py-0.5 text-[10px] font-medium text-muted-foreground", children: "Public" })))] }), meta?.slug && (_jsx("span", { className: "mt-0.5 block truncate font-mono text-xs text-muted-foreground", children: meta.org ? `${meta.org}/${meta.slug}` : meta.slug })), _jsxs("div", { className: "mt-0.5 flex flex-wrap items-center gap-x-1.5 text-xs text-muted-foreground", children: [meta?.org && _jsx("span", { children: meta.org }), status && (_jsx(ValidationStateBadge, { state: status.validationState })), lastDiscoveredAt && (_jsxs(_Fragment, { children: [_jsx(Dot, {}), _jsxs("span", { children: ["Discovered ", formatDate(lastDiscoveredAt)] })] })), createdAt && (_jsxs(_Fragment, { children: [_jsx(Dot, {}), _jsxs("span", { children: ["Created ", formatDate(createdAt)] })] })), updatedAt && (_jsxs(_Fragment, { children: [_jsx(Dot, {}), _jsxs("span", { children: ["Updated ", formatDate(updatedAt)] })] }))] }), spec?.description && (_jsx("p", { className: "mt-2 text-sm text-muted-foreground", children: spec.description }))] })] }));
}
function ValidationStateBadge({ state, }) {
    switch (state) {
        case ValidationState.valid:
            return (_jsxs(_Fragment, { children: [_jsx(Dot, {}), _jsxs("span", { className: "inline-flex items-center gap-1 text-emerald-600 dark:text-emerald-400", children: [_jsx(CheckIcon, { className: "size-3" }), "Valid"] })] }));
        case ValidationState.invalid:
            return (_jsxs(_Fragment, { children: [_jsx(Dot, {}), _jsx("span", { className: "text-destructive", children: "Invalid" })] }));
        default:
            return null;
    }
}
function ServerConfigSection({ serverType, }) {
    return (_jsx(Section, { title: "Server Configuration", children: _jsxs("div", { className: "flex flex-col gap-2 p-3", children: [_jsxs("div", { className: "flex items-baseline gap-2", children: [_jsx("span", { className: "text-xs font-medium text-muted-foreground", children: "Type" }), _jsx("span", { className: "rounded bg-muted px-1.5 py-0.5 font-mono text-xs font-medium text-foreground", children: serverType.case })] }), serverType.case === "stdio" && (_jsxs(_Fragment, { children: [_jsxs("div", { className: "flex items-baseline gap-2", children: [_jsx("span", { className: "text-xs font-medium text-muted-foreground", children: "Command" }), _jsxs("code", { className: "font-mono text-sm text-foreground", children: [serverType.value.command, serverType.value.args.length > 0 &&
                                            ` ${serverType.value.args.join(" ")}`] })] }), serverType.value.workingDir && (_jsxs("div", { className: "flex items-baseline gap-2", children: [_jsx("span", { className: "text-xs font-medium text-muted-foreground", children: "Working Dir" }), _jsx("code", { className: "font-mono text-xs text-foreground", children: serverType.value.workingDir })] }))] })), serverType.case === "http" && (_jsxs(_Fragment, { children: [_jsxs("div", { className: "flex items-baseline gap-2", children: [_jsx("span", { className: "text-xs font-medium text-muted-foreground", children: "URL" }), _jsx("code", { className: "break-all font-mono text-sm text-foreground", children: serverType.value.url })] }), serverType.value.timeoutSeconds > 0 && (_jsxs("div", { className: "flex items-baseline gap-2", children: [_jsx("span", { className: "text-xs font-medium text-muted-foreground", children: "Timeout" }), _jsxs("span", { className: "text-xs text-foreground", children: [serverType.value.timeoutSeconds, "s"] })] }))] }))] }) }));
}
function SourceSection({ spec, }) {
    return (_jsx(Section, { title: "Source", children: _jsxs("div", { className: "flex flex-col gap-2 p-3", children: [spec.repositoryUrl && (_jsxs("div", { className: "flex items-baseline gap-2", children: [_jsx("span", { className: "shrink-0 text-xs font-medium text-muted-foreground", children: "Repository" }), _jsxs("a", { href: spec.repositoryUrl, target: "_blank", rel: "noopener noreferrer", className: "inline-flex items-center gap-1 break-all font-mono text-xs text-foreground underline decoration-muted-foreground/40 underline-offset-2 hover:decoration-foreground", children: [spec.repositoryUrl, _jsx(ExternalLinkIcon, { className: "size-3 shrink-0" })] })] })), spec.githubStars > 0 && (_jsxs("div", { className: "flex items-baseline gap-2", children: [_jsx("span", { className: "shrink-0 text-xs font-medium text-muted-foreground", children: "Stars" }), _jsx("span", { className: "text-xs text-foreground", children: spec.githubStars.toLocaleString() })] }))] }) }));
}
function ResourceTemplatesList({ templates, }) {
    if (templates.length === 0)
        return null;
    return (_jsx("div", { className: "flex flex-col divide-y divide-border", children: templates.map((tpl) => (_jsxs("div", { className: "px-3 py-2.5", children: [_jsxs("div", { className: "flex items-baseline gap-2", children: [_jsx("span", { className: "text-sm font-medium text-foreground", children: tpl.name }), _jsx("code", { className: "font-mono text-[10px] text-muted-foreground", children: tpl.uriTemplate })] }), tpl.description && (_jsx("p", { className: "mt-0.5 text-xs text-muted-foreground", children: tpl.description }))] }, tpl.uriTemplate || tpl.name))) }));
}
function EnvSection({ data, oauthTargetEnvVar, }) {
    const entries = Object.entries(data).sort(([a], [b]) => a.localeCompare(b));
    return (_jsx(Section, { title: `Environment Variables (${entries.length})`, children: _jsx("div", { className: "flex flex-col divide-y divide-border", children: entries.map(([name, env]) => {
                const isOAuthManaged = name === oauthTargetEnvVar;
                return (_jsxs("div", { className: "flex items-start gap-3 px-3 py-2", children: [_jsx("code", { className: "shrink-0 font-mono text-sm font-medium text-foreground", children: name }), _jsx("span", { className: "shrink-0 rounded bg-muted px-1.5 py-0.5 text-[10px] font-medium text-muted-foreground", children: env.isSecret ? "secret" : "config" }), isOAuthManaged && (_jsx("span", { className: "shrink-0 rounded bg-primary-subtle px-1.5 py-0.5 text-[10px] font-medium text-primary", children: "oauth" })), env.optional && (_jsx("span", { className: "shrink-0 rounded bg-muted px-1.5 py-0.5 text-[10px] font-medium text-muted-foreground-subtle", children: "optional" })), env.description && (_jsx("span", { className: "text-xs text-muted-foreground", children: env.description }))] }, name));
            }) }) }));
}
function TagsSection({ tags }) {
    return (_jsx(Section, { title: `Tags (${tags.length})`, children: _jsx("div", { className: "flex flex-wrap gap-1.5 p-3", children: tags.map((tag) => (_jsx("span", { className: "rounded-full bg-muted px-2.5 py-0.5 text-xs font-medium text-muted-foreground", children: tag }, tag))) }) }));
}
// ---------------------------------------------------------------------------
// Capability tab contents (read-only)
// ---------------------------------------------------------------------------
function ToolsTabContent({ tools, }) {
    if (tools.length === 0) {
        return (_jsxs("div", { className: "px-3 py-8 text-center", children: [_jsx(ConnectIcon, { className: "mx-auto mb-2 size-6 text-muted-foreground-faint" }), _jsx("p", { className: "text-xs text-muted-foreground", children: "Connect to this MCP server to discover its available tools." })] }));
    }
    return (_jsx("div", { className: "flex flex-col divide-y divide-border", children: tools.map((tool) => (_jsxs("div", { className: "px-3 py-2.5", children: [_jsx("code", { className: "font-mono text-sm font-medium text-foreground", children: tool.name }), tool.description && (_jsx("p", { className: "mt-0.5 text-xs text-muted-foreground", children: tool.description }))] }, tool.name))) }));
}
function PoliciesTabContent({ pinnedPolicies, classifiedPolicies, hasDiscoveredTools, }) {
    const hasPinnedPolicies = pinnedPolicies.length > 0;
    const hasClassifiedPolicies = classifiedPolicies.length > 0;
    const hasAnyPolicies = hasPinnedPolicies || hasClassifiedPolicies;
    if (!hasAnyPolicies) {
        return (_jsxs("div", { className: "px-3 py-8 text-center", children: [_jsx(ShieldIcon, { className: "mx-auto mb-2 size-6 text-muted-foreground-faint" }), _jsx("p", { className: "text-xs text-muted-foreground", children: hasDiscoveredTools
                        ? "No approval policies yet. Reconnect to reclassify tools."
                        : "Connect to discover tools and auto-classify approval policies." })] }));
    }
    return (_jsxs("div", { className: "flex flex-col", children: [hasPinnedPolicies && (_jsx(PolicyGroup, { icon: _jsx(PinIcon, { className: "size-3.5" }), label: "Pinned", policies: pinnedPolicies })), hasClassifiedPolicies && (_jsx(PolicyGroup, { icon: _jsx(SparklesIcon, { className: "size-3.5" }), label: "Auto-classified", policies: classifiedPolicies }))] }));
}
function PolicyGroup({ icon, label, policies, }) {
    return (_jsxs("div", { className: "flex flex-col", children: [_jsxs("div", { className: "flex items-center gap-1.5 border-b border-border bg-muted-faint px-3 py-1.5", children: [_jsx("span", { className: "text-muted-foreground", children: icon }), _jsx("span", { className: "text-[10px] font-medium uppercase tracking-wider text-muted-foreground", children: label }), _jsxs("span", { className: "text-[10px] text-muted-foreground", children: ["(", policies.length, ")"] })] }), _jsx("div", { className: "flex flex-col divide-y divide-border", children: policies.map((policy) => (_jsxs("div", { className: "px-3 py-2.5", children: [_jsxs("div", { className: "flex items-baseline gap-2", children: [_jsx("code", { className: "font-mono text-sm font-medium text-foreground", children: policy.toolName }), _jsx(ShieldIcon, { className: "size-3 text-amber-500 dark:text-amber-400" })] }), policy.message && (_jsx("p", { className: "mt-0.5 text-xs text-muted-foreground", children: policy.message }))] }, policy.toolName))) })] }));
}
// ---------------------------------------------------------------------------
// Shared layout primitives
// ---------------------------------------------------------------------------
function Section({ title, children, }) {
    return (_jsxs("section", { children: [_jsx("h3", { className: "mb-2 text-xs font-medium uppercase tracking-wider text-muted-foreground", children: title }), _jsx("div", { className: "overflow-hidden rounded-lg border border-border", children: children })] }));
}
function Dot() {
    return (_jsx("span", { className: "shrink-0", "aria-hidden": "true", children: "\u00B7" }));
}
// ---------------------------------------------------------------------------
// Non-happy states
// ---------------------------------------------------------------------------
function LoadingSkeleton({ className }) {
    return (_jsxs("div", { className: cn("flex flex-col gap-6", className), "aria-busy": "true", "aria-label": "Loading MCP server details", children: [_jsxs("div", { className: "flex items-start gap-3", children: [_jsx("div", { className: "mt-1 size-6 shrink-0 animate-pulse rounded bg-muted" }), _jsxs("div", { className: "flex-1 space-y-2", children: [_jsx("div", { className: "h-5 w-48 animate-pulse rounded bg-muted" }), _jsx("div", { className: "h-3 w-64 animate-pulse rounded bg-muted" }), _jsx("div", { className: "h-4 w-full max-w-md animate-pulse rounded bg-muted" })] })] }), [24, 48, 16, 12].map((h, i) => (_jsxs("div", { className: "space-y-2", children: [_jsx("div", { className: "h-3 w-28 animate-pulse rounded bg-muted" }), _jsx("div", { className: "animate-pulse rounded-lg border border-border bg-muted-faint", style: { height: `${h * 4}px` } })] }, i)))] }));
}
function NotFoundState({ className }) {
    return (_jsxs("div", { role: "status", className: cn("flex flex-col items-center gap-2 py-12 text-center", className), children: [_jsx(McpServerIcon, { className: "size-10 text-muted-foreground-faint" }), _jsx("p", { className: "text-sm font-medium text-muted-foreground", children: "MCP Server not found" }), _jsx("p", { className: "text-xs text-muted-foreground-subtle", children: "This MCP server doesn't exist or you don't have access to it." })] }));
}
// ---------------------------------------------------------------------------
// Utilities
// ---------------------------------------------------------------------------
function formatDate(date) {
    return date.toLocaleDateString("en-US", {
        month: "short",
        day: "numeric",
        year: "numeric",
    });
}
// ---------------------------------------------------------------------------
// Icons — inline SVGs following the SDK pattern (no icon library dependency)
// ---------------------------------------------------------------------------
function McpServerIcon({ className }) {
    return (_jsxs("svg", { className: className, viewBox: "0 0 16 16", fill: "none", stroke: "currentColor", strokeWidth: "1.5", strokeLinecap: "round", strokeLinejoin: "round", "aria-hidden": "true", children: [_jsx("rect", { x: "2", y: "2", width: "12", height: "5", rx: "1" }), _jsx("rect", { x: "2", y: "9", width: "12", height: "5", rx: "1" }), _jsx("circle", { cx: "5", cy: "4.5", r: "0.75", fill: "currentColor", stroke: "none" }), _jsx("circle", { cx: "5", cy: "11.5", r: "0.75", fill: "currentColor", stroke: "none" })] }));
}
function CheckIcon({ className }) {
    return (_jsx("svg", { className: className, viewBox: "0 0 16 16", fill: "none", stroke: "currentColor", strokeWidth: "2", strokeLinecap: "round", strokeLinejoin: "round", "aria-hidden": "true", children: _jsx("path", { d: "m3 8.5 3.5 3.5 6.5-8" }) }));
}
function WarningIcon({ className }) {
    return (_jsxs("svg", { className: className, viewBox: "0 0 16 16", fill: "none", stroke: "currentColor", strokeWidth: "1.5", strokeLinecap: "round", strokeLinejoin: "round", "aria-hidden": "true", children: [_jsx("path", { d: "M8 1.5 1 14h14L8 1.5Z" }), _jsx("path", { d: "M8 6v3.5" }), _jsx("circle", { cx: "8", cy: "11.5", r: "0.5", fill: "currentColor", stroke: "none" })] }));
}
function ConnectIcon({ className }) {
    return (_jsxs("svg", { className: className, viewBox: "0 0 16 16", fill: "none", stroke: "currentColor", strokeWidth: "1.5", strokeLinecap: "round", strokeLinejoin: "round", "aria-hidden": "true", children: [_jsx("path", { d: "M6.5 6.5 4.25 4.25" }), _jsx("path", { d: "m9.5 9.5 2.25 2.25" }), _jsx("rect", { x: "1.5", y: "1.5", width: "5", height: "5", rx: "1" }), _jsx("rect", { x: "9.5", y: "9.5", width: "5", height: "5", rx: "1" }), _jsx("path", { d: "m6.5 9.5-3 3" }), _jsx("path", { d: "m9.5 6.5 3-3" })] }));
}
function RefreshIcon({ className }) {
    return (_jsxs("svg", { className: className, viewBox: "0 0 16 16", fill: "none", stroke: "currentColor", strokeWidth: "1.5", strokeLinecap: "round", strokeLinejoin: "round", "aria-hidden": "true", children: [_jsx("path", { d: "M2.5 8a5.5 5.5 0 0 1 9.36-3.92" }), _jsx("path", { d: "M13.5 8a5.5 5.5 0 0 1-9.36 3.92" }), _jsx("path", { d: "M12 2v3h-3" }), _jsx("path", { d: "M4 14v-3h3" })] }));
}
function ShieldIcon({ className }) {
    return (_jsx("svg", { className: className, viewBox: "0 0 16 16", fill: "none", stroke: "currentColor", strokeWidth: "1.5", strokeLinecap: "round", strokeLinejoin: "round", "aria-hidden": "true", children: _jsx("path", { d: "M8 1.5 2.5 4v4c0 3.31 2.35 6.4 5.5 7 3.15-.6 5.5-3.69 5.5-7V4L8 1.5Z" }) }));
}
function PinIcon({ className }) {
    return (_jsxs("svg", { className: className, viewBox: "0 0 16 16", fill: "none", stroke: "currentColor", strokeWidth: "1.5", strokeLinecap: "round", strokeLinejoin: "round", "aria-hidden": "true", children: [_jsx("path", { d: "M9.5 2.5 13.5 6.5" }), _jsx("path", { d: "M5 7 3 14l7-2" }), _jsx("path", { d: "m5 7 2-2 4.5-1 1.5 1.5-1 4.5-2 2z" })] }));
}
function SparklesIcon({ className }) {
    return (_jsx("svg", { className: className, viewBox: "0 0 16 16", fill: "none", stroke: "currentColor", strokeWidth: "1.5", strokeLinecap: "round", strokeLinejoin: "round", "aria-hidden": "true", children: _jsx("path", { d: "M8 1v2M8 13v2M1 8h2M13 8h2M3.05 3.05l1.41 1.41M11.54 11.54l1.41 1.41M3.05 12.95l1.41-1.41M11.54 4.46l1.41-1.41" }) }));
}
function OAuthIcon({ className }) {
    return (_jsxs("svg", { className: className, viewBox: "0 0 16 16", fill: "none", stroke: "currentColor", strokeWidth: "1.5", strokeLinecap: "round", strokeLinejoin: "round", "aria-hidden": "true", children: [_jsx("rect", { x: "1.5", y: "5", width: "13", height: "8", rx: "1.5" }), _jsx("path", { d: "M4.5 5V3.5a3.5 3.5 0 0 1 7 0V5" }), _jsx("circle", { cx: "8", cy: "9.5", r: "1.25" })] }));
}
function ExternalLinkIcon({ className }) {
    return (_jsxs("svg", { className: className, viewBox: "0 0 16 16", fill: "none", stroke: "currentColor", strokeWidth: "1.5", strokeLinecap: "round", strokeLinejoin: "round", "aria-hidden": "true", children: [_jsx("path", { d: "M12 8.667v4A1.333 1.333 0 0 1 10.667 14H3.333A1.333 1.333 0 0 1 2 12.667V5.333A1.333 1.333 0 0 1 3.333 4h4" }), _jsx("path", { d: "M10 2h4v4" }), _jsx("path", { d: "M6.667 9.333 14 2" })] }));
}
function Spinner() {
    return (_jsx("svg", { width: "14", height: "14", viewBox: "0 0 16 16", fill: "none", stroke: "currentColor", strokeWidth: "2", strokeLinecap: "round", className: "animate-spin", "aria-hidden": "true", children: _jsx("path", { d: "M8 2a6 6 0 1 0 6 6" }) }));
}
//# sourceMappingURL=McpServerDetailView.js.map