"use client"; import { useId } from "react"; import type { SyntaxHighlighterProps } from "@assistant-ui/react-streamdown"; import { CheckIcon, CopyIcon, DownloadIcon } from "lucide-react"; import { PreviewCard } from "@base-ui/react/preview-card"; import { useCopyToClipboard } from "@assistant-ui/ui/hooks/use-copy-to-clipboard"; import { analytics } from "@/lib/analytics"; import { trackXuluxDownload, useXuluxAnalytics, withXuluxContext, } from "@/lib/xulux/analytics-context"; export type OpenInData = { title: string; downloadUrl?: string; prompt?: string; }; function isValidOpenInUrl(url: unknown): url is string { if (typeof url !== "string" || url.trim().length === 0) return false; if (url.includes("<") || url.includes(">")) return false; if (/from-tool-result|placeholder| ); } function CodexLogo() { return ( ); } function CursorLogo() { return ( ); } function ConductorLogo() { return ( ); } function ChatGPTLogo() { return ( ); } function VSCodeLogo() { return ( ); } const PLATFORM_LOGOS = [ { id: "claude", Logo: ClaudeLogo }, { id: "codex", Logo: CodexLogo }, { id: "vscode", Logo: VSCodeLogo }, { id: "cursor", Logo: CursorLogo }, { id: "conductor", Logo: ConductorLogo }, { id: "chatgpt", Logo: ChatGPTLogo }, ] as const; export function OpenInCard({ title, downloadUrl, prompt: agentPrompt, }: OpenInData) { const analyticsCtx = useXuluxAnalytics(); const prompt = buildPrompt({ title, ...(downloadUrl ? { downloadUrl } : {}), ...(agentPrompt ? { prompt: agentPrompt } : {}), }); const { isCopied, copyToClipboard } = useCopyToClipboard(); const validDownloadUrl = isValidOpenInUrl(downloadUrl) ? downloadUrl : undefined; const hasDownload = Boolean(validDownloadUrl); const promptPreviewId = useId(); return (
{/* Row 1: headline + decorative logos */}
Continue in your coding agent {PLATFORM_LOGOS.map(({ id, Logo }) => ( ))}
{/* Row 2: actions */}
{hasDownload && ( <> trackXuluxDownload(analyticsCtx, { surface: "open_in_card", download_type: "demo", }) } className="border-border bg-background hover:bg-muted inline-flex size-8 items-center justify-center rounded-md border transition-colors" > or )} { copyToClipboard(prompt); analytics.xulux.converted( withXuluxContext(analyticsCtx, { action: "copy_prompt", surface: "open_in_card", }), ); }} className="bg-foreground text-background hover:bg-foreground/90 inline-flex h-8 items-center gap-1.5 rounded-md px-3.5 text-xs font-medium transition-colors" aria-describedby={promptPreviewId} /> } > {isCopied ? ( ) : ( )} {isCopied ? "Copied!" : "Copy prompt"}
Prompt preview
                  {prompt}
                
); } export function OpenInSyntaxHighlighter({ code }: SyntaxHighlighterProps) { let data: OpenInData; try { data = JSON.parse(code) as OpenInData; } catch { return null; } if (!data.title) return null; const downloadUrl = isValidOpenInUrl(data.downloadUrl) ? data.downloadUrl : undefined; return ( ); }