2 import { AlertCircle, Loader2 } from '@lucide/svelte';
3 import { X } from '@lucide/svelte';
4 import { ActionIcon } from '$lib/components/app';
5 import * as Tooltip from '$lib/components/ui/tooltip';
6 import { mcpStore } from '$lib/stores/mcp.svelte';
7 import type { MCPResourceAttachment } from '$lib/types';
8 import { getResourceDisplayName, getResourceIcon } from '$lib/utils';
11 attachment: MCPResourceAttachment;
14 onRemove?: (attachmentId: string) => void;
17 let { attachment, class: className, onclick, onRemove }: Props = $props();
19 const ResourceIcon = $derived(
20 getResourceIcon(attachment.resource.mimeType, attachment.resource.uri)
22 const serverName = $derived(mcpStore.getServerDisplayName(attachment.resource.serverName));
23 const favicon = $derived(mcpStore.getServerFavicon(attachment.resource.serverName));
25 function getStatusClass(attachment: MCPResourceAttachment): string {
26 if (attachment.error) return 'border-red-500/50 bg-red-500/10';
28 if (attachment.loading) return 'border-border/50 bg-muted/30';
30 return 'border-border/50 bg-muted/30';
38 'flex flex-shrink-0 items-center gap-1.5 rounded-md border px-2 py-0.75 text-sm transition-colors',
39 getStatusClass(attachment),
40 onclick && 'cursor-pointer hover:bg-muted/50',
47 {#if attachment.loading}
48 <Loader2 class="h-3 w-3 animate-spin text-muted-foreground" />
49 {:else if attachment.error}
50 <AlertCircle class="h-3 w-3 text-red-500" />
52 <ResourceIcon class="h-3 w-3 text-muted-foreground" />
55 <span class="max-w-[150px] truncate text-xs">
56 {getResourceDisplayName(attachment.resource)}
61 class="-my-2 -mr-1.5 bg-transparent"
64 onclick={() => onRemove?.(attachment.id)}
65 stopPropagationOnClick
73 <div class="flex items-center gap-1 text-xs">
76 alt={attachment.resource.serverName}
77 class="h-3 w-3 shrink-0 rounded-sm"
79 (e.currentTarget as HTMLImageElement).style.display = 'none';
85 <span class="truncate">