@arbidocs/react 0.5.29 → 0.5.31

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -6,10 +6,10 @@ import { getCollisionPadding, usePortalContainer, DropdownMenu, DropdownMenuTrig
6
6
  import { cn } from './chunk-SN5YV6FF.js';
7
7
  import { useHostConfigRecord } from './chunk-CPZ36AQS.js';
8
8
  import * as React from 'react';
9
- import React__default, { forwardRef, memo, useState, useRef, useEffect, useCallback, useId, useMemo, Fragment as Fragment$1 } from 'react';
9
+ import React__default, { forwardRef, memo, useState, useRef, useEffect, useId, useCallback, useMemo, Fragment as Fragment$1 } from 'react';
10
10
  import { createPortal } from 'react-dom';
11
11
  import { jsx, jsxs, Fragment } from 'react/jsx-runtime';
12
- import { Check, ChevronDown, ChevronUp, Circle, Search, MessageCircleMore, MoreVertical, Loader2, Square, Mic, BadgeCheck, MessageSquareLock, Info, FileQuestion, BookOpen, Upload, LogOut, LayoutGrid, Bell, MessageSquare, CircleUserRound, Wrench, CreditCard, ClipboardList, UserPlus, UserStar, Settings2, Users, User, NotebookPen, NotebookText, Building2, Contact, Scale, Tags, StickyNote, FolderPlus, Hash, EyeOff, Eye, CaptionsOff, FolderOpen, MessageSquareMore, MessageSquarePlus, MessageSquareText, MessageSquareOff, MessagesSquare, Columns3Cog, SquarePlus, SquareM, ChevronsDown, Bot, Calendar, Folder, List, SquareCheckBig, Minus, Plus, Share2, CheckCircle2, FileText, Crown, MessageSquareShare, ChevronsUpDown, X, AlertTriangle, FileX, SkipForward, XCircle, CheckCircle } from 'lucide-react';
12
+ import { Check, MessageCircleMore, ChevronDown, ChevronUp, Circle, Search, MoreVertical, Loader2, Square, Mic, BadgeCheck, MessageSquareLock, Info, FileQuestion, BookOpen, Upload, LogOut, LayoutGrid, Bell, MessageSquare, CircleUserRound, Wrench, CreditCard, ClipboardList, UserPlus, UserStar, Settings2, Users, User, NotebookPen, NotebookText, Building2, Contact, Scale, Tags, StickyNote, FolderPlus, Hash, EyeOff, Eye, CaptionsOff, FolderOpen, MessageSquareMore, MessageSquarePlus, MessageSquareText, MessageSquareOff, MessagesSquare, Columns3Cog, SquarePlus, SquareM, ChevronsDown, Bot, Calendar, Folder, List, SquareCheckBig, Minus, Plus, MessageSquareShare, Share2, CheckCircle2, FileText, Crown, ChevronsUpDown, X, AlertTriangle, FileX, SkipForward, XCircle, CheckCircle } from 'lucide-react';
13
13
  import * as CheckboxPrimitive from '@radix-ui/react-checkbox';
14
14
  import { cva } from 'class-variance-authority';
15
15
  import * as SelectPrimitive from '@radix-ui/react-select';
@@ -2246,6 +2246,14 @@ function InlineMicButton({
2246
2246
  )
2247
2247
  ] });
2248
2248
  }
2249
+ function ThreadVisibilityIcon({
2250
+ shared,
2251
+ className,
2252
+ ...props
2253
+ }) {
2254
+ const Icon2 = shared ? MessageSquareShare : MessageSquareLock;
2255
+ return /* @__PURE__ */ jsx(Icon2, { ...props, className: cn(shared ? "text-secondary" : "text-primary", className) });
2256
+ }
2249
2257
  var ENTITY_MAPPINGS = {
2250
2258
  PRODUCT: {
2251
2259
  NAMES: {
@@ -2575,2457 +2583,2449 @@ var VisibilityIcon = ({
2575
2583
  className: [isShared ? "text-secondary" : "text-primary", className].filter(Boolean).join(" ")
2576
2584
  });
2577
2585
  };
2578
- var Select = SelectPrimitive.Root;
2579
- var SelectGroup = SelectPrimitive.Group;
2580
- var SelectValue = SelectPrimitive.Value;
2581
- function SelectPortal({
2582
- container,
2583
- ...props
2584
- }) {
2585
- const fallback = usePortalContainer();
2586
- return /* @__PURE__ */ jsx(SelectPrimitive.Portal, { container: container ?? fallback, ...props });
2586
+
2587
+ // src/entities/tag-kinds.ts
2588
+ var KIND_ENTITY = {
2589
+ label: "LABEL",
2590
+ annotation: "ANNOTATION",
2591
+ search: "SAVED_SEARCH",
2592
+ issue: "ISSUE",
2593
+ person: "PERSON",
2594
+ organisation: "ORGANISATION"
2595
+ };
2596
+ function tagKindTitle(kind, { plural = false } = {}) {
2597
+ return getEntityLabel(KIND_ENTITY[kind], plural ? "PLURAL" : "SINGULAR");
2587
2598
  }
2588
- var SelectTrigger = React.forwardRef(({ className, children, ...props }, ref) => /* @__PURE__ */ jsxs(
2589
- SelectPrimitive.Trigger,
2590
- {
2591
- ref,
2592
- className: cn(
2593
- "flex h-9 pointer-coarse:min-h-11 w-full items-center justify-between rounded-md border border-input bg-background px-3 py-2 text-sm placeholder:text-muted-foreground/60 focus:outline-none focus-visible:border-ring/50 disabled:cursor-not-allowed disabled:opacity-50 [&>span]:line-clamp-1",
2594
- className
2595
- ),
2596
- ...props,
2597
- children: [
2598
- children,
2599
- /* @__PURE__ */ jsx(SelectPrimitive.Icon, { asChild: true, children: /* @__PURE__ */ jsx(ChevronDown, { className: "h-4 w-4 opacity-50" }) })
2600
- ]
2601
- }
2602
- ));
2603
- SelectTrigger.displayName = SelectPrimitive.Trigger.displayName;
2604
- var SelectScrollUpButton = React.forwardRef(({ className, ...props }, ref) => /* @__PURE__ */ jsx(
2605
- SelectPrimitive.ScrollUpButton,
2606
- {
2607
- ref,
2608
- className: cn("flex cursor-default items-center justify-center py-1", className),
2609
- ...props,
2610
- children: /* @__PURE__ */ jsx(ChevronUp, { className: "h-4 w-4" })
2611
- }
2612
- ));
2613
- SelectScrollUpButton.displayName = SelectPrimitive.ScrollUpButton.displayName;
2614
- var SelectScrollDownButton = React.forwardRef(({ className, ...props }, ref) => /* @__PURE__ */ jsx(
2615
- SelectPrimitive.ScrollDownButton,
2616
- {
2617
- ref,
2618
- className: cn("flex cursor-default items-center justify-center py-1", className),
2619
- ...props,
2620
- children: /* @__PURE__ */ jsx(ChevronDown, { className: "h-4 w-4" })
2621
- }
2622
- ));
2623
- SelectScrollDownButton.displayName = SelectPrimitive.ScrollDownButton.displayName;
2624
- var SelectContent = React.forwardRef(({ className, children, position = "popper", ...props }, ref) => /* @__PURE__ */ jsx(SelectPortal, { children: /* @__PURE__ */ jsxs(
2625
- SelectPrimitive.Content,
2626
- {
2627
- ref,
2628
- className: cn(
2629
- "relative z-50 max-h-[min(24rem,var(--radix-select-content-available-height))] min-w-[8rem] max-w-[calc(100vw-1rem)] overflow-hidden rounded-md border bg-popover text-popover-foreground shadow-lg data-[state=open]:animate-in data-[state=closed]:animate-out data-[state=closed]:fade-out-0 data-[state=open]:fade-in-0 data-[state=closed]:zoom-out-95 data-[state=open]:zoom-in-95 data-[side=bottom]:slide-in-from-top-2 data-[side=left]:slide-in-from-right-2 data-[side=right]:slide-in-from-left-2 data-[side=top]:slide-in-from-bottom-2",
2630
- position === "popper" && "data-[side=bottom]:translate-y-1 data-[side=left]:-translate-x-1 data-[side=right]:translate-x-1 data-[side=top]:-translate-y-1",
2631
- className
2632
- ),
2633
- position,
2634
- collisionPadding: getCollisionPadding(),
2635
- ...props,
2636
- children: [
2637
- /* @__PURE__ */ jsx(SelectScrollUpButton, {}),
2638
- /* @__PURE__ */ jsx(
2639
- SelectPrimitive.Viewport,
2640
- {
2641
- className: cn(
2642
- "p-1",
2643
- position === "popper" && "h-[var(--radix-select-trigger-height)] w-full min-w-[var(--radix-select-trigger-width)]"
2644
- ),
2645
- children
2646
- }
2647
- ),
2648
- /* @__PURE__ */ jsx(SelectScrollDownButton, {})
2649
- ]
2650
- }
2651
- ) }));
2652
- SelectContent.displayName = SelectPrimitive.Content.displayName;
2653
- var SelectLabel = React.forwardRef(({ className, ...props }, ref) => /* @__PURE__ */ jsx(
2654
- SelectPrimitive.Label,
2655
- {
2656
- ref,
2657
- className: cn("py-1.5 pl-8 pr-2 text-sm font-semibold", className),
2658
- ...props
2659
- }
2660
- ));
2661
- SelectLabel.displayName = SelectPrimitive.Label.displayName;
2662
- var SelectItem = React.forwardRef(({ className, children, ...props }, ref) => /* @__PURE__ */ jsxs(
2663
- SelectPrimitive.Item,
2664
- {
2665
- ref,
2666
- className: cn(
2667
- "relative flex w-full cursor-default select-none items-center rounded-sm py-1.5 pl-8 pr-2 pointer-coarse:min-h-11 text-sm outline-none focus:bg-accent focus:text-accent-foreground data-[disabled]:pointer-events-none data-[disabled]:opacity-50",
2668
- className
2669
- ),
2670
- ...props,
2671
- children: [
2672
- /* @__PURE__ */ jsx("span", { className: "absolute left-2 flex h-3.5 w-3.5 items-center justify-center", children: /* @__PURE__ */ jsx(SelectPrimitive.ItemIndicator, { children: /* @__PURE__ */ jsx(Check, { className: "h-4 w-4" }) }) }),
2673
- /* @__PURE__ */ jsx(SelectPrimitive.ItemText, { children })
2674
- ]
2675
- }
2676
- ));
2677
- SelectItem.displayName = SelectPrimitive.Item.displayName;
2678
- var SelectSeparator = React.forwardRef(({ className, ...props }, ref) => /* @__PURE__ */ jsx(
2679
- SelectPrimitive.Separator,
2680
- {
2681
- ref,
2682
- className: cn("-mx-1 my-1 h-px bg-muted", className),
2683
- ...props
2599
+ function tagKindNouns(kind) {
2600
+ return {
2601
+ singular: tagKindTitle(kind).toLowerCase(),
2602
+ plural: tagKindTitle(kind, { plural: true }).toLowerCase()
2603
+ };
2604
+ }
2605
+ var VARIANT_STYLES = {
2606
+ "mine-paid": {
2607
+ pill: "text-primary",
2608
+ icon: "text-primary"
2609
+ },
2610
+ other: {
2611
+ pill: "text-secondary",
2612
+ icon: "text-secondary"
2613
+ },
2614
+ "mine-free": {
2615
+ pill: "text-muted-foreground",
2616
+ icon: "text-muted-foreground"
2617
+ },
2618
+ common: {
2619
+ pill: "",
2620
+ icon: "text-muted-foreground"
2684
2621
  }
2685
- ));
2686
- SelectSeparator.displayName = SelectPrimitive.Separator.displayName;
2687
- var COLORS = {
2688
- text: "text-secondary",
2689
- bg: "bg-secondary"
2690
2622
  };
2691
- function isItemShared(item) {
2692
- return item.shared === true || item.is_shared === true;
2623
+ function resolveVariant(relation, paid, hasCollaborators) {
2624
+ if (relation === "common") return "common";
2625
+ if (relation === "other") return "other";
2626
+ if (relation === "mine") return paid ? "mine-paid" : "mine-free";
2627
+ if (paid) return hasCollaborators ? "other" : "mine-paid";
2628
+ return "mine-free";
2693
2629
  }
2694
- function VisibilityToggle({
2695
- items,
2696
- presentation = "toggle",
2697
- onToggle,
2698
- disabled = false,
2699
- disabledTooltip,
2700
- disablePrivate = false,
2701
- showLabel = true,
2702
- showTooltip = true,
2703
- tooltipActive,
2704
- tooltipInactive,
2705
- tooltipMixed,
2706
- label = "Visibility",
2707
- workspaceLabel = getEntityLabel("WORKSPACE"),
2708
- "data-testid": dataTestId
2630
+ function ProjectEntity({
2631
+ name,
2632
+ label,
2633
+ icon,
2634
+ subscription = "none",
2635
+ hasCollaborators = false,
2636
+ size = "sm",
2637
+ className,
2638
+ onClick,
2639
+ relation,
2640
+ isPaid,
2641
+ tooltipContent
2709
2642
  }) {
2710
- const itemsArray = useMemo(() => Array.isArray(items) ? items : [items], [items]);
2711
- const { isAllShared, isMixed } = useMemo(() => {
2712
- if (itemsArray.length === 0) return { isAllShared: false, isMixed: false };
2713
- const sharedCount = itemsArray.filter(isItemShared).length;
2714
- return {
2715
- isAllShared: sharedCount === itemsArray.length,
2716
- isMixed: sharedCount > 0 && sharedCount < itemsArray.length
2717
- };
2718
- }, [itemsArray]);
2719
- const isSingle = itemsArray.length === 1;
2720
- const defaultTooltipActive = `Hide${isSingle ? "" : " all"} from ${workspaceLabel} members`;
2721
- const defaultTooltipInactive = `Make${isSingle ? "" : " all"} visible to ${workspaceLabel} members`;
2722
- const defaultTooltipMixed = `Make all visible to ${workspaceLabel} members (some already shared)`;
2723
- const handleToggle = () => {
2724
- const shouldShare = !isAllShared;
2725
- if (disablePrivate && !shouldShare) return;
2726
- onToggle(shouldShare);
2727
- };
2728
- if (presentation === "select")
2729
- return /* @__PURE__ */ jsxs(
2730
- Select,
2731
- {
2732
- value: isMixed ? "mixed" : isAllShared ? "workspace" : "me",
2733
- onValueChange: (value) => onToggle(value === "workspace"),
2734
- disabled: disabled || !itemsArray.length,
2735
- children: [
2736
- /* @__PURE__ */ jsxs(
2737
- SelectTrigger,
2738
- {
2739
- "aria-label": label,
2740
- "data-testid": dataTestId,
2741
- className: "h-7 w-auto gap-1 border-0 bg-transparent px-1 text-xs font-normal text-muted-foreground shadow-none hover:bg-muted pointer-coarse:h-11",
2742
- children: [
2743
- showLabel && /* @__PURE__ */ jsxs("span", { children: [
2744
- label,
2745
- ":"
2746
- ] }),
2747
- /* @__PURE__ */ jsx(SelectValue, {})
2748
- ]
2749
- }
2750
- ),
2751
- /* @__PURE__ */ jsxs(SelectContent, { children: [
2752
- /* @__PURE__ */ jsx(SelectItem, { value: "me", disabled: disablePrivate, children: "Me" }),
2753
- /* @__PURE__ */ jsx(SelectItem, { value: "workspace", children: "Workspace" }),
2754
- isMixed && /* @__PURE__ */ jsx(SelectItem, { value: "mixed", disabled: true, children: "Mixed" })
2755
- ] })
2756
- ]
2757
- }
2758
- );
2643
+ const paid = isPaid ?? (subscription === "active" || subscription === "past_due" || subscription === "dev");
2644
+ const variant = resolveVariant(relation, paid, hasCollaborators);
2645
+ const { pill, icon: iconClass } = VARIANT_STYLES[variant];
2646
+ const iconSizeClass = size === "base" ? "h-4 w-4" : "h-3.5 w-3.5";
2647
+ const iconNode = icon ?? /* @__PURE__ */ jsx(CreditCard, { className: cn(iconSizeClass, iconClass) });
2759
2648
  return /* @__PURE__ */ jsx(
2760
- IconToggle,
2649
+ EntityPill,
2761
2650
  {
2762
- icon: Share2,
2763
- isActive: isAllShared,
2764
- onToggle: handleToggle,
2765
- colors: COLORS,
2766
- inactiveColors: { text: "text-primary", bg: "bg-primary/10" },
2767
- disabled: disabled || itemsArray.length === 0,
2768
- disabledTooltip,
2769
- showLabel,
2770
- showTooltip,
2771
- label,
2772
- isMixed,
2773
- tooltipActive: tooltipActive || defaultTooltipActive,
2774
- tooltipInactive: tooltipInactive || defaultTooltipInactive,
2775
- tooltipMixed: tooltipMixed || defaultTooltipMixed,
2776
- "data-testid": dataTestId
2651
+ icon: iconNode,
2652
+ label: label ?? name,
2653
+ size,
2654
+ shape: "rounded",
2655
+ className: cn(pill, className),
2656
+ onClick,
2657
+ tooltipContent
2777
2658
  }
2778
2659
  );
2779
2660
  }
2780
- var COLORS2 = {
2781
- text: "text-green-text",
2782
- bg: "bg-green-text"
2661
+ var ArbiBotHeadIcon = ({ size = 24, className = "" }) => {
2662
+ const maskId = useId();
2663
+ return /* @__PURE__ */ jsxs(
2664
+ "svg",
2665
+ {
2666
+ xmlns: "http://www.w3.org/2000/svg",
2667
+ width: size,
2668
+ height: size,
2669
+ viewBox: "30 -5 190 190",
2670
+ preserveAspectRatio: "xMidYMid meet",
2671
+ className,
2672
+ children: [
2673
+ /* @__PURE__ */ jsx("defs", { children: /* @__PURE__ */ jsx("mask", { id: maskId, children: /* @__PURE__ */ jsxs("g", { transform: "translate(0,250) scale(0.1,-0.1)", children: [
2674
+ /* @__PURE__ */ jsx("rect", { x: "0", y: "0", width: "2500", height: "2500", fill: "white" }),
2675
+ /* @__PURE__ */ jsx("circle", { cx: "855", cy: "1715", r: "190", fill: "black" }),
2676
+ /* @__PURE__ */ jsx("circle", { cx: "855", cy: "1715", r: "50", fill: "white" }),
2677
+ /* @__PURE__ */ jsx("circle", { cx: "1665", cy: "1700", r: "190", fill: "black" }),
2678
+ /* @__PURE__ */ jsx("circle", { cx: "1665", cy: "1700", r: "50", fill: "white" })
2679
+ ] }) }) }),
2680
+ /* @__PURE__ */ jsxs("g", { mask: `url(#${maskId})`, children: [
2681
+ /* @__PURE__ */ jsx(
2682
+ "g",
2683
+ {
2684
+ transform: "translate(0,250) scale(0.1,-0.1)",
2685
+ fill: "currentColor",
2686
+ stroke: "currentColor",
2687
+ strokeWidth: "100",
2688
+ children: /* @__PURE__ */ jsx("path", { d: "M1038 2434 c-217 -39 -406 -154 -522 -318 -121 -170 -176 -376 -103 -384 l27 -3 0 -106 c0 -88 -3 -108 -17 -118 -15 -11 -16 -18 -5 -66 44 -188 209 -369 420 -459 l65 -28 -74 -7 c-283 -26 -444 -152 -535 -418 -70 -204 -73 -507 -5 -507 4 0 12 75 19 168 18 263 68 419 167 530 78 87 224 162 263 134 9 -6 43 -26 76 -43 224 -117 802 -95 948 38 38 34 165 -22 253 -111 117 -119 168 -268 187 -549 6 -92 15 -167 19 -167 89 0 53 415 -54 627 -88 173 -238 270 -458 295 l-99 11 75 32 c201 88 367 274 406 454 10 47 9 56 -5 66 -13 10 -16 32 -16 118 l0 106 28 3 c91 10 -12 297 -165 459 -202 214 -544 307 -895 243z m472 -84 c170 -43 323 -140 416 -264 47 -61 117 -197 128 -248 l6 -28 -65 0 c-64 0 -65 1 -78 33 -43 102 -109 136 -262 137 l-110 0 -38 -40 c-25 -27 -46 -40 -65 -41 -134 -5 -394 1 -410 10 -11 6 -30 24 -42 41 l-21 30 -112 0 c-156 -1 -219 -33 -262 -136 -14 -34 -14 -34 -80 -34 -76 0 -74 -7 -30 103 96 243 311 406 595 452 118 20 319 13 430 -15z m-561 -505 c97 -50 126 -174 61 -263 -118 -163 -380 -23 -309 165 35 93 162 143 248 98z m799 -15 c129 -96 69 -304 -92 -318 -189 -16 -265 218 -106 326 48 33 149 29 198 -8z m272 -389 c0 -23 -45 -110 -86 -168 -245 -343 -856 -408 -1231 -130 -90 67 -213 236 -213 294 0 11 132 13 765 13 457 0 765 -4 765 -9z" })
2689
+ }
2690
+ ),
2691
+ /* @__PURE__ */ jsxs("g", { transform: "translate(0,250) scale(0.1,-0.1)", fill: "currentColor", stroke: "none", children: [
2692
+ /* @__PURE__ */ jsx("path", { d: "M785 1777 c-60 -60 -59 -134 1 -186 92 -82 236 9 204 128 -25 93 -138 125 -205 58z m161 -29 c7 -22 -19 -52 -40 -45 -21 7 -30 35 -17 51 19 23 48 20 57 -6z" }),
2693
+ /* @__PURE__ */ jsx("path", { d: "M1591 1803 c-128 -67 -85 -243 60 -243 83 0 141 99 105 178 -32 69 -103 97 -165 65z m127 -59 c4 -25 -19 -47 -41 -38 -22 8 -30 34 -16 51 17 20 53 12 57 -13z" }),
2694
+ /* @__PURE__ */ jsx("path", { d: "M843 1347 c-9 -15 9 -63 41 -108 148 -202 565 -209 730 -12 37 44 60 103 47 116 -13 13 -810 17 -818 4z" })
2695
+ ] })
2696
+ ] })
2697
+ ]
2698
+ }
2699
+ );
2783
2700
  };
2784
- function VerifiedToggle({
2785
- verified,
2786
- onToggle,
2787
- disabled = false,
2788
- showLabel = true,
2789
- showTooltip = true,
2790
- tooltipActive,
2791
- tooltipInactive,
2792
- "data-testid": dataTestId
2793
- }) {
2701
+ function VerifiedBadge({ className, label = "Identity verified" }) {
2794
2702
  return /* @__PURE__ */ jsx(
2795
- IconToggle,
2703
+ BadgeCheck,
2796
2704
  {
2797
- icon: CheckCircle2,
2798
- isActive: verified,
2799
- onToggle,
2800
- colors: COLORS2,
2801
- disabled,
2802
- showLabel,
2803
- label: "Verified",
2804
- showTooltip,
2805
- tooltipActive: tooltipActive || "Verified by a human \u2014 click to unverify",
2806
- tooltipInactive: tooltipInactive || "Not verified \u2014 click to verify",
2807
- "data-testid": dataTestId
2705
+ role: "img",
2706
+ "aria-label": label,
2707
+ "data-testid": "verified-badge",
2708
+ className: cn("h-3.5 w-3.5 shrink-0 text-sky-500", className),
2709
+ children: /* @__PURE__ */ jsx("title", { children: label })
2808
2710
  }
2809
2711
  );
2810
2712
  }
2811
-
2812
- // src/lib/format-friendly-date.ts
2813
- function formatFriendlyDate(dateString, includeTime = true) {
2814
- if (!dateString) return "";
2815
- try {
2816
- if (dateString.includes("Today") || dateString.includes("Yesterday") || /\w+ \d+, \d+:\d+:\d+/.test(dateString)) {
2817
- return dateString;
2818
- }
2819
- if (/^\d{1,2}:\d{2}(:\d{2})?$/.test(dateString)) {
2820
- return dateString;
2821
- }
2822
- const date = new Date(dateString);
2823
- if (isNaN(date.getTime())) return dateString;
2824
- const timeOptions = { hour: "2-digit", minute: "2-digit" };
2825
- const timeString = date.toLocaleTimeString([], timeOptions);
2826
- const now = /* @__PURE__ */ new Date();
2827
- const today = now.toDateString();
2828
- const yesterday = new Date(now);
2829
- yesterday.setDate(yesterday.getDate() - 1);
2830
- if (date.toDateString() === today) {
2831
- return includeTime ? `Today, ${timeString}` : "today";
2832
- } else if (date.toDateString() === yesterday.toDateString()) {
2833
- return includeTime ? `Yesterday, ${timeString}` : "yesterday";
2834
- } else {
2835
- const dateOptions = {
2836
- month: "short",
2837
- day: "numeric"
2838
- };
2839
- if (date.getFullYear() !== now.getFullYear()) {
2840
- dateOptions.year = "numeric";
2713
+ var sizeClasses = {
2714
+ xs: "h-5 w-5",
2715
+ sm: "h-6 w-6",
2716
+ md: "h-8 w-8",
2717
+ lg: "h-10 w-10"
2718
+ };
2719
+ var textSizeClasses = {
2720
+ xs: "text-xs",
2721
+ sm: "text-xs",
2722
+ md: "text-xs",
2723
+ lg: "text-sm"
2724
+ };
2725
+ var presenceDotClasses = {
2726
+ xs: "w-2 h-2 border",
2727
+ sm: "w-2.5 h-2.5 border",
2728
+ md: "w-3 h-3 border-2",
2729
+ lg: "w-3.5 h-3.5 border-2"
2730
+ };
2731
+ var presencePositionClasses = {
2732
+ xs: "-right-1 bottom-0",
2733
+ sm: "-right-1 bottom-0",
2734
+ md: "-right-1.5 -bottom-0.5",
2735
+ lg: "-right-1.5 -bottom-0.5"
2736
+ };
2737
+ var PRESENCE_LABELS = {
2738
+ connected: "Online",
2739
+ connecting: "Connecting",
2740
+ disconnected: "Offline",
2741
+ error: "Connection problem",
2742
+ hidden: "Status hidden"
2743
+ };
2744
+ var presenceColorClasses = {
2745
+ connected: "bg-status-online",
2746
+ connecting: "bg-status-connecting",
2747
+ disconnected: "bg-status-away",
2748
+ error: "bg-status-busy",
2749
+ hidden: "bg-status-offline"
2750
+ };
2751
+ var UserEntity = memo(function UserEntity2({
2752
+ size = "md",
2753
+ variant = "pill",
2754
+ className,
2755
+ showTooltip = true,
2756
+ interactive = true,
2757
+ hasUnreadMessages = false,
2758
+ initials = "",
2759
+ displayName = "",
2760
+ picture,
2761
+ avatarImageClassName,
2762
+ colorClass = "",
2763
+ isAgent: isAgent2 = false,
2764
+ isVerified = false,
2765
+ agentStyle,
2766
+ avatarStyle,
2767
+ isMe = false,
2768
+ displayStatus,
2769
+ onClick,
2770
+ tooltipContent,
2771
+ empty = false
2772
+ }) {
2773
+ if (empty) {
2774
+ return /* @__PURE__ */ jsx(
2775
+ Avatar,
2776
+ {
2777
+ className: cn(sizeClasses[size], "border border-border", className),
2778
+ "data-testid": "user-entity",
2779
+ children: /* @__PURE__ */ jsx(AvatarFallback, { className: "bg-status-empty text-muted-foreground text-xs font-semibold", children: "?" })
2841
2780
  }
2842
- const formattedDate = date.toLocaleDateString([], dateOptions);
2843
- return includeTime ? `${formattedDate}, ${timeString}` : formattedDate;
2844
- }
2845
- } catch {
2846
- return dateString;
2781
+ );
2847
2782
  }
2848
- }
2849
-
2850
- // src/lib/markdown-to-text.ts
2851
- function markdownToPlainText(input) {
2852
- if (!input) return "";
2853
- return input.replace(/```[^\n]*\n?/g, "").replace(/!\[([^\]]*)\]\([^)]*\)/g, "$1").replace(/\[([^\]]+)\]\([^)]*\)/g, "$1").replace(/^[ \t]*#{1,6}[ \t]+/gm, "").replace(/^[ \t]*>[ \t]?/gm, "").replace(/^[ \t]*([-*+]|\d+[.)])[ \t]+/gm, "").replace(/(\*\*|__)(.*?)\1/g, "$2").replace(/(\*|_)(.*?)\1/g, "$2").replace(/`([^`]*)`/g, "$1").replace(/\s+/g, " ").trim();
2854
- }
2855
- var TABLE_DELIMITER_ROW = /^\s*\|?\s*:?-{3,}:?\s*(\|\s*:?-{3,}:?\s*)*\|?\s*$/;
2856
- function splitTableRow(line) {
2857
- return line.trim().replace(/^\|/, "").replace(/(?<!\\)\|$/, "").split(/(?<!\\)\|/).map((cell) => cell.trim().replace(/\\\|/g, "|"));
2858
- }
2859
- function flattenMarkdownTables(input) {
2860
- const lines = input.split("\n");
2861
- const out = [];
2862
- for (let i = 0; i < lines.length; i++) {
2863
- const isTableStart = lines[i].includes("|") && i + 1 < lines.length && lines[i + 1].includes("|") && TABLE_DELIMITER_ROW.test(lines[i + 1]);
2864
- if (!isTableStart) {
2865
- out.push(lines[i]);
2866
- continue;
2783
+ const agentBadge = isAgent2 ? /* @__PURE__ */ jsx(ArbiBotHeadIcon, { className: "w-3.5 h-3.5 text-muted-foreground" }) : void 0;
2784
+ const canMessage = interactive && !isMe && !isAgent2;
2785
+ const showUnread = hasUnreadMessages && !isMe && !isAgent2;
2786
+ const surfaceStyle = avatarStyle ?? agentStyle;
2787
+ const avatarCore = /* @__PURE__ */ jsxs(
2788
+ Avatar,
2789
+ {
2790
+ className: cn(
2791
+ sizeClasses[size],
2792
+ isAgent2 ? "rounded-full border-2 border-dashed" : "border border-white"
2793
+ ),
2794
+ style: surfaceStyle,
2795
+ "data-testid": "user-entity",
2796
+ children: [
2797
+ picture && /* @__PURE__ */ jsx(AvatarImage, { src: picture, alt: initials, className: avatarImageClassName }),
2798
+ /* @__PURE__ */ jsx(
2799
+ AvatarFallback,
2800
+ {
2801
+ className: cn(
2802
+ textSizeClasses[size],
2803
+ "font-semibold leading-none",
2804
+ isAgent2 ? "rounded-full bg-transparent" : `text-white ${colorClass}`
2805
+ ),
2806
+ style: surfaceStyle,
2807
+ children: initials
2808
+ }
2809
+ )
2810
+ ]
2867
2811
  }
2868
- out.push(splitTableRow(lines[i]).join(" "));
2869
- i += 1;
2870
- while (i + 1 < lines.length && lines[i + 1].includes("|") && lines[i + 1].trim()) {
2871
- i += 1;
2872
- out.push(splitTableRow(lines[i]).join(" "));
2812
+ );
2813
+ const statusDot = showUnread || displayStatus ? /* @__PURE__ */ jsx(
2814
+ "span",
2815
+ {
2816
+ className: cn(
2817
+ "absolute rounded-full border-white",
2818
+ presenceDotClasses[size],
2819
+ presencePositionClasses[size],
2820
+ !showUnread && displayStatus ? presenceColorClasses[displayStatus] : ""
2821
+ ),
2822
+ style: showUnread ? { backgroundColor: "#00adef" } : void 0,
2823
+ "data-testid": "user-entity-presence",
2824
+ role: "img",
2825
+ "aria-label": showUnread ? "Unread messages" : PRESENCE_LABELS[displayStatus],
2826
+ title: showUnread ? "Unread messages" : PRESENCE_LABELS[displayStatus]
2873
2827
  }
2874
- }
2875
- return out.join("\n");
2876
- }
2877
- function markdownToPlainTextBlocks(input) {
2878
- if (!input) return "";
2879
- return flattenMarkdownTables(input).replace(/^[ \t]*([-*_])([ \t]*\1){2,}[ \t]*$/gm, "").replace(/```[^\n]*\n?/g, "").replace(/!\[([^\]]*)\]\([^)]*\)/g, "$1").replace(/\[([^\]]+)\]\(([^)\s]+)\)/g, "$1 ($2)").replace(/^[ \t]*#{1,6}[ \t]+/gm, "").replace(/^[ \t]*>[ \t]?/gm, "").replace(/(\*\*|__)(?=\S)(.+?)(?<=\S)\1/g, "$2").replace(/\*(?=\S)(.+?)(?<=\S)\*/g, "$1").replace(/(^|[^\w])_(?=\S)(.+?)(?<=\S)_(?!\w)/g, "$1$2").replace(/`([^`]*)`/g, "$1").replace(/[ \t]+\n/g, "\n").replace(/\n{3,}/g, "\n\n").trim();
2880
- }
2881
-
2882
- // src/ui/DictateContext.tsx
2883
- function useDictateContext() {
2884
- return useHostConfigRecord().dictate ?? null;
2885
- }
2886
- var Input = React.forwardRef(
2887
- ({ className, type, dictate, onFocus, onBlur, ...props }, forwardedRef) => {
2888
- const dictateCtx = useDictateContext();
2889
- const [focused, setFocused] = React.useState(false);
2890
- const innerRef = React.useRef(null);
2891
- React.useImperativeHandle(forwardedRef, () => innerRef.current);
2892
- const showDictate = dictate && !!dictateCtx && !props.disabled && !props.readOnly;
2893
- const input = /* @__PURE__ */ jsx(
2894
- "input",
2895
- {
2896
- type,
2897
- "data-slot": "input",
2898
- className: cn(
2899
- "flex h-9 pointer-coarse:h-11 w-full rounded-md border border-input bg-background px-3 py-1 text-base shadow-sm transition-colors file:border-0 file:bg-transparent file:text-sm file:font-medium file:text-foreground placeholder:text-muted-foreground/60 focus-visible:outline-none focus-visible:border-ring/50 disabled:cursor-not-allowed disabled:opacity-50 md:text-sm",
2900
- showDictate && "pr-9",
2901
- className
2902
- ),
2903
- ref: innerRef,
2904
- onFocus: (e) => {
2905
- setFocused(true);
2906
- onFocus?.(e);
2907
- },
2908
- onBlur: (e) => {
2909
- setFocused(false);
2910
- onBlur?.(e);
2911
- },
2912
- ...props
2913
- }
2914
- );
2915
- if (!showDictate) return input;
2916
- return /* @__PURE__ */ jsxs("div", { className: "relative w-full", children: [
2917
- input,
2918
- /* @__PURE__ */ jsx(
2919
- InlineMicButton,
2828
+ ) : null;
2829
+ const avatarElement = statusDot ? /* @__PURE__ */ jsxs(
2830
+ "div",
2831
+ {
2832
+ className: cn(
2833
+ "relative inline-block",
2834
+ sizeClasses[size],
2835
+ variant === "pill" ? "" : className
2836
+ ),
2837
+ children: [
2838
+ avatarCore,
2839
+ statusDot
2840
+ ]
2841
+ }
2842
+ ) : /* @__PURE__ */ jsx("div", { className: cn("inline-block", variant === "pill" ? "" : className), children: avatarCore });
2843
+ const pillAvatar = (
2844
+ // shrink-0: when the pill is squeezed the NAME truncates away — the avatar
2845
+ // must never collapse under it and overflow onto neighbouring text.
2846
+ /* @__PURE__ */ jsxs("span", { className: cn("relative inline-block shrink-0", sizeClasses[size]), children: [
2847
+ /* @__PURE__ */ jsx("span", { className: cn("block transition-opacity", canMessage && "group-hover/pill:opacity-0"), children: avatarCore }),
2848
+ canMessage && /* @__PURE__ */ jsx(
2849
+ "span",
2920
2850
  {
2921
- focused,
2922
- transcribe: dictateCtx.transcribe,
2923
- onError: dictateCtx.onError,
2924
- className: "absolute right-1.5 top-1/2 -translate-y-1/2",
2925
- onTranscript: (text) => {
2926
- const el = innerRef.current;
2927
- if (!el) return;
2928
- const next = el.value ? `${el.value} ${text}` : text;
2929
- const setter = Object.getOwnPropertyDescriptor(
2930
- window.HTMLInputElement.prototype,
2931
- "value"
2932
- )?.set;
2933
- setter?.call(el, next);
2934
- el.dispatchEvent(new Event("input", { bubbles: true }));
2935
- }
2851
+ "aria-hidden": true,
2852
+ className: "absolute inset-0 flex items-center justify-center rounded-full bg-muted text-foreground opacity-0 transition-opacity group-hover/pill:opacity-100",
2853
+ children: /* @__PURE__ */ jsx(MessageCircleMore, { className: size === "xs" ? "h-3 w-3" : "h-4 w-4" })
2936
2854
  }
2937
- )
2855
+ ),
2856
+ statusDot
2857
+ ] })
2858
+ );
2859
+ const resolvedTooltip = showTooltip ? tooltipContent : void 0;
2860
+ if (variant === "pill") {
2861
+ const row = /* @__PURE__ */ jsxs(Fragment, { children: [
2862
+ pillAvatar,
2863
+ displayName && /* @__PURE__ */ jsx("span", { className: "min-w-0 max-w-[320px] truncate text-sm leading-tight", children: displayName }),
2864
+ isVerified && !isAgent2 && /* @__PURE__ */ jsx(VerifiedBadge, {}),
2865
+ agentBadge
2938
2866
  ] });
2939
- }
2940
- );
2941
- Input.displayName = "Input";
2942
- var Textarea = React.forwardRef(
2943
- ({ className, dictate, onFocus, onBlur, ...props }, forwardedRef) => {
2944
- const dictateCtx = useDictateContext();
2945
- const [focused, setFocused] = React.useState(false);
2946
- const innerRef = React.useRef(null);
2947
- React.useImperativeHandle(forwardedRef, () => innerRef.current);
2948
- const showDictate = dictate && !!dictateCtx && !props.disabled && !props.readOnly;
2949
- const textarea = /* @__PURE__ */ jsx(
2950
- "textarea",
2951
- {
2952
- className: cn(
2953
- "flex min-h-[60px] w-full rounded-md border border-input bg-background px-3 py-2 text-base shadow-sm placeholder:text-muted-foreground/60 focus-visible:outline-none focus-visible:border-ring/50 disabled:cursor-not-allowed disabled:opacity-50 md:text-sm",
2954
- showDictate && "pr-9",
2955
- className
2867
+ const rowClass = "group/pill inline-flex min-w-0 items-center gap-2";
2868
+ const clickable = interactive && !!onClick;
2869
+ const clickableClass = "relative cursor-pointer rounded-md px-1 py-0.5 -mx-1 transition-colors hover:bg-muted/60 pointer-coarse:after:absolute pointer-coarse:after:inset-x-0 pointer-coarse:after:-inset-y-3 pointer-coarse:after:content-['']";
2870
+ if (resolvedTooltip) {
2871
+ return /* @__PURE__ */ jsxs(Tooltip, { children: [
2872
+ /* @__PURE__ */ jsx(
2873
+ TooltipTrigger,
2874
+ {
2875
+ type: "button",
2876
+ onClick: clickable ? onClick : void 0,
2877
+ onFocusCapture: (e) => e.stopPropagation(),
2878
+ className: cn(rowClass, clickable && clickableClass, className),
2879
+ "data-testid": "user-entity-pill",
2880
+ children: row
2881
+ }
2956
2882
  ),
2957
- ref: innerRef,
2958
- onFocus: (e) => {
2959
- setFocused(true);
2960
- onFocus?.(e);
2961
- },
2962
- onBlur: (e) => {
2963
- setFocused(false);
2964
- onBlur?.(e);
2965
- },
2966
- ...props
2967
- }
2968
- );
2969
- if (!showDictate) return textarea;
2970
- return /* @__PURE__ */ jsxs("div", { className: "relative w-full", children: [
2971
- textarea,
2883
+ /* @__PURE__ */ jsx(TooltipContent, { className: "p-2", children: resolvedTooltip })
2884
+ ] });
2885
+ }
2886
+ if (clickable) {
2887
+ return /* @__PURE__ */ jsx(
2888
+ "button",
2889
+ {
2890
+ type: "button",
2891
+ onClick,
2892
+ className: cn(rowClass, clickableClass, className),
2893
+ "data-testid": "user-entity-pill",
2894
+ children: row
2895
+ }
2896
+ );
2897
+ }
2898
+ return /* @__PURE__ */ jsx("span", { className: cn(rowClass, className), "data-testid": "user-entity-pill", children: row });
2899
+ }
2900
+ if (showTooltip) {
2901
+ return /* @__PURE__ */ jsxs(Tooltip, { children: [
2972
2902
  /* @__PURE__ */ jsx(
2973
- InlineMicButton,
2903
+ TooltipTrigger,
2974
2904
  {
2975
- focused,
2976
- transcribe: dictateCtx.transcribe,
2977
- onError: dictateCtx.onError,
2978
- className: "absolute right-1.5 top-1.5",
2979
- onTranscript: (text) => {
2980
- const el = innerRef.current;
2981
- if (!el) return;
2982
- const next = el.value ? `${el.value} ${text}` : text;
2983
- const setter = Object.getOwnPropertyDescriptor(
2984
- window.HTMLTextAreaElement.prototype,
2985
- "value"
2986
- )?.set;
2987
- setter?.call(el, next);
2988
- el.dispatchEvent(new Event("input", { bubbles: true }));
2989
- }
2905
+ onFocusCapture: (e) => e.stopPropagation(),
2906
+ className: "touch-hit inline-flex",
2907
+ children: avatarElement
2990
2908
  }
2991
- )
2909
+ ),
2910
+ /* @__PURE__ */ jsx(TooltipContent, { className: "p-2", children: tooltipContent })
2992
2911
  ] });
2993
2912
  }
2994
- );
2995
- Textarea.displayName = "Textarea";
2996
- function DebouncedInput({
2997
- value,
2998
- onChange,
2999
- disabled,
3000
- type = "text",
3001
- multiline = false,
3002
- className,
3003
- debounceMs = 500,
3004
- placeholder,
3005
- autoResize = true,
3006
- minHeight = 28,
3007
- maxHeight = 72
3008
- }) {
3009
- const [localValue, setLocalValue] = useState(value);
3010
- const timeoutRef = useRef(void 0);
3011
- const pendingRef = useRef(null);
3012
- const textareaRef = useRef(null);
3013
- const adjustHeight = useCallback(() => {
3014
- const textarea = textareaRef.current;
3015
- if (!textarea || !autoResize) return;
3016
- textarea.style.height = "auto";
3017
- const newHeight = Math.min(Math.max(textarea.scrollHeight, minHeight), maxHeight);
3018
- textarea.style.height = `${newHeight}px`;
3019
- }, [autoResize, minHeight, maxHeight]);
3020
- useEffect(() => {
3021
- if (pendingRef.current !== null) return;
3022
- setLocalValue(value);
3023
- }, [value]);
3024
- useEffect(() => {
3025
- if (multiline) {
3026
- adjustHeight();
2913
+ return avatarElement;
2914
+ });
2915
+ function AgentBadge({ className }) {
2916
+ return /* @__PURE__ */ jsxs(
2917
+ "span",
2918
+ {
2919
+ "data-testid": "agent-badge",
2920
+ className: cn(
2921
+ "inline-flex shrink-0 items-center gap-1 rounded-full border border-ai-accent/50",
2922
+ "bg-ai-accent-soft px-2 py-0.5 text-xs font-bold uppercase tracking-wider text-ai-accent",
2923
+ className
2924
+ ),
2925
+ children: [
2926
+ /* @__PURE__ */ jsx(ArbiBotHeadIcon, { size: 14, className: "text-ai-accent" }),
2927
+ "Agent"
2928
+ ]
3027
2929
  }
3028
- }, [localValue, multiline, adjustHeight]);
3029
- const onChangeRef = useRef(onChange);
3030
- useEffect(() => {
3031
- onChangeRef.current = onChange;
3032
- }, [onChange]);
3033
- const flushPendingChange = useCallback(() => {
3034
- if (pendingRef.current === null) return false;
3035
- const pending = pendingRef.current;
3036
- pendingRef.current = null;
3037
- clearTimeout(timeoutRef.current);
3038
- onChangeRef.current(pending);
3039
- return true;
3040
- }, []);
3041
- const handleChange = useCallback(
3042
- (e) => {
3043
- const newValue = e.target.value;
3044
- setLocalValue(newValue);
3045
- pendingRef.current = newValue;
3046
- clearTimeout(timeoutRef.current);
3047
- timeoutRef.current = setTimeout(() => {
3048
- pendingRef.current = null;
3049
- onChangeRef.current(newValue);
3050
- }, debounceMs);
3051
- },
3052
- [debounceMs]
3053
2930
  );
3054
- useEffect(
3055
- () => () => {
3056
- const pending = pendingRef.current;
3057
- pendingRef.current = null;
3058
- clearTimeout(timeoutRef.current);
3059
- if (pending !== null) onChangeRef.current(pending);
3060
- },
3061
- []
3062
- );
3063
- const handleBlur = useCallback(() => {
3064
- flushPendingChange();
3065
- if (localValue !== value) {
3066
- setLocalValue(value);
3067
- }
3068
- }, [flushPendingChange, localValue, value]);
3069
- if (multiline) {
3070
- return /* @__PURE__ */ jsx(
3071
- Textarea,
3072
- {
3073
- ref: textareaRef,
3074
- value: localValue,
3075
- onChange: handleChange,
3076
- onBlur: handleBlur,
3077
- disabled,
3078
- className: `resize-y ${className || ""}`,
3079
- placeholder,
3080
- style: { minHeight: `${minHeight}px` }
3081
- }
3082
- );
3083
- }
3084
- return /* @__PURE__ */ jsx(
3085
- Input,
2931
+ }
2932
+ var PRESENCE_WORDS = {
2933
+ connected: "Online",
2934
+ connecting: "Connecting",
2935
+ disconnected: "Offline",
2936
+ error: "Connection problem",
2937
+ hidden: null
2938
+ };
2939
+ function PresenceLabel({
2940
+ status,
2941
+ className
2942
+ }) {
2943
+ if (!status) return null;
2944
+ const word = PRESENCE_WORDS[status];
2945
+ if (!word) return null;
2946
+ const online = status === "connected";
2947
+ return /* @__PURE__ */ jsxs(
2948
+ "span",
3086
2949
  {
3087
- type,
3088
- value: localValue,
3089
- onChange: handleChange,
3090
- onBlur: handleBlur,
3091
- disabled,
3092
- className,
3093
- placeholder
2950
+ "data-testid": "presence-label",
2951
+ className: cn("inline-flex shrink-0 items-center gap-1 text-xs", className),
2952
+ children: [
2953
+ /* @__PURE__ */ jsx(
2954
+ "span",
2955
+ {
2956
+ className: cn(
2957
+ "size-1.5 rounded-full",
2958
+ online ? "bg-status-online" : "bg-muted-foreground/50"
2959
+ ),
2960
+ "aria-hidden": "true"
2961
+ }
2962
+ ),
2963
+ /* @__PURE__ */ jsx("span", { className: online ? "font-medium text-status-online" : "text-muted-foreground", children: word })
2964
+ ]
3094
2965
  }
3095
2966
  );
3096
2967
  }
3097
- var HoverCard = HoverCardPrimitive.Root;
3098
- var HoverCardTrigger = HoverCardPrimitive.Trigger;
3099
- function HoverCardPortal({
3100
- container,
3101
- ...props
2968
+ var PACKAGE_BADGE_VARIANTS = [
2969
+ "default",
2970
+ "accent",
2971
+ "secondary",
2972
+ "destructive",
2973
+ "outline"
2974
+ ];
2975
+ function isPackageBadgeVariant(v) {
2976
+ return PACKAGE_BADGE_VARIANTS.some((known) => known === v);
2977
+ }
2978
+ function PackageStatusBadge({ variant, ...rest }) {
2979
+ return /* @__PURE__ */ jsx(Badge, { variant: isPackageBadgeVariant(variant) ? variant : "outline", ...rest });
2980
+ }
2981
+ var registry = {
2982
+ variants: {},
2983
+ fallback: "outline",
2984
+ Badge: PackageStatusBadge
2985
+ };
2986
+ function configureStatusRegistry(map, opts) {
2987
+ Object.assign(registry.variants, map);
2988
+ if (opts?.fallback) registry.fallback = opts.fallback;
2989
+ if (opts?.Badge) registry.Badge = opts.Badge;
2990
+ }
2991
+ function getStatusVariant(status) {
2992
+ return registry.variants[status] ?? registry.fallback;
2993
+ }
2994
+ function StatusPill({ status, label, variant, className, testId }) {
2995
+ const Badge2 = registry.Badge;
2996
+ return /* @__PURE__ */ jsx(Badge2, { variant: variant ?? getStatusVariant(status), className, "data-testid": testId, children: label ?? status });
2997
+ }
2998
+ var RAG_LABELS = { red: "At risk", amber: "Attention", green: "On track" };
2999
+ function configureRagLabels(labels) {
3000
+ RAG_LABELS = { ...RAG_LABELS, ...labels };
3001
+ }
3002
+ function RagDot({
3003
+ rag,
3004
+ withLabel,
3005
+ className
3102
3006
  }) {
3103
- const fallback = usePortalContainer();
3104
- return /* @__PURE__ */ jsx(HoverCardPrimitive.Portal, { container: container ?? fallback, ...props });
3007
+ const color = rag === "red" ? "bg-destructive" : rag === "amber" ? "bg-warning" : "bg-success";
3008
+ return /* @__PURE__ */ jsxs("span", { className: cn("inline-flex items-center gap-1.5", className), "data-testid": `rag-${rag}`, children: [
3009
+ /* @__PURE__ */ jsx("span", { className: cn("size-2 rounded-full", color) }),
3010
+ withLabel && /* @__PURE__ */ jsx("span", { className: "text-xs text-muted-foreground", children: RAG_LABELS[rag] })
3011
+ ] });
3105
3012
  }
3106
- var HoverCardContent = React.forwardRef(({ className, align = "center", sideOffset = 4, ...props }, ref) => /* @__PURE__ */ jsx(HoverCardPortal, { children: /* @__PURE__ */ jsx(
3107
- HoverCardPrimitive.Content,
3108
- {
3109
- ref,
3110
- align,
3111
- sideOffset,
3112
- collisionPadding: getCollisionPadding(),
3113
- className: cn(
3114
- "z-50 w-64 max-w-[calc(100vw-1rem)] rounded-md border bg-popover p-4 text-popover-foreground shadow-lg outline-none data-[state=open]:animate-in data-[state=closed]:animate-out data-[state=closed]:fade-out-0 data-[state=open]:fade-in-0 data-[state=closed]:zoom-out-95 data-[state=open]:zoom-in-95 data-[side=bottom]:slide-in-from-top-2 data-[side=left]:slide-in-from-right-2 data-[side=right]:slide-in-from-left-2 data-[side=top]:slide-in-from-bottom-2 origin-[--radix-hover-card-content-transform-origin]",
3115
- className
3116
- ),
3117
- ...props
3118
- }
3119
- ) }));
3120
- HoverCardContent.displayName = HoverCardPrimitive.Content.displayName;
3121
- var cardVariants = cva("min-w-0 rounded-lg bg-card text-card-foreground", {
3122
- variants: {
3123
- variant: {
3124
- flat: "",
3125
- outline: "border",
3126
- elevated: "border shadow-sm"
3127
- }
3128
- },
3129
- defaultVariants: {
3130
- variant: "flat"
3013
+
3014
+ // src/entities/colors.ts
3015
+ var OPACITY_LIGHT = 0.15;
3016
+ var OPACITY_MEDIUM = 1;
3017
+ var OPACITY_BORDER = 0.3;
3018
+ var PLACEHOLDER_COLOR = "#9ca3af";
3019
+ var NEUTRAL_GRAY2 = "#64748b";
3020
+ var BASE_COLORS2 = {
3021
+ "0": "#10b981",
3022
+ "1": "#3b82f6",
3023
+ "2": "#8b5cf6",
3024
+ "3": "#f43f5e",
3025
+ "4": "#f59e0b",
3026
+ "5": "#84cc16",
3027
+ "6": "#a855f7",
3028
+ "7": "#06b6d4",
3029
+ "8": "#f97316",
3030
+ "9": "#14b8a6",
3031
+ a: "#ef4444",
3032
+ b: "#6366f1",
3033
+ c: "#ec4899",
3034
+ d: "#22c55e",
3035
+ e: "#eab308",
3036
+ f: "#0ea5e9"
3037
+ };
3038
+ function hexToRgba(hex, opacity) {
3039
+ const r = parseInt(hex.slice(1, 3), 16);
3040
+ const g = parseInt(hex.slice(3, 5), 16);
3041
+ const b = parseInt(hex.slice(5, 7), 16);
3042
+ return `rgba(${r}, ${g}, ${b}, ${opacity})`;
3043
+ }
3044
+ function getEntityColor2(entityId, variant = "medium") {
3045
+ const baseColor = BASE_COLORS2[entityId[4]] || BASE_COLORS2["0"];
3046
+ switch (variant) {
3047
+ case "light":
3048
+ return hexToRgba(baseColor, OPACITY_LIGHT);
3049
+ case "medium":
3050
+ return hexToRgba(baseColor, OPACITY_MEDIUM);
3051
+ case "text":
3052
+ return baseColor;
3131
3053
  }
3132
- });
3133
- var Card = React.forwardRef(
3134
- ({ className, variant, ...props }, ref) => /* @__PURE__ */ jsx(
3135
- "div",
3054
+ }
3055
+ function getEntityColorStyles(entityId) {
3056
+ const baseColor = BASE_COLORS2[entityId[4]] || BASE_COLORS2["0"];
3057
+ return {
3058
+ backgroundColor: getEntityColor2(entityId, "light"),
3059
+ color: baseColor,
3060
+ borderColor: hexToRgba(baseColor, OPACITY_BORDER)
3061
+ };
3062
+ }
3063
+ var getWorkspaceColor = (workspaceId, useWorkspaceColors) => {
3064
+ const shouldUseWorkspaceColors = useWorkspaceColors !== void 0 ? useWorkspaceColors : true;
3065
+ if (!shouldUseWorkspaceColors) return "hsl(var(--primary))";
3066
+ const isValidId = workspaceId && workspaceId.startsWith("wrk-") && workspaceId.length >= 5;
3067
+ if (!isValidId) return "hsl(var(--primary))";
3068
+ return getEntityColor2(workspaceId, "medium");
3069
+ };
3070
+ var ShieldIcon = ({
3071
+ char,
3072
+ size = 24,
3073
+ className = "",
3074
+ workspaceColor,
3075
+ isSelected = false,
3076
+ ...props
3077
+ }) => {
3078
+ const fillColor = workspaceColor && workspaceColor !== "hsl(var(--primary))" ? workspaceColor : "transparent";
3079
+ const strokeColor = isSelected ? "white" : workspaceColor && workspaceColor !== "hsl(var(--primary))" ? workspaceColor : "currentColor";
3080
+ return /* @__PURE__ */ jsxs(
3081
+ "svg",
3136
3082
  {
3137
- ref,
3138
- "data-slot": "card",
3139
- className: cn(cardVariants({ variant }), className),
3140
- ...props
3083
+ width: size,
3084
+ height: size,
3085
+ viewBox: "0 0 24 24",
3086
+ fill: fillColor,
3087
+ stroke: strokeColor,
3088
+ strokeWidth: "2",
3089
+ strokeLinecap: "round",
3090
+ strokeLinejoin: "round",
3091
+ className: `lucide lucide-square ${className}`,
3092
+ ...props,
3093
+ children: [
3094
+ /* @__PURE__ */ jsx("rect", { width: "18", height: "18", x: "3", y: "3", rx: "2" }),
3095
+ char && /* @__PURE__ */ jsx(
3096
+ "text",
3097
+ {
3098
+ x: "12",
3099
+ y: "12.5",
3100
+ textAnchor: "middle",
3101
+ fontSize: "9",
3102
+ fontFamily: "sans-serif",
3103
+ fontWeight: "300",
3104
+ dominantBaseline: "middle",
3105
+ stroke: workspaceColor ? "white" : "currentColor",
3106
+ strokeWidth: "0.8",
3107
+ children: char.toUpperCase()
3108
+ }
3109
+ )
3110
+ ]
3141
3111
  }
3142
- )
3143
- );
3144
- Card.displayName = "Card";
3145
- var CardHeader = React.forwardRef(
3146
- ({ className, ...props }, ref) => /* @__PURE__ */ jsx(
3147
- "div",
3148
- {
3149
- ref,
3150
- "data-slot": "card-header",
3151
- className: cn("flex flex-col space-y-1.5 p-6", className),
3152
- ...props
3153
- }
3154
- )
3155
- );
3156
- CardHeader.displayName = "CardHeader";
3157
- var CardTitle = React.forwardRef(
3158
- ({ className, ...props }, ref) => /* @__PURE__ */ jsx(
3159
- "div",
3160
- {
3161
- ref,
3162
- "data-slot": "card-title",
3163
- className: cn("font-semibold leading-none tracking-tight", className),
3164
- ...props
3165
- }
3166
- )
3167
- );
3168
- CardTitle.displayName = "CardTitle";
3169
- var CardDescription = React.forwardRef(
3170
- ({ className, ...props }, ref) => /* @__PURE__ */ jsx(
3171
- "div",
3172
- {
3173
- ref,
3174
- "data-slot": "card-description",
3175
- className: cn("text-sm text-muted-foreground", className),
3176
- ...props
3177
- }
3178
- )
3179
- );
3180
- CardDescription.displayName = "CardDescription";
3181
- var CardContent = React.forwardRef(
3182
- ({ className, ...props }, ref) => /* @__PURE__ */ jsx("div", { ref, "data-slot": "card-content", className: cn("p-6 pt-0", className), ...props })
3183
- );
3184
- CardContent.displayName = "CardContent";
3185
- var CardFooter = React.forwardRef(
3186
- ({ className, ...props }, ref) => /* @__PURE__ */ jsx(
3187
- "div",
3188
- {
3189
- ref,
3190
- "data-slot": "card-footer",
3191
- className: cn("flex items-center p-6 pt-0", className),
3192
- ...props
3112
+ );
3113
+ };
3114
+
3115
+ // src/entities/agent-avatar-colors.ts
3116
+ var BG_TO_COLOR = {
3117
+ "bg-emerald-700": "#047857",
3118
+ "bg-blue-700": "#1d4ed8",
3119
+ "bg-purple-700": "#7e22ce",
3120
+ "bg-amber-700": "#b45309",
3121
+ "bg-rose-700": "#be123c",
3122
+ "bg-red-700": "#b91c1c",
3123
+ "bg-indigo-700": "#4338ca",
3124
+ "bg-teal-700": "#0f766e",
3125
+ "bg-cyan-700": "#0e7490",
3126
+ "bg-sky-700": "#0369a1",
3127
+ "bg-lime-700": "#4d7c0f",
3128
+ "bg-orange-700": "#c2410c",
3129
+ "bg-pink-700": "#be185d",
3130
+ "bg-violet-700": "#6d28d9",
3131
+ "bg-fuchsia-700": "#a21caf",
3132
+ "bg-yellow-700": "#a16207"
3133
+ };
3134
+ function agentAvatarColors(bgColorClass) {
3135
+ const color = BG_TO_COLOR[bgColorClass] || "#047857";
3136
+ return { borderColor: color, color };
3137
+ }
3138
+
3139
+ // src/entities/media-type.ts
3140
+ function getDottedExtension(fileName) {
3141
+ if (!fileName) return "";
3142
+ return fileName.substring(fileName.lastIndexOf(".")).toLowerCase();
3143
+ }
3144
+ var DOWNLOAD_ONLY_EXTENSIONS = /* @__PURE__ */ new Set([
3145
+ ".zip",
3146
+ ".rar",
3147
+ ".7z",
3148
+ ".tar",
3149
+ ".gz",
3150
+ ".exe",
3151
+ ".bin",
3152
+ ".dmg",
3153
+ ".iso",
3154
+ ".apk",
3155
+ ".msi",
3156
+ ".dll",
3157
+ ".so",
3158
+ ".psd",
3159
+ ".ai",
3160
+ ".sketch"
3161
+ ]);
3162
+ var IMAGE_EXTENSIONS3 = /* @__PURE__ */ new Set([
3163
+ ".jpg",
3164
+ ".jpeg",
3165
+ ".png",
3166
+ ".gif",
3167
+ ".bmp",
3168
+ ".tiff",
3169
+ ".tif",
3170
+ ".webp"
3171
+ ]);
3172
+ var VIDEO_EXTENSIONS3 = /* @__PURE__ */ new Set([".mp4", ".mpeg", ".mpg", ".webm", ".mov", ".avi", ".mkv"]);
3173
+ var AUDIO_EXTENSIONS3 = /* @__PURE__ */ new Set([".mp3", ".wav", ".m4a", ".aac", ".ogg", ".flac"]);
3174
+ function isImageFile(fileName) {
3175
+ return IMAGE_EXTENSIONS3.has(getDottedExtension(fileName));
3176
+ }
3177
+ function isVideoFile(fileName) {
3178
+ return VIDEO_EXTENSIONS3.has(getDottedExtension(fileName));
3179
+ }
3180
+ function isAudioFile(fileName) {
3181
+ return AUDIO_EXTENSIONS3.has(getDottedExtension(fileName));
3182
+ }
3183
+ function isMediaFile(fileName) {
3184
+ return isImageFile(fileName) || isVideoFile(fileName) || isAudioFile(fileName);
3185
+ }
3186
+ function usesOriginalBytesForViewer(fileName) {
3187
+ return isMediaFile(fileName);
3188
+ }
3189
+ function isDownloadOnlyFile(fileName) {
3190
+ return DOWNLOAD_ONLY_EXTENSIONS.has(getDottedExtension(fileName));
3191
+ }
3192
+
3193
+ // src/entities/file-type.ts
3194
+ var EXT_LABELS = {
3195
+ pdf: "PDF",
3196
+ // Word / docs
3197
+ doc: "Word",
3198
+ docx: "Word",
3199
+ rtf: "Word",
3200
+ odt: "Word",
3201
+ // Spreadsheets
3202
+ xls: "Excel",
3203
+ xlsx: "Excel",
3204
+ ods: "Excel",
3205
+ csv: "CSV",
3206
+ tsv: "CSV",
3207
+ // Slides
3208
+ ppt: "PowerPoint",
3209
+ pptx: "PowerPoint",
3210
+ odp: "PowerPoint",
3211
+ // Plain text / markup
3212
+ txt: "Text",
3213
+ log: "Text",
3214
+ md: "Markdown",
3215
+ markdown: "Markdown",
3216
+ html: "HTML",
3217
+ htm: "HTML",
3218
+ xml: "XML",
3219
+ json: "JSON",
3220
+ yaml: "YAML",
3221
+ yml: "YAML",
3222
+ // Email
3223
+ eml: "Email",
3224
+ msg: "Email",
3225
+ mbox: "Email",
3226
+ pst: "Outlook",
3227
+ ost: "Outlook",
3228
+ // Images
3229
+ jpg: "Image",
3230
+ jpeg: "Image",
3231
+ png: "Image",
3232
+ gif: "Image",
3233
+ bmp: "Image",
3234
+ tif: "Image",
3235
+ tiff: "Image",
3236
+ webp: "Image",
3237
+ svg: "Image",
3238
+ heic: "Image",
3239
+ heif: "Image",
3240
+ // Audio
3241
+ mp3: "Audio",
3242
+ wav: "Audio",
3243
+ m4a: "Audio",
3244
+ aac: "Audio",
3245
+ ogg: "Audio",
3246
+ flac: "Audio",
3247
+ opus: "Audio",
3248
+ // Video
3249
+ mp4: "Video",
3250
+ webm: "Video",
3251
+ mov: "Video",
3252
+ avi: "Video",
3253
+ mkv: "Video",
3254
+ // Archives
3255
+ zip: "Archive",
3256
+ tar: "Archive",
3257
+ gz: "Archive",
3258
+ rar: "Archive",
3259
+ "7z": "Archive"
3260
+ };
3261
+ var MIME_SUBTYPE_LABELS = {
3262
+ // PDF
3263
+ pdf: "PDF",
3264
+ "x-pdf": "PDF",
3265
+ // Word
3266
+ msword: "Word",
3267
+ "vnd.openxmlformats-officedocument.wordprocessingml.document": "Word",
3268
+ "vnd.oasis.opendocument.text": "Word",
3269
+ rtf: "Word",
3270
+ // Excel
3271
+ "vnd.ms-excel": "Excel",
3272
+ "vnd.openxmlformats-officedocument.spreadsheetml.sheet": "Excel",
3273
+ "vnd.oasis.opendocument.spreadsheet": "Excel",
3274
+ csv: "CSV",
3275
+ "tab-separated-values": "CSV",
3276
+ // PowerPoint
3277
+ "vnd.ms-powerpoint": "PowerPoint",
3278
+ "vnd.openxmlformats-officedocument.presentationml.presentation": "PowerPoint",
3279
+ "vnd.oasis.opendocument.presentation": "PowerPoint",
3280
+ // Plain text / markup
3281
+ plain: "Text",
3282
+ html: "HTML",
3283
+ xml: "XML",
3284
+ json: "JSON",
3285
+ markdown: "Markdown",
3286
+ "x-markdown": "Markdown",
3287
+ yaml: "YAML",
3288
+ "x-yaml": "YAML",
3289
+ // Email
3290
+ rfc822: "Email",
3291
+ "vnd.ms-outlook": "Email",
3292
+ // Archives
3293
+ zip: "Archive",
3294
+ "x-zip-compressed": "Archive",
3295
+ "x-tar": "Archive",
3296
+ gzip: "Archive",
3297
+ "x-7z-compressed": "Archive",
3298
+ "x-rar-compressed": "Archive"
3299
+ };
3300
+ var MIME_TYPE_LABELS = {
3301
+ image: "Image",
3302
+ audio: "Audio",
3303
+ video: "Video",
3304
+ text: "Text"
3305
+ };
3306
+ function lookupExt(ext) {
3307
+ return EXT_LABELS[ext.toLowerCase().replace(/^\./, "")];
3308
+ }
3309
+ function lookupMime(mime) {
3310
+ const base = mime.toLowerCase().split(";")[0].trim();
3311
+ const slash = base.indexOf("/");
3312
+ if (slash <= 0) return void 0;
3313
+ const top = base.slice(0, slash);
3314
+ const sub = base.slice(slash + 1);
3315
+ return MIME_SUBTYPE_LABELS[sub] ?? MIME_TYPE_LABELS[top];
3316
+ }
3317
+ function extFromFileName(fileName) {
3318
+ if (!fileName) return void 0;
3319
+ const dot = fileName.lastIndexOf(".");
3320
+ if (dot <= 0 || dot === fileName.length - 1) return void 0;
3321
+ return fileName.slice(dot + 1);
3322
+ }
3323
+ function friendlyFileType(fileType, fileName) {
3324
+ if (fileType) {
3325
+ const trimmed = fileType.trim();
3326
+ if (trimmed.includes("/")) {
3327
+ const fromMime = lookupMime(trimmed);
3328
+ if (fromMime) return fromMime;
3329
+ } else {
3330
+ const fromExt = lookupExt(trimmed);
3331
+ if (fromExt) return fromExt;
3193
3332
  }
3194
- )
3195
- );
3196
- CardFooter.displayName = "CardFooter";
3197
- var Label2 = React.forwardRef(({ className, ...props }, ref) => /* @__PURE__ */ jsx(
3198
- "label",
3199
- {
3200
- ref,
3201
- className: `text-sm font-medium leading-none peer-disabled:cursor-not-allowed peer-disabled:opacity-70 ${className || ""}`,
3202
- ...props
3203
3333
  }
3204
- ));
3205
- Label2.displayName = "Label";
3206
- var Separator2 = React.forwardRef(({ className, orientation = "horizontal", decorative = true, ...props }, ref) => /* @__PURE__ */ jsx(
3207
- SeparatorPrimitive.Root,
3334
+ const fnExt = extFromFileName(fileName);
3335
+ if (fnExt) {
3336
+ const fromExt = lookupExt(fnExt);
3337
+ if (fromExt) return fromExt;
3338
+ }
3339
+ return "Other";
3340
+ }
3341
+ var Select = SelectPrimitive.Root;
3342
+ var SelectGroup = SelectPrimitive.Group;
3343
+ var SelectValue = SelectPrimitive.Value;
3344
+ function SelectPortal({
3345
+ container,
3346
+ ...props
3347
+ }) {
3348
+ const fallback = usePortalContainer();
3349
+ return /* @__PURE__ */ jsx(SelectPrimitive.Portal, { container: container ?? fallback, ...props });
3350
+ }
3351
+ var SelectTrigger = React.forwardRef(({ className, children, ...props }, ref) => /* @__PURE__ */ jsxs(
3352
+ SelectPrimitive.Trigger,
3208
3353
  {
3209
3354
  ref,
3210
- decorative,
3211
- orientation,
3212
3355
  className: cn(
3213
- "shrink-0 bg-border",
3214
- orientation === "horizontal" ? "h-[1px] w-full" : "h-full w-[1px]",
3356
+ "flex h-9 pointer-coarse:min-h-11 w-full items-center justify-between rounded-md border border-input bg-background px-3 py-2 text-sm placeholder:text-muted-foreground/60 focus:outline-none focus-visible:border-ring/50 disabled:cursor-not-allowed disabled:opacity-50 [&>span]:line-clamp-1",
3215
3357
  className
3216
3358
  ),
3217
- ...props
3359
+ ...props,
3360
+ children: [
3361
+ children,
3362
+ /* @__PURE__ */ jsx(SelectPrimitive.Icon, { asChild: true, children: /* @__PURE__ */ jsx(ChevronDown, { className: "h-4 w-4 opacity-50" }) })
3363
+ ]
3218
3364
  }
3219
3365
  ));
3220
- Separator2.displayName = SeparatorPrimitive.Root.displayName;
3221
- var Collapsible = CollapsiblePrimitive.Root;
3222
- var CollapsibleTrigger2 = CollapsiblePrimitive.CollapsibleTrigger;
3223
- var CollapsibleContent2 = CollapsiblePrimitive.CollapsibleContent;
3224
- var Progress = React.forwardRef(({ className, value, ...props }, ref) => /* @__PURE__ */ jsx(
3225
- ProgressPrimitive.Root,
3366
+ SelectTrigger.displayName = SelectPrimitive.Trigger.displayName;
3367
+ var SelectScrollUpButton = React.forwardRef(({ className, ...props }, ref) => /* @__PURE__ */ jsx(
3368
+ SelectPrimitive.ScrollUpButton,
3226
3369
  {
3227
3370
  ref,
3228
- className: cn("relative h-2 w-full overflow-hidden rounded-full bg-primary/20", className),
3371
+ className: cn("flex cursor-default items-center justify-center py-1", className),
3229
3372
  ...props,
3230
- children: /* @__PURE__ */ jsx(
3231
- ProgressPrimitive.Indicator,
3232
- {
3233
- className: "h-full w-full flex-1 bg-primary transition-all",
3234
- style: { transform: `translateX(-${100 - (value || 0)}%)` }
3235
- }
3236
- )
3373
+ children: /* @__PURE__ */ jsx(ChevronUp, { className: "h-4 w-4" })
3237
3374
  }
3238
3375
  ));
3239
- Progress.displayName = ProgressPrimitive.Root.displayName;
3240
- var RadioGroup = React.forwardRef(({ className, ...props }, ref) => {
3241
- return /* @__PURE__ */ jsx(RadioGroupPrimitive.Root, { className: cn("grid gap-2", className), ...props, ref });
3242
- });
3243
- RadioGroup.displayName = RadioGroupPrimitive.Root.displayName;
3244
- var RadioGroupItem = React.forwardRef(({ className, ...props }, ref) => {
3245
- return /* @__PURE__ */ jsx(
3246
- RadioGroupPrimitive.Item,
3247
- {
3248
- ref,
3249
- className: cn(
3250
- "relative aspect-square h-4 w-4 rounded-full border border-primary text-primary after:absolute after:left-1/2 after:top-1/2 after:hidden after:size-11 after:-translate-x-1/2 after:-translate-y-1/2 after:content-[''] pointer-coarse:after:block focus:outline-none focus-visible:ring-1 focus-visible:ring-ring disabled:cursor-not-allowed disabled:opacity-50",
3251
- className
3252
- ),
3253
- ...props,
3254
- children: /* @__PURE__ */ jsx(RadioGroupPrimitive.Indicator, { className: "flex items-center justify-center", children: /* @__PURE__ */ jsx(Circle, { className: "h-2.5 w-2.5 fill-current text-current" }) })
3255
- }
3256
- );
3257
- });
3258
- RadioGroupItem.displayName = RadioGroupPrimitive.Item.displayName;
3259
- var Switch = React.forwardRef(({ className, ...props }, ref) => /* @__PURE__ */ jsx(
3260
- SwitchPrimitives.Root,
3376
+ SelectScrollUpButton.displayName = SelectPrimitive.ScrollUpButton.displayName;
3377
+ var SelectScrollDownButton = React.forwardRef(({ className, ...props }, ref) => /* @__PURE__ */ jsx(
3378
+ SelectPrimitive.ScrollDownButton,
3261
3379
  {
3262
- className: cn(
3263
- "peer relative inline-flex h-5 w-9 shrink-0 cursor-pointer items-center rounded-full border-2 border-transparent shadow-sm transition-colors focus-visible:outline-none focus-visible:ring-1 focus-visible:ring-ring disabled:cursor-not-allowed disabled:opacity-50 data-[state=checked]:bg-primary data-[state=unchecked]:bg-input dark:data-[state=unchecked]:bg-muted-foreground/45 after:absolute after:left-1/2 after:top-1/2 after:hidden after:size-11 after:-translate-x-1/2 after:-translate-y-1/2 after:content-[''] pointer-coarse:after:block",
3264
- className
3265
- ),
3266
- ...props,
3267
3380
  ref,
3268
- children: /* @__PURE__ */ jsx(
3269
- SwitchPrimitives.Thumb,
3270
- {
3271
- className: cn(
3272
- "pointer-events-none block h-4 w-4 rounded-full bg-background shadow-lg ring-0 transition-transform data-[state=checked]:translate-x-4 data-[state=unchecked]:translate-x-0"
3273
- )
3274
- }
3275
- )
3381
+ className: cn("flex cursor-default items-center justify-center py-1", className),
3382
+ ...props,
3383
+ children: /* @__PURE__ */ jsx(ChevronDown, { className: "h-4 w-4" })
3276
3384
  }
3277
3385
  ));
3278
- Switch.displayName = SwitchPrimitives.Root.displayName;
3279
- var Tabs = TabsPrimitive.Root;
3280
- var TabsList = React.forwardRef(({ className, ...props }, ref) => /* @__PURE__ */ jsx(
3281
- TabsPrimitive.List,
3386
+ SelectScrollDownButton.displayName = SelectPrimitive.ScrollDownButton.displayName;
3387
+ var SelectContent = React.forwardRef(({ className, children, position = "popper", ...props }, ref) => /* @__PURE__ */ jsx(SelectPortal, { children: /* @__PURE__ */ jsxs(
3388
+ SelectPrimitive.Content,
3282
3389
  {
3283
3390
  ref,
3284
3391
  className: cn(
3285
- "inline-flex h-9 pointer-coarse:h-auto items-center justify-center rounded-lg bg-muted p-1 text-muted-foreground",
3392
+ "relative z-50 max-h-[min(24rem,var(--radix-select-content-available-height))] min-w-[8rem] max-w-[calc(100vw-1rem)] overflow-hidden rounded-md border bg-popover text-popover-foreground shadow-lg data-[state=open]:animate-in data-[state=closed]:animate-out data-[state=closed]:fade-out-0 data-[state=open]:fade-in-0 data-[state=closed]:zoom-out-95 data-[state=open]:zoom-in-95 data-[side=bottom]:slide-in-from-top-2 data-[side=left]:slide-in-from-right-2 data-[side=right]:slide-in-from-left-2 data-[side=top]:slide-in-from-bottom-2",
3393
+ position === "popper" && "data-[side=bottom]:translate-y-1 data-[side=left]:-translate-x-1 data-[side=right]:translate-x-1 data-[side=top]:-translate-y-1",
3286
3394
  className
3287
3395
  ),
3288
- ...props
3396
+ position,
3397
+ collisionPadding: getCollisionPadding(),
3398
+ ...props,
3399
+ children: [
3400
+ /* @__PURE__ */ jsx(SelectScrollUpButton, {}),
3401
+ /* @__PURE__ */ jsx(
3402
+ SelectPrimitive.Viewport,
3403
+ {
3404
+ className: cn(
3405
+ "p-1",
3406
+ position === "popper" && "h-[var(--radix-select-trigger-height)] w-full min-w-[var(--radix-select-trigger-width)]"
3407
+ ),
3408
+ children
3409
+ }
3410
+ ),
3411
+ /* @__PURE__ */ jsx(SelectScrollDownButton, {})
3412
+ ]
3289
3413
  }
3290
- ));
3291
- TabsList.displayName = TabsPrimitive.List.displayName;
3292
- var TabsTrigger = React.forwardRef(({ className, ...props }, ref) => /* @__PURE__ */ jsx(
3293
- TabsPrimitive.Trigger,
3294
- {
3295
- ref,
3296
- className: cn(
3297
- "inline-flex items-center justify-center whitespace-nowrap rounded-md px-3 py-1 text-sm pointer-coarse:min-h-11 font-medium ring-offset-background transition-all focus-visible:outline-none focus-visible:ring-2 focus-visible:ring-ring focus-visible:ring-offset-2 disabled:pointer-events-none disabled:opacity-50 data-[state=active]:bg-background data-[state=active]:text-foreground data-[state=active]:shadow",
3298
- className
3299
- ),
3414
+ ) }));
3415
+ SelectContent.displayName = SelectPrimitive.Content.displayName;
3416
+ var SelectLabel = React.forwardRef(({ className, ...props }, ref) => /* @__PURE__ */ jsx(
3417
+ SelectPrimitive.Label,
3418
+ {
3419
+ ref,
3420
+ className: cn("py-1.5 pl-8 pr-2 text-sm font-semibold", className),
3300
3421
  ...props
3301
3422
  }
3302
3423
  ));
3303
- TabsTrigger.displayName = TabsPrimitive.Trigger.displayName;
3304
- var TabsContent = React.forwardRef(({ className, ...props }, ref) => /* @__PURE__ */ jsx(
3305
- TabsPrimitive.Content,
3424
+ SelectLabel.displayName = SelectPrimitive.Label.displayName;
3425
+ var SelectItem = React.forwardRef(({ className, children, ...props }, ref) => /* @__PURE__ */ jsxs(
3426
+ SelectPrimitive.Item,
3306
3427
  {
3307
3428
  ref,
3308
3429
  className: cn(
3309
- "mt-2 ring-offset-background focus-visible:outline-none focus-visible:ring-2 focus-visible:ring-ring focus-visible:ring-offset-2",
3430
+ "relative flex w-full cursor-default select-none items-center rounded-sm py-1.5 pl-8 pr-2 pointer-coarse:min-h-11 text-sm outline-none focus:bg-accent focus:text-accent-foreground data-[disabled]:pointer-events-none data-[disabled]:opacity-50",
3310
3431
  className
3311
3432
  ),
3312
- ...props
3433
+ ...props,
3434
+ children: [
3435
+ /* @__PURE__ */ jsx("span", { className: "absolute left-2 flex h-3.5 w-3.5 items-center justify-center", children: /* @__PURE__ */ jsx(SelectPrimitive.ItemIndicator, { children: /* @__PURE__ */ jsx(Check, { className: "h-4 w-4" }) }) }),
3436
+ /* @__PURE__ */ jsx(SelectPrimitive.ItemText, { children })
3437
+ ]
3313
3438
  }
3314
3439
  ));
3315
- TabsContent.displayName = TabsPrimitive.Content.displayName;
3316
- var Table = React.forwardRef(
3317
- ({ className, ...props }, ref) => /* @__PURE__ */ jsx("div", { className: "relative w-full overflow-auto", children: /* @__PURE__ */ jsx("table", { ref, className: cn("w-full caption-bottom text-sm", className), ...props }) })
3318
- );
3319
- Table.displayName = "Table";
3320
- var TableHeader = React.forwardRef(({ className, ...props }, ref) => /* @__PURE__ */ jsx("thead", { ref, className: cn("[&_tr]:border-b", className), ...props }));
3321
- TableHeader.displayName = "TableHeader";
3322
- var TableBody = React.forwardRef(({ className, ...props }, ref) => /* @__PURE__ */ jsx("tbody", { ref, className: cn("[&_tr:last-child]:border-0", className), ...props }));
3323
- TableBody.displayName = "TableBody";
3324
- var TableFooter = React.forwardRef(({ className, ...props }, ref) => /* @__PURE__ */ jsx(
3325
- "tfoot",
3440
+ SelectItem.displayName = SelectPrimitive.Item.displayName;
3441
+ var SelectSeparator = React.forwardRef(({ className, ...props }, ref) => /* @__PURE__ */ jsx(
3442
+ SelectPrimitive.Separator,
3326
3443
  {
3327
3444
  ref,
3328
- className: cn("border-t bg-muted/50 font-medium [&>tr]:last:border-b-0", className),
3445
+ className: cn("-mx-1 my-1 h-px bg-muted", className),
3329
3446
  ...props
3330
3447
  }
3331
3448
  ));
3332
- TableFooter.displayName = "TableFooter";
3333
- var TableRow = React.forwardRef(
3334
- ({ className, ...props }, ref) => /* @__PURE__ */ jsx(
3335
- "tr",
3336
- {
3337
- ref,
3338
- className: cn(
3339
- "border-b transition-colors hover:bg-muted/50 data-[state=selected]:bg-muted",
3340
- className
3341
- ),
3342
- ...props
3343
- }
3344
- )
3345
- );
3346
- TableRow.displayName = "TableRow";
3347
- var TableHead = React.forwardRef(
3348
- ({ className, ...props }, ref) => /* @__PURE__ */ jsx(
3349
- "th",
3350
- {
3351
- ref,
3352
- className: cn(
3353
- "h-10 px-2 text-left align-middle font-medium text-muted-foreground [&:has([role=checkbox])]:pr-0 [&>[role=checkbox]]:translate-y-[2px]",
3354
- className
3355
- ),
3356
- ...props
3357
- }
3358
- )
3359
- );
3360
- TableHead.displayName = "TableHead";
3361
- var TableCell = React.forwardRef(
3362
- ({ className, ...props }, ref) => /* @__PURE__ */ jsx(
3363
- "td",
3364
- {
3365
- ref,
3366
- className: cn(
3367
- "p-2 align-middle [&:has([role=checkbox])]:pr-0 [&>[role=checkbox]]:translate-y-[2px]",
3368
- className
3369
- ),
3370
- ...props
3371
- }
3372
- )
3373
- );
3374
- TableCell.displayName = "TableCell";
3375
- var TableCaption = React.forwardRef(({ className, ...props }, ref) => /* @__PURE__ */ jsx("caption", { ref, className: cn("mt-4 text-sm text-muted-foreground", className), ...props }));
3376
- TableCaption.displayName = "TableCaption";
3377
- var Slider = React.forwardRef(
3378
- ({ className, rangeClassName, ...props }, ref) => /* @__PURE__ */ jsxs(
3379
- SliderPrimitive.Root,
3380
- {
3381
- ref,
3382
- className: cn("relative flex w-full touch-none select-none items-center", className),
3383
- ...props,
3384
- children: [
3385
- /* @__PURE__ */ jsx(SliderPrimitive.Track, { className: "relative h-1.5 w-full grow overflow-hidden rounded-full bg-primary/20", children: /* @__PURE__ */ jsx(SliderPrimitive.Range, { className: cn("absolute h-full bg-primary", rangeClassName) }) }),
3386
- /* @__PURE__ */ jsx(SliderPrimitive.Thumb, { className: "block h-4 w-4 rounded-full border border-primary/50 bg-background shadow transition-colors focus-visible:outline-none focus-visible:ring-1 focus-visible:ring-ring disabled:pointer-events-none disabled:opacity-50" })
3387
- ]
3388
- }
3389
- )
3390
- );
3391
- Slider.displayName = SliderPrimitive.Root.displayName;
3392
- var toggleVariants = cva(
3393
- "inline-flex items-center justify-center gap-2 rounded-md text-sm font-medium transition-colors hover:bg-muted hover:text-muted-foreground focus-visible:outline-none focus-visible:ring-1 focus-visible:ring-ring disabled:pointer-events-none disabled:opacity-50 data-[state=on]:bg-accent data-[state=on]:text-accent-foreground [&_svg]:pointer-events-none [&_svg]:size-4 [&_svg]:shrink-0",
3394
- {
3395
- variants: {
3396
- variant: {
3397
- default: "bg-transparent",
3398
- outline: "border border-input bg-transparent shadow-sm hover:bg-accent hover:text-accent-foreground"
3399
- },
3400
- size: {
3401
- default: "h-9 px-2 min-w-9 pointer-coarse:h-11 pointer-coarse:min-w-11",
3402
- sm: "h-8 px-1.5 min-w-8 pointer-coarse:h-11 pointer-coarse:min-w-11",
3403
- lg: "h-10 px-2.5 min-w-10 pointer-coarse:h-11 pointer-coarse:min-w-11"
3449
+ SelectSeparator.displayName = SelectPrimitive.Separator.displayName;
3450
+ var COLORS = {
3451
+ text: "text-secondary",
3452
+ bg: "bg-secondary"
3453
+ };
3454
+ function isItemShared(item) {
3455
+ return item.shared === true || item.is_shared === true;
3456
+ }
3457
+ function VisibilityToggle({
3458
+ items,
3459
+ presentation = "toggle",
3460
+ onToggle,
3461
+ disabled = false,
3462
+ disabledTooltip,
3463
+ disablePrivate = false,
3464
+ showLabel = true,
3465
+ showTooltip = true,
3466
+ tooltipActive,
3467
+ tooltipInactive,
3468
+ tooltipMixed,
3469
+ label = "Visibility",
3470
+ workspaceLabel = getEntityLabel("WORKSPACE"),
3471
+ "data-testid": dataTestId
3472
+ }) {
3473
+ const itemsArray = useMemo(() => Array.isArray(items) ? items : [items], [items]);
3474
+ const { isAllShared, isMixed } = useMemo(() => {
3475
+ if (itemsArray.length === 0) return { isAllShared: false, isMixed: false };
3476
+ const sharedCount = itemsArray.filter(isItemShared).length;
3477
+ return {
3478
+ isAllShared: sharedCount === itemsArray.length,
3479
+ isMixed: sharedCount > 0 && sharedCount < itemsArray.length
3480
+ };
3481
+ }, [itemsArray]);
3482
+ const isSingle = itemsArray.length === 1;
3483
+ const defaultTooltipActive = `Hide${isSingle ? "" : " all"} from ${workspaceLabel} members`;
3484
+ const defaultTooltipInactive = `Make${isSingle ? "" : " all"} visible to ${workspaceLabel} members`;
3485
+ const defaultTooltipMixed = `Make all visible to ${workspaceLabel} members (some already shared)`;
3486
+ const handleToggle = () => {
3487
+ const shouldShare = !isAllShared;
3488
+ if (disablePrivate && !shouldShare) return;
3489
+ onToggle(shouldShare);
3490
+ };
3491
+ if (presentation === "select")
3492
+ return /* @__PURE__ */ jsxs(
3493
+ Select,
3494
+ {
3495
+ value: isMixed ? "mixed" : isAllShared ? "workspace" : "me",
3496
+ onValueChange: (value) => onToggle(value === "workspace"),
3497
+ disabled: disabled || !itemsArray.length,
3498
+ children: [
3499
+ /* @__PURE__ */ jsxs(
3500
+ SelectTrigger,
3501
+ {
3502
+ "aria-label": label,
3503
+ "data-testid": dataTestId,
3504
+ className: "h-7 w-auto gap-1 border-0 bg-transparent px-1 text-xs font-normal text-muted-foreground shadow-none hover:bg-muted pointer-coarse:h-11",
3505
+ children: [
3506
+ showLabel && /* @__PURE__ */ jsxs("span", { children: [
3507
+ label,
3508
+ ":"
3509
+ ] }),
3510
+ /* @__PURE__ */ jsx(SelectValue, {})
3511
+ ]
3512
+ }
3513
+ ),
3514
+ /* @__PURE__ */ jsxs(SelectContent, { children: [
3515
+ /* @__PURE__ */ jsx(SelectItem, { value: "me", disabled: disablePrivate, children: "Me" }),
3516
+ /* @__PURE__ */ jsx(SelectItem, { value: "workspace", children: "Workspace" }),
3517
+ isMixed && /* @__PURE__ */ jsx(SelectItem, { value: "mixed", disabled: true, children: "Mixed" })
3518
+ ] })
3519
+ ]
3404
3520
  }
3405
- },
3406
- defaultVariants: {
3407
- variant: "default",
3408
- size: "default"
3521
+ );
3522
+ return /* @__PURE__ */ jsx(
3523
+ IconToggle,
3524
+ {
3525
+ icon: Share2,
3526
+ isActive: isAllShared,
3527
+ onToggle: handleToggle,
3528
+ colors: COLORS,
3529
+ inactiveColors: { text: "text-primary", bg: "bg-primary/10" },
3530
+ disabled: disabled || itemsArray.length === 0,
3531
+ disabledTooltip,
3532
+ showLabel,
3533
+ showTooltip,
3534
+ label,
3535
+ isMixed,
3536
+ tooltipActive: tooltipActive || defaultTooltipActive,
3537
+ tooltipInactive: tooltipInactive || defaultTooltipInactive,
3538
+ tooltipMixed: tooltipMixed || defaultTooltipMixed,
3539
+ "data-testid": dataTestId
3409
3540
  }
3410
- }
3411
- );
3412
- var Toggle = React.forwardRef(({ className, variant, size, ...props }, ref) => /* @__PURE__ */ jsx(
3413
- TogglePrimitive.Root,
3414
- {
3415
- ref,
3416
- className: cn(toggleVariants({ variant, size, className })),
3417
- ...props
3418
- }
3419
- ));
3420
- Toggle.displayName = TogglePrimitive.Root.displayName;
3421
- var ToggleGroupContext = React.createContext({
3422
- size: "default",
3423
- variant: "default"
3424
- });
3425
- var ToggleGroup = React.forwardRef(({ className, variant, size, children, ...props }, ref) => /* @__PURE__ */ jsx(
3426
- ToggleGroupPrimitive.Root,
3427
- {
3428
- ref,
3429
- className: cn("flex items-center justify-center gap-1", className),
3430
- ...props,
3431
- children: /* @__PURE__ */ jsx(ToggleGroupContext.Provider, { value: { variant, size }, children })
3432
- }
3433
- ));
3434
- ToggleGroup.displayName = ToggleGroupPrimitive.Root.displayName;
3435
- var ToggleGroupItem = React.forwardRef(({ className, children, variant, size, ...props }, ref) => {
3436
- const context = React.useContext(ToggleGroupContext);
3541
+ );
3542
+ }
3543
+ var COLORS2 = {
3544
+ text: "text-green-text",
3545
+ bg: "bg-green-text"
3546
+ };
3547
+ function VerifiedToggle({
3548
+ verified,
3549
+ onToggle,
3550
+ disabled = false,
3551
+ showLabel = true,
3552
+ showTooltip = true,
3553
+ tooltipActive,
3554
+ tooltipInactive,
3555
+ "data-testid": dataTestId
3556
+ }) {
3437
3557
  return /* @__PURE__ */ jsx(
3438
- ToggleGroupPrimitive.Item,
3558
+ IconToggle,
3439
3559
  {
3440
- ref,
3441
- className: cn(
3442
- toggleVariants({
3443
- variant: context.variant || variant,
3444
- size: context.size || size
3445
- }),
3446
- className
3447
- ),
3448
- ...props,
3449
- children
3560
+ icon: CheckCircle2,
3561
+ isActive: verified,
3562
+ onToggle,
3563
+ colors: COLORS2,
3564
+ disabled,
3565
+ showLabel,
3566
+ label: "Verified",
3567
+ showTooltip,
3568
+ tooltipActive: tooltipActive || "Verified by a human \u2014 click to unverify",
3569
+ tooltipInactive: tooltipInactive || "Not verified \u2014 click to verify",
3570
+ "data-testid": dataTestId
3450
3571
  }
3451
3572
  );
3452
- });
3453
- ToggleGroupItem.displayName = ToggleGroupPrimitive.Item.displayName;
3454
- var Popover = PopoverPrimitive.Root;
3455
- var PopoverTrigger = PopoverPrimitive.Trigger;
3456
- var PopoverAnchor = PopoverPrimitive.Anchor;
3457
- function PopoverPortal({
3458
- container,
3459
- ...props
3460
- }) {
3461
- const fallback = usePortalContainer();
3462
- return /* @__PURE__ */ jsx(PopoverPrimitive.Portal, { container: container ?? fallback, ...props });
3463
- }
3464
- var PopoverContent = React.forwardRef(({ className, align = "center", sideOffset = 4, container, ...props }, ref) => /* @__PURE__ */ jsx(PopoverPortal, { container: container ?? void 0, children: /* @__PURE__ */ jsx(
3465
- PopoverPrimitive.Content,
3466
- {
3467
- ref,
3468
- align,
3469
- sideOffset,
3470
- collisionPadding: getCollisionPadding(),
3471
- className: cn(
3472
- "z-50 w-72 max-w-[calc(100vw-1rem)] max-h-[var(--radix-popover-content-available-height)] overflow-y-auto overscroll-contain rounded-md border border-border bg-popover p-4 text-popover-foreground shadow-lg outline-none data-[state=open]:animate-in data-[state=closed]:animate-out data-[state=closed]:fade-out-0 data-[state=open]:fade-in-0 data-[state=closed]:zoom-out-95 data-[state=open]:zoom-in-95 data-[side=bottom]:slide-in-from-top-2 data-[side=left]:slide-in-from-right-2 data-[side=right]:slide-in-from-left-2 data-[side=top]:slide-in-from-bottom-2 origin-[--radix-popover-content-transform-origin]",
3473
- className
3474
- ),
3475
- ...props
3476
- }
3477
- ) }));
3478
- PopoverContent.displayName = PopoverPrimitive.Content.displayName;
3479
- var PopoverClose = PopoverPrimitive.Close;
3480
- var FINE_OPEN_DELAY = 350;
3481
- var FINE_CLOSE_DELAY = 180;
3482
- var silentFocusMarks = /* @__PURE__ */ new WeakSet();
3483
- function returnFocusToMark(mark) {
3484
- silentFocusMarks.add(mark);
3485
- mark.focus({ preventScroll: true });
3486
- silentFocusMarks.delete(mark);
3487
3573
  }
3488
- function isFocusVisible(el) {
3574
+
3575
+ // src/lib/format-friendly-date.ts
3576
+ function formatFriendlyDate(dateString, includeTime = true) {
3577
+ if (!dateString) return "";
3489
3578
  try {
3490
- return el.matches(":focus-visible");
3579
+ if (dateString.includes("Today") || dateString.includes("Yesterday") || /\w+ \d+, \d+:\d+:\d+/.test(dateString)) {
3580
+ return dateString;
3581
+ }
3582
+ if (/^\d{1,2}:\d{2}(:\d{2})?$/.test(dateString)) {
3583
+ return dateString;
3584
+ }
3585
+ const date = new Date(dateString);
3586
+ if (isNaN(date.getTime())) return dateString;
3587
+ const timeOptions = { hour: "2-digit", minute: "2-digit" };
3588
+ const timeString = date.toLocaleTimeString([], timeOptions);
3589
+ const now = /* @__PURE__ */ new Date();
3590
+ const today = now.toDateString();
3591
+ const yesterday = new Date(now);
3592
+ yesterday.setDate(yesterday.getDate() - 1);
3593
+ if (date.toDateString() === today) {
3594
+ return includeTime ? `Today, ${timeString}` : "today";
3595
+ } else if (date.toDateString() === yesterday.toDateString()) {
3596
+ return includeTime ? `Yesterday, ${timeString}` : "yesterday";
3597
+ } else {
3598
+ const dateOptions = {
3599
+ month: "short",
3600
+ day: "numeric"
3601
+ };
3602
+ if (date.getFullYear() !== now.getFullYear()) {
3603
+ dateOptions.year = "numeric";
3604
+ }
3605
+ const formattedDate = date.toLocaleDateString([], dateOptions);
3606
+ return includeTime ? `${formattedDate}, ${timeString}` : formattedDate;
3607
+ }
3491
3608
  } catch {
3492
- return true;
3609
+ return dateString;
3493
3610
  }
3494
3611
  }
3495
- function isCoarse(pointerType) {
3496
- if (pointerType === "touch" || pointerType === "pen") return true;
3497
- if (pointerType === "mouse") return false;
3498
- return typeof window !== "undefined" && !!window.matchMedia?.("(pointer: coarse)").matches;
3612
+
3613
+ // src/lib/markdown-to-text.ts
3614
+ function markdownToPlainText(input) {
3615
+ if (!input) return "";
3616
+ return input.replace(/```[^\n]*\n?/g, "").replace(/!\[([^\]]*)\]\([^)]*\)/g, "$1").replace(/\[([^\]]+)\]\([^)]*\)/g, "$1").replace(/^[ \t]*#{1,6}[ \t]+/gm, "").replace(/^[ \t]*>[ \t]?/gm, "").replace(/^[ \t]*([-*+]|\d+[.)])[ \t]+/gm, "").replace(/(\*\*|__)(.*?)\1/g, "$2").replace(/(\*|_)(.*?)\1/g, "$2").replace(/`([^`]*)`/g, "$1").replace(/\s+/g, " ").trim();
3499
3617
  }
3500
- function MarkMenu({
3501
- as = "span",
3502
- href,
3503
- items,
3504
- preview,
3505
- menuLabel,
3506
- shouldClickRunPrimary = true,
3507
- openDelay = FINE_OPEN_DELAY,
3508
- closeDelay = FINE_CLOSE_DELAY,
3509
- testId,
3510
- menuTestId,
3511
- triggerRef: externalRef,
3512
- className,
3513
- children,
3514
- onPointerDown,
3515
- onPointerEnter,
3516
- onPointerMove,
3517
- onPointerLeave,
3518
- onFocus,
3519
- onBlur,
3520
- onKeyDown,
3521
- ...rest
3522
- }) {
3523
- const [open, setOpen] = useState(false);
3524
- const [side, setSide] = useState("bottom");
3525
- const menuId = useId();
3526
- const triggerRef = useRef(null);
3527
- const contentRef = useRef(null);
3528
- const timer = useRef(null);
3529
- const mode = useRef("hover");
3530
- const lastPointer = useRef("mouse");
3531
- const focusFirstOnOpen = useRef(false);
3532
- const hoverArmed = useRef(false);
3533
- const isEmpty = items.length === 0 && !preview;
3534
- const ordered = [...items].sort((a, b) => Number(!!b.primary) - Number(!!a.primary));
3535
- const primary = ordered[0];
3536
- const clearTimer = () => {
3537
- if (timer.current) clearTimeout(timer.current);
3538
- timer.current = null;
3539
- };
3540
- useEffect(() => clearTimer, []);
3541
- useEffect(() => {
3542
- if (!open) return;
3543
- const onDocumentPointerDown = (e) => {
3544
- const target = e.target;
3545
- if (triggerRef.current?.contains(target) || contentRef.current?.contains(target)) return;
3546
- if (timer.current) clearTimeout(timer.current);
3547
- setOpen(false);
3548
- };
3549
- document.addEventListener("pointerdown", onDocumentPointerDown, true);
3550
- return () => document.removeEventListener("pointerdown", onDocumentPointerDown, true);
3551
- }, [open]);
3552
- const rows = () => Array.from(contentRef.current?.querySelectorAll('[role="menuitem"]') ?? []);
3553
- const firstItem = () => rows()[0];
3554
- const openWith = (next, focusFirst = false) => {
3555
- clearTimer();
3556
- mode.current = next;
3557
- focusFirstOnOpen.current = focusFirst;
3558
- setSide(next === "press" && isCoarse(lastPointer.current) ? "top" : "bottom");
3559
- setOpen(true);
3560
- if (focusFirst) {
3561
- requestAnimationFrame(() => firstItem()?.focus());
3562
- }
3563
- };
3564
- const close = (returnFocus = false) => {
3565
- clearTimer();
3566
- setOpen(false);
3567
- if (returnFocus && triggerRef.current) returnFocusToMark(triggerRef.current);
3568
- };
3569
- const schedule = (action, delay) => {
3570
- clearTimer();
3571
- timer.current = setTimeout(action, delay);
3572
- };
3573
- const handlePointerDown = (e) => {
3574
- lastPointer.current = e.pointerType;
3575
- onPointerDown?.(e);
3576
- };
3577
- const handlePointerEnter = (e) => {
3578
- onPointerEnter?.(e);
3579
- if (isCoarse(e.pointerType) || isEmpty) return;
3580
- lastPointer.current = e.pointerType;
3581
- hoverArmed.current = true;
3582
- };
3583
- const handlePointerMove = (e) => {
3584
- onPointerMove?.(e);
3585
- if (!hoverArmed.current) return;
3586
- hoverArmed.current = false;
3587
- if (isCoarse(e.pointerType)) return;
3588
- schedule(() => openWith("hover"), openDelay);
3589
- };
3590
- const handlePointerLeave = (e) => {
3591
- onPointerLeave?.(e);
3592
- hoverArmed.current = false;
3593
- if (isCoarse(e.pointerType)) return;
3594
- if (!open) return clearTimer();
3595
- if (mode.current === "hover") schedule(() => close(), closeDelay);
3596
- };
3597
- const handleFocus = (e) => {
3598
- onFocus?.(e);
3599
- if (isEmpty || silentFocusMarks.has(e.currentTarget)) return;
3600
- if (isFocusVisible(e.currentTarget)) schedule(() => openWith("focus"), openDelay);
3601
- };
3602
- const handleBlur = (e) => {
3603
- onBlur?.(e);
3604
- const next = e.relatedTarget;
3605
- if (next && contentRef.current?.contains(next)) return;
3606
- if (mode.current === "focus" || mode.current === "key") schedule(() => close(), closeDelay);
3607
- else clearTimer();
3608
- };
3609
- const handleKeyDown = (e) => {
3610
- onKeyDown?.(e);
3611
- lastPointer.current = "keyboard";
3612
- if (e.defaultPrevented || isEmpty) return;
3613
- if (e.key === "Enter" || e.key === " " || e.key === "ArrowDown") {
3614
- e.preventDefault();
3615
- openWith("key", true);
3616
- } else if (e.key === "Escape" && open) {
3617
- e.preventDefault();
3618
- e.stopPropagation();
3619
- close(true);
3620
- }
3621
- };
3622
- const handleClick = (e) => {
3623
- if (isEmpty) return;
3624
- if (e.metaKey || e.ctrlKey || e.shiftKey || e.altKey) return;
3625
- if (e.detail === 0 && lastPointer.current === "keyboard") {
3626
- e.preventDefault();
3627
- return;
3628
- }
3629
- if (isCoarse(lastPointer.current)) {
3630
- e.preventDefault();
3631
- if (open) close();
3632
- else openWith("press");
3633
- return;
3634
- }
3635
- if (shouldClickRunPrimary && primary?.onSelect) {
3636
- e.preventDefault();
3637
- close();
3638
- primary.onSelect();
3639
- }
3640
- };
3641
- const handleMenuKeyDown = (e) => {
3642
- const list = rows();
3643
- const index = list.indexOf(document.activeElement);
3644
- let target;
3645
- if (e.key === "ArrowDown") target = list[(index + 1) % list.length];
3646
- else if (e.key === "ArrowUp") target = list[(index - 1 + list.length) % list.length];
3647
- else if (e.key === "Home") target = list[0];
3648
- else if (e.key === "End") target = list[list.length - 1];
3649
- else if (e.key === "Escape") {
3650
- e.preventDefault();
3651
- e.stopPropagation();
3652
- close(true);
3653
- return;
3654
- } else if (e.key === "Tab") {
3655
- close();
3656
- return;
3618
+ var TABLE_DELIMITER_ROW = /^\s*\|?\s*:?-{3,}:?\s*(\|\s*:?-{3,}:?\s*)*\|?\s*$/;
3619
+ function splitTableRow(line) {
3620
+ return line.trim().replace(/^\|/, "").replace(/(?<!\\)\|$/, "").split(/(?<!\\)\|/).map((cell) => cell.trim().replace(/\\\|/g, "|"));
3621
+ }
3622
+ function flattenMarkdownTables(input) {
3623
+ const lines = input.split("\n");
3624
+ const out = [];
3625
+ for (let i = 0; i < lines.length; i++) {
3626
+ const isTableStart = lines[i].includes("|") && i + 1 < lines.length && lines[i + 1].includes("|") && TABLE_DELIMITER_ROW.test(lines[i + 1]);
3627
+ if (!isTableStart) {
3628
+ out.push(lines[i]);
3629
+ continue;
3657
3630
  }
3658
- if (target) {
3659
- e.preventDefault();
3660
- target.focus();
3631
+ out.push(splitTableRow(lines[i]).join(" "));
3632
+ i += 1;
3633
+ while (i + 1 < lines.length && lines[i + 1].includes("|") && lines[i + 1].trim()) {
3634
+ i += 1;
3635
+ out.push(splitTableRow(lines[i]).join(" "));
3661
3636
  }
3662
- };
3663
- const choose = (item) => {
3664
- const wasKey = mode.current === "key";
3665
- close(wasKey);
3666
- item.onSelect?.();
3667
- };
3668
- const setTriggerRef = useCallback(
3669
- (el) => {
3670
- triggerRef.current = el;
3671
- if (typeof externalRef === "function") externalRef(el);
3672
- else if (externalRef) externalRef.current = el;
3673
- },
3674
- [externalRef]
3675
- );
3676
- const triggerProps = {
3677
- ref: setTriggerRef,
3678
- className,
3679
- "data-testid": testId,
3680
- "data-slot": "mark",
3681
- "aria-haspopup": "true",
3682
- "aria-expanded": open,
3683
- "aria-controls": open ? menuId : void 0,
3684
- onPointerDown: handlePointerDown,
3685
- onPointerEnter: handlePointerEnter,
3686
- onPointerMove: handlePointerMove,
3687
- onPointerLeave: handlePointerLeave,
3688
- onFocus: handleFocus,
3689
- onBlur: handleBlur,
3690
- onKeyDown: handleKeyDown,
3691
- onClick: handleClick,
3692
- ...rest
3693
- };
3694
- return /* @__PURE__ */ jsxs(Popover, { open: open && !isEmpty, children: [
3695
- /* @__PURE__ */ jsx(PopoverAnchor, { asChild: true, children: as === "a" ? /* @__PURE__ */ jsx("a", { href, ...triggerProps, children }) : /* @__PURE__ */ jsx("span", { role: "button", tabIndex: 0, ...triggerProps, children }) }),
3696
- /* @__PURE__ */ jsxs(
3697
- PopoverContent,
3637
+ }
3638
+ return out.join("\n");
3639
+ }
3640
+ function markdownToPlainTextBlocks(input) {
3641
+ if (!input) return "";
3642
+ return flattenMarkdownTables(input).replace(/^[ \t]*([-*_])([ \t]*\1){2,}[ \t]*$/gm, "").replace(/```[^\n]*\n?/g, "").replace(/!\[([^\]]*)\]\([^)]*\)/g, "$1").replace(/\[([^\]]+)\]\(([^)\s]+)\)/g, "$1 ($2)").replace(/^[ \t]*#{1,6}[ \t]+/gm, "").replace(/^[ \t]*>[ \t]?/gm, "").replace(/(\*\*|__)(?=\S)(.+?)(?<=\S)\1/g, "$2").replace(/\*(?=\S)(.+?)(?<=\S)\*/g, "$1").replace(/(^|[^\w])_(?=\S)(.+?)(?<=\S)_(?!\w)/g, "$1$2").replace(/`([^`]*)`/g, "$1").replace(/[ \t]+\n/g, "\n").replace(/\n{3,}/g, "\n\n").trim();
3643
+ }
3644
+
3645
+ // src/ui/DictateContext.tsx
3646
+ function useDictateContext() {
3647
+ return useHostConfigRecord().dictate ?? null;
3648
+ }
3649
+ var Input = React.forwardRef(
3650
+ ({ className, type, dictate, onFocus, onBlur, ...props }, forwardedRef) => {
3651
+ const dictateCtx = useDictateContext();
3652
+ const [focused, setFocused] = React.useState(false);
3653
+ const innerRef = React.useRef(null);
3654
+ React.useImperativeHandle(forwardedRef, () => innerRef.current);
3655
+ const showDictate = dictate && !!dictateCtx && !props.disabled && !props.readOnly;
3656
+ const input = /* @__PURE__ */ jsx(
3657
+ "input",
3698
3658
  {
3699
- ref: contentRef,
3700
- id: menuId,
3701
- side,
3702
- align: "start",
3703
- sideOffset: 6,
3704
- collisionPadding: 8,
3705
- role: "group",
3706
- "data-testid": menuTestId,
3707
- "data-slot": "mark-menu",
3708
- className: "w-auto min-w-[12rem] max-w-[min(22rem,calc(100vw-1rem))] p-1",
3709
- onOpenAutoFocus: (e) => {
3710
- e.preventDefault();
3711
- if (focusFirstOnOpen.current) firstItem()?.focus();
3659
+ type,
3660
+ "data-slot": "input",
3661
+ className: cn(
3662
+ "flex h-9 pointer-coarse:h-11 w-full rounded-md border border-input bg-background px-3 py-1 text-base shadow-sm transition-colors file:border-0 file:bg-transparent file:text-sm file:font-medium file:text-foreground placeholder:text-muted-foreground/60 focus-visible:outline-none focus-visible:border-ring/50 disabled:cursor-not-allowed disabled:opacity-50 md:text-sm",
3663
+ showDictate && "pr-9",
3664
+ className
3665
+ ),
3666
+ ref: innerRef,
3667
+ onFocus: (e) => {
3668
+ setFocused(true);
3669
+ onFocus?.(e);
3712
3670
  },
3713
- onCloseAutoFocus: (e) => e.preventDefault(),
3714
- onEscapeKeyDown: (e) => {
3715
- e.preventDefault();
3716
- close(true);
3671
+ onBlur: (e) => {
3672
+ setFocused(false);
3673
+ onBlur?.(e);
3717
3674
  },
3718
- onInteractOutside: (e) => {
3719
- if (triggerRef.current?.contains(e.target)) e.preventDefault();
3675
+ ...props
3676
+ }
3677
+ );
3678
+ if (!showDictate) return input;
3679
+ return /* @__PURE__ */ jsxs("div", { className: "relative w-full", children: [
3680
+ input,
3681
+ /* @__PURE__ */ jsx(
3682
+ InlineMicButton,
3683
+ {
3684
+ focused,
3685
+ transcribe: dictateCtx.transcribe,
3686
+ onError: dictateCtx.onError,
3687
+ className: "absolute right-1.5 top-1/2 -translate-y-1/2",
3688
+ onTranscript: (text) => {
3689
+ const el = innerRef.current;
3690
+ if (!el) return;
3691
+ const next = el.value ? `${el.value} ${text}` : text;
3692
+ const setter = Object.getOwnPropertyDescriptor(
3693
+ window.HTMLInputElement.prototype,
3694
+ "value"
3695
+ )?.set;
3696
+ setter?.call(el, next);
3697
+ el.dispatchEvent(new Event("input", { bubbles: true }));
3698
+ }
3699
+ }
3700
+ )
3701
+ ] });
3702
+ }
3703
+ );
3704
+ Input.displayName = "Input";
3705
+ var Textarea = React.forwardRef(
3706
+ ({ className, dictate, onFocus, onBlur, ...props }, forwardedRef) => {
3707
+ const dictateCtx = useDictateContext();
3708
+ const [focused, setFocused] = React.useState(false);
3709
+ const innerRef = React.useRef(null);
3710
+ React.useImperativeHandle(forwardedRef, () => innerRef.current);
3711
+ const showDictate = dictate && !!dictateCtx && !props.disabled && !props.readOnly;
3712
+ const textarea = /* @__PURE__ */ jsx(
3713
+ "textarea",
3714
+ {
3715
+ className: cn(
3716
+ "flex min-h-[60px] w-full rounded-md border border-input bg-background px-3 py-2 text-base shadow-sm placeholder:text-muted-foreground/60 focus-visible:outline-none focus-visible:border-ring/50 disabled:cursor-not-allowed disabled:opacity-50 md:text-sm",
3717
+ showDictate && "pr-9",
3718
+ className
3719
+ ),
3720
+ ref: innerRef,
3721
+ onFocus: (e) => {
3722
+ setFocused(true);
3723
+ onFocus?.(e);
3720
3724
  },
3721
- onPointerEnter: clearTimer,
3722
- onPointerLeave: (e) => {
3723
- if (!isCoarse(e.pointerType) && mode.current === "hover")
3724
- schedule(() => close(), closeDelay);
3725
+ onBlur: (e) => {
3726
+ setFocused(false);
3727
+ onBlur?.(e);
3725
3728
  },
3726
- children: [
3727
- preview && /* @__PURE__ */ jsx("div", { className: "px-2 py-1.5 text-sm", children: preview }),
3728
- ordered.length > 0 && /* @__PURE__ */ jsx("div", { role: "menu", "aria-label": menuLabel, onKeyDown: handleMenuKeyDown, children: ordered.map((item) => {
3729
- const rowClass = cn(
3730
- "flex w-full cursor-pointer items-center rounded-sm px-2 py-1.5 text-left text-sm outline-none transition-colors hover:bg-accent focus-visible:bg-accent pointer-coarse:min-h-11 pointer-coarse:px-3",
3731
- item.primary && "font-medium pointer-coarse:text-base",
3732
- item.destructive && "text-destructive"
3733
- );
3734
- return item.href && !item.onSelect ? /* @__PURE__ */ jsx(
3735
- "a",
3736
- {
3737
- role: "menuitem",
3738
- tabIndex: -1,
3739
- href: item.href,
3740
- className: rowClass,
3741
- "data-testid": item.testId,
3742
- onClick: () => close(),
3743
- children: item.label
3744
- },
3745
- item.id
3746
- ) : /* @__PURE__ */ jsx(
3747
- "button",
3748
- {
3749
- type: "button",
3750
- role: "menuitem",
3751
- tabIndex: -1,
3752
- className: rowClass,
3753
- "data-testid": item.testId,
3754
- onClick: () => choose(item),
3755
- children: item.label
3756
- },
3757
- item.id
3758
- );
3759
- }) })
3760
- ]
3729
+ ...props
3730
+ }
3731
+ );
3732
+ if (!showDictate) return textarea;
3733
+ return /* @__PURE__ */ jsxs("div", { className: "relative w-full", children: [
3734
+ textarea,
3735
+ /* @__PURE__ */ jsx(
3736
+ InlineMicButton,
3737
+ {
3738
+ focused,
3739
+ transcribe: dictateCtx.transcribe,
3740
+ onError: dictateCtx.onError,
3741
+ className: "absolute right-1.5 top-1.5",
3742
+ onTranscript: (text) => {
3743
+ const el = innerRef.current;
3744
+ if (!el) return;
3745
+ const next = el.value ? `${el.value} ${text}` : text;
3746
+ const setter = Object.getOwnPropertyDescriptor(
3747
+ window.HTMLTextAreaElement.prototype,
3748
+ "value"
3749
+ )?.set;
3750
+ setter?.call(el, next);
3751
+ el.dispatchEvent(new Event("input", { bubbles: true }));
3752
+ }
3753
+ }
3754
+ )
3755
+ ] });
3756
+ }
3757
+ );
3758
+ Textarea.displayName = "Textarea";
3759
+ function DebouncedInput({
3760
+ value,
3761
+ onChange,
3762
+ disabled,
3763
+ type = "text",
3764
+ multiline = false,
3765
+ className,
3766
+ debounceMs = 500,
3767
+ placeholder,
3768
+ autoResize = true,
3769
+ minHeight = 28,
3770
+ maxHeight = 72
3771
+ }) {
3772
+ const [localValue, setLocalValue] = useState(value);
3773
+ const timeoutRef = useRef(void 0);
3774
+ const pendingRef = useRef(null);
3775
+ const textareaRef = useRef(null);
3776
+ const adjustHeight = useCallback(() => {
3777
+ const textarea = textareaRef.current;
3778
+ if (!textarea || !autoResize) return;
3779
+ textarea.style.height = "auto";
3780
+ const newHeight = Math.min(Math.max(textarea.scrollHeight, minHeight), maxHeight);
3781
+ textarea.style.height = `${newHeight}px`;
3782
+ }, [autoResize, minHeight, maxHeight]);
3783
+ useEffect(() => {
3784
+ if (pendingRef.current !== null) return;
3785
+ setLocalValue(value);
3786
+ }, [value]);
3787
+ useEffect(() => {
3788
+ if (multiline) {
3789
+ adjustHeight();
3790
+ }
3791
+ }, [localValue, multiline, adjustHeight]);
3792
+ const onChangeRef = useRef(onChange);
3793
+ useEffect(() => {
3794
+ onChangeRef.current = onChange;
3795
+ }, [onChange]);
3796
+ const flushPendingChange = useCallback(() => {
3797
+ if (pendingRef.current === null) return false;
3798
+ const pending = pendingRef.current;
3799
+ pendingRef.current = null;
3800
+ clearTimeout(timeoutRef.current);
3801
+ onChangeRef.current(pending);
3802
+ return true;
3803
+ }, []);
3804
+ const handleChange = useCallback(
3805
+ (e) => {
3806
+ const newValue = e.target.value;
3807
+ setLocalValue(newValue);
3808
+ pendingRef.current = newValue;
3809
+ clearTimeout(timeoutRef.current);
3810
+ timeoutRef.current = setTimeout(() => {
3811
+ pendingRef.current = null;
3812
+ onChangeRef.current(newValue);
3813
+ }, debounceMs);
3814
+ },
3815
+ [debounceMs]
3816
+ );
3817
+ useEffect(
3818
+ () => () => {
3819
+ const pending = pendingRef.current;
3820
+ pendingRef.current = null;
3821
+ clearTimeout(timeoutRef.current);
3822
+ if (pending !== null) onChangeRef.current(pending);
3823
+ },
3824
+ []
3825
+ );
3826
+ const handleBlur = useCallback(() => {
3827
+ flushPendingChange();
3828
+ if (localValue !== value) {
3829
+ setLocalValue(value);
3830
+ }
3831
+ }, [flushPendingChange, localValue, value]);
3832
+ if (multiline) {
3833
+ return /* @__PURE__ */ jsx(
3834
+ Textarea,
3835
+ {
3836
+ ref: textareaRef,
3837
+ value: localValue,
3838
+ onChange: handleChange,
3839
+ onBlur: handleBlur,
3840
+ disabled,
3841
+ className: `resize-y ${className || ""}`,
3842
+ placeholder,
3843
+ style: { minHeight: `${minHeight}px` }
3761
3844
  }
3762
- )
3763
- ] });
3764
- }
3765
- var Command = React.forwardRef(({ className, ...props }, ref) => /* @__PURE__ */ jsx(
3766
- Command$1,
3767
- {
3768
- ref,
3769
- className: cn(
3770
- "flex h-full w-full flex-col overflow-hidden rounded-md bg-popover text-popover-foreground",
3771
- className
3772
- ),
3773
- ...props
3845
+ );
3774
3846
  }
3775
- ));
3776
- Command.displayName = Command$1.displayName;
3777
- var CommandDialog = ({ children, ...props }) => {
3778
- return /* @__PURE__ */ jsx(Dialog, { ...props, children: /* @__PURE__ */ jsx(DialogContent, { className: "overflow-hidden p-0", children: /* @__PURE__ */ jsx(Command, { className: "[&_[cmdk-group-heading]]:px-2 [&_[cmdk-group-heading]]:font-medium [&_[cmdk-group-heading]]:text-muted-foreground [&_[cmdk-group]:not([hidden])_~[cmdk-group]]:pt-0 [&_[cmdk-group]]:px-2 [&_[cmdk-input-wrapper]_svg]:h-5 [&_[cmdk-input-wrapper]_svg]:w-5 [&_[cmdk-input]]:h-12 [&_[cmdk-item]]:px-2 [&_[cmdk-item]]:py-3 [&_[cmdk-item]_svg]:h-5 [&_[cmdk-item]_svg]:w-5", children }) }) });
3779
- };
3780
- var CommandInput = React.forwardRef(({ className, ...props }, ref) => /* @__PURE__ */ jsxs("div", { className: "flex items-center border-b px-3", "data-cmdk-input-wrapper": "", children: [
3781
- /* @__PURE__ */ jsx(Search, { className: "mr-2 h-4 w-4 shrink-0 opacity-50" }),
3782
- /* @__PURE__ */ jsx(
3783
- Command$1.Input,
3847
+ return /* @__PURE__ */ jsx(
3848
+ Input,
3784
3849
  {
3785
- ref,
3786
- className: cn(
3787
- "flex h-10 pointer-coarse:h-11 w-full rounded-md bg-transparent py-3 text-sm outline-none placeholder:text-muted-foreground disabled:cursor-not-allowed disabled:opacity-50",
3788
- className
3789
- ),
3790
- ...props
3850
+ type,
3851
+ value: localValue,
3852
+ onChange: handleChange,
3853
+ onBlur: handleBlur,
3854
+ disabled,
3855
+ className,
3856
+ placeholder
3791
3857
  }
3792
- )
3793
- ] }));
3794
- CommandInput.displayName = Command$1.Input.displayName;
3795
- var CommandList = React.forwardRef(({ className, ...props }, ref) => /* @__PURE__ */ jsx(
3796
- Command$1.List,
3797
- {
3798
- ref,
3799
- className: cn("max-h-[min(300px,50dvh)] overflow-y-auto overflow-x-hidden", className),
3800
- ...props
3801
- }
3802
- ));
3803
- CommandList.displayName = Command$1.List.displayName;
3804
- var CommandEmpty = React.forwardRef((props, ref) => /* @__PURE__ */ jsx(Command$1.Empty, { ref, className: "py-6 text-center text-sm", ...props }));
3805
- CommandEmpty.displayName = Command$1.Empty.displayName;
3806
- var CommandGroup = React.forwardRef(({ className, ...props }, ref) => /* @__PURE__ */ jsx(
3807
- Command$1.Group,
3858
+ );
3859
+ }
3860
+ var HoverCard = HoverCardPrimitive.Root;
3861
+ var HoverCardTrigger = HoverCardPrimitive.Trigger;
3862
+ function HoverCardPortal({
3863
+ container,
3864
+ ...props
3865
+ }) {
3866
+ const fallback = usePortalContainer();
3867
+ return /* @__PURE__ */ jsx(HoverCardPrimitive.Portal, { container: container ?? fallback, ...props });
3868
+ }
3869
+ var HoverCardContent = React.forwardRef(({ className, align = "center", sideOffset = 4, ...props }, ref) => /* @__PURE__ */ jsx(HoverCardPortal, { children: /* @__PURE__ */ jsx(
3870
+ HoverCardPrimitive.Content,
3808
3871
  {
3809
3872
  ref,
3873
+ align,
3874
+ sideOffset,
3875
+ collisionPadding: getCollisionPadding(),
3810
3876
  className: cn(
3811
- "overflow-hidden p-1 text-foreground [&_[cmdk-group-heading]]:px-2 [&_[cmdk-group-heading]]:py-1.5 [&_[cmdk-group-heading]]:text-sm [&_[cmdk-group-heading]]:font-medium [&_[cmdk-group-heading]]:text-muted-foreground",
3877
+ "z-50 w-64 max-w-[calc(100vw-1rem)] rounded-md border bg-popover p-4 text-popover-foreground shadow-lg outline-none data-[state=open]:animate-in data-[state=closed]:animate-out data-[state=closed]:fade-out-0 data-[state=open]:fade-in-0 data-[state=closed]:zoom-out-95 data-[state=open]:zoom-in-95 data-[side=bottom]:slide-in-from-top-2 data-[side=left]:slide-in-from-right-2 data-[side=right]:slide-in-from-left-2 data-[side=top]:slide-in-from-bottom-2 origin-[--radix-hover-card-content-transform-origin]",
3812
3878
  className
3813
3879
  ),
3814
3880
  ...props
3815
3881
  }
3816
- ));
3817
- CommandGroup.displayName = Command$1.Group.displayName;
3818
- var CommandSeparator = React.forwardRef(({ className, ...props }, ref) => /* @__PURE__ */ jsx(
3819
- Command$1.Separator,
3820
- {
3821
- ref,
3822
- className: cn("-mx-1 h-px bg-border", className),
3823
- ...props
3824
- }
3825
- ));
3826
- CommandSeparator.displayName = Command$1.Separator.displayName;
3827
- var CommandItem = React.forwardRef(({ className, ...props }, ref) => /* @__PURE__ */ jsx(
3828
- Command$1.Item,
3829
- {
3830
- ref,
3831
- className: cn(
3832
- "relative flex cursor-default gap-2 select-none items-center rounded-sm px-2 py-1.5 pointer-coarse:min-h-11 text-sm outline-none data-[disabled=true]:pointer-events-none data-[selected=true]:bg-accent data-[selected=true]:text-accent-foreground data-[disabled=true]:opacity-50 [&_svg]:pointer-events-none [&_svg]:size-4 [&_svg]:shrink-0",
3833
- className
3834
- ),
3835
- ...props
3882
+ ) }));
3883
+ HoverCardContent.displayName = HoverCardPrimitive.Content.displayName;
3884
+ var cardVariants = cva("min-w-0 rounded-lg bg-card text-card-foreground", {
3885
+ variants: {
3886
+ variant: {
3887
+ flat: "",
3888
+ outline: "border",
3889
+ elevated: "border shadow-sm"
3890
+ }
3891
+ },
3892
+ defaultVariants: {
3893
+ variant: "flat"
3836
3894
  }
3837
- ));
3838
- CommandItem.displayName = Command$1.Item.displayName;
3839
- var CommandShortcut = ({ className, ...props }) => {
3840
- return /* @__PURE__ */ jsx(
3841
- "span",
3895
+ });
3896
+ var Card = React.forwardRef(
3897
+ ({ className, variant, ...props }, ref) => /* @__PURE__ */ jsx(
3898
+ "div",
3842
3899
  {
3843
- className: cn("ml-auto text-sm tracking-widest text-muted-foreground", className),
3900
+ ref,
3901
+ "data-slot": "card",
3902
+ className: cn(cardVariants({ variant }), className),
3844
3903
  ...props
3845
3904
  }
3846
- );
3847
- };
3848
- CommandShortcut.displayName = "CommandShortcut";
3849
- var AI_COMPONENTS = {
3850
- a: (p) => /* @__PURE__ */ jsx(
3851
- "a",
3852
- {
3853
- className: "text-ai-accent underline underline-offset-2",
3854
- target: "_blank",
3855
- rel: "noopener noreferrer",
3856
- ...p
3857
- }
3858
- ),
3859
- // Redline marks: deletions in red strike, <ins>/<mark> additions accented.
3860
- del: (p) => /* @__PURE__ */ jsx("del", { className: "rounded bg-destructive/10 text-destructive decoration-destructive/60", ...p }),
3861
- ins: (p) => /* @__PURE__ */ jsx("ins", { className: "rounded bg-ai-accent-soft px-0.5 text-ai-accent no-underline", ...p }),
3862
- mark: (p) => /* @__PURE__ */ jsx("mark", { className: "rounded bg-ai-accent-soft px-0.5 text-ai-accent", ...p }),
3863
- thead: (p) => /* @__PURE__ */ jsx("thead", { className: "bg-secondary/60", ...p })
3864
- };
3865
- function AiMarkdown({
3866
- children,
3867
- className,
3868
- isStreaming,
3869
- allowHtml
3870
- }) {
3871
- return /* @__PURE__ */ jsx(
3872
- MarkdownRenderer,
3873
- {
3874
- className: className ?? "text-sm",
3875
- components: AI_COMPONENTS,
3876
- isStreaming,
3877
- allowHtml,
3878
- testId: "ai-markdown",
3879
- children
3880
- }
3881
- );
3882
- }
3883
- var TIERS = [
3884
- { min: 0.7, tone: "bg-emerald-500", label: "High relevance" },
3885
- { min: 0.4, tone: "bg-amber-500", label: "Medium relevance" },
3886
- { min: -Infinity, tone: "bg-muted-foreground/40", label: "Low relevance" }
3887
- ];
3888
- function RelevanceDot({ score }) {
3889
- if (score == null) return null;
3890
- const tier = TIERS.find((t) => score >= t.min) ?? TIERS[TIERS.length - 1];
3891
- return /* @__PURE__ */ jsx(
3892
- "span",
3905
+ )
3906
+ );
3907
+ Card.displayName = "Card";
3908
+ var CardHeader = React.forwardRef(
3909
+ ({ className, ...props }, ref) => /* @__PURE__ */ jsx(
3910
+ "div",
3893
3911
  {
3894
- role: "img",
3895
- "aria-label": tier.label,
3896
- title: `${tier.label} (${score.toFixed(2)})`,
3897
- className: cn("size-1.5 shrink-0 rounded-full", tier.tone),
3898
- "data-testid": "passage-relevance"
3912
+ ref,
3913
+ "data-slot": "card-header",
3914
+ className: cn("flex flex-col space-y-1.5 p-6", className),
3915
+ ...props
3899
3916
  }
3900
- );
3901
- }
3902
- function PassageCard({
3903
- header,
3904
- score,
3905
- headerRight,
3906
- active,
3907
- onClick,
3908
- footer,
3909
- className,
3910
- children,
3911
- "data-testid": testId
3912
- }) {
3913
- const body = /* @__PURE__ */ jsxs(Fragment, { children: [
3914
- /* @__PURE__ */ jsxs("div", { className: "mb-1.5 flex items-center gap-2", children: [
3915
- header,
3916
- (score != null || headerRight) && /* @__PURE__ */ jsxs("div", { className: "ml-auto flex shrink-0 items-center gap-2", children: [
3917
- /* @__PURE__ */ jsx(RelevanceDot, { score }),
3918
- headerRight
3919
- ] })
3920
- ] }),
3921
- /* @__PURE__ */ jsx("div", { className: "[&_mark]:rounded-sm [&_mark]:bg-ai-accent/20 [&_mark]:px-0.5 [&_mark]:font-medium [&_mark]:text-foreground", children })
3922
- ] });
3923
- return /* @__PURE__ */ jsxs(
3917
+ )
3918
+ );
3919
+ CardHeader.displayName = "CardHeader";
3920
+ var CardTitle = React.forwardRef(
3921
+ ({ className, ...props }, ref) => /* @__PURE__ */ jsx(
3924
3922
  "div",
3925
3923
  {
3926
- className: cn(
3927
- "group rounded-lg border border-border bg-card p-3 text-left transition-colors",
3928
- onClick && "hover:border-ai-accent/40 focus-within:ring-2 focus-within:ring-ai-accent/40",
3929
- active && "border-ai-accent/60 ring-1 ring-ai-accent/30",
3930
- className
3931
- ),
3932
- children: [
3933
- onClick ? /* @__PURE__ */ jsx(
3934
- "div",
3935
- {
3936
- role: "button",
3937
- tabIndex: 0,
3938
- onClick,
3939
- onKeyDown: (e) => {
3940
- if (e.key === "Enter" || e.key === " ") {
3941
- e.preventDefault();
3942
- onClick(e);
3943
- }
3944
- },
3945
- "aria-current": active || void 0,
3946
- "data-testid": testId,
3947
- className: "cursor-pointer focus:outline-none",
3948
- children: body
3949
- }
3950
- ) : /* @__PURE__ */ jsx("div", { "aria-current": active || void 0, "data-testid": testId, children: body }),
3951
- footer
3952
- ]
3924
+ ref,
3925
+ "data-slot": "card-title",
3926
+ className: cn("font-semibold leading-none tracking-tight", className),
3927
+ ...props
3953
3928
  }
3954
- );
3955
- }
3956
- var TextIcon = FileText;
3957
- var IMAGE_EXTENSIONS3 = /* @__PURE__ */ new Set(["jpg", "jpeg", "png", "gif", "bmp", "tiff", "tif", "webp", "svg"]);
3958
- var VIDEO_EXTENSIONS3 = /* @__PURE__ */ new Set(["mp4", "mpeg", "mpg", "webm", "mov", "avi", "mkv"]);
3959
- var AUDIO_EXTENSIONS3 = /* @__PURE__ */ new Set(["mp3", "wav", "m4a", "aac", "ogg", "flac"]);
3960
- var DOCX_EXTENSIONS2 = /* @__PURE__ */ new Set(["doc", "docx", "odt", "rtf"]);
3961
- var XLSX_EXTENSIONS2 = /* @__PURE__ */ new Set(["xls", "xlsx", "csv", "ods"]);
3962
- var EMAIL_EXTENSIONS3 = /* @__PURE__ */ new Set(["eml", "msg"]);
3963
- var HTML_EXTENSIONS2 = /* @__PURE__ */ new Set(["html", "htm", "mhtml"]);
3964
- var PDF_EXTENSIONS = /* @__PURE__ */ new Set(["pdf"]);
3965
- var TEXT_EXTENSIONS2 = /* @__PURE__ */ new Set([
3966
- "txt",
3967
- "text",
3968
- "md",
3969
- "markdown",
3970
- "log",
3971
- "json",
3972
- "xml",
3973
- "yaml",
3974
- "yml"
3975
- ]);
3976
- function getFileExtension(fileName) {
3977
- if (!fileName) return "";
3978
- const dot = fileName.lastIndexOf(".");
3979
- if (dot <= 0 || dot === fileName.length - 1) return "";
3980
- return fileName.slice(dot + 1).toLowerCase();
3981
- }
3982
- var MIME_TO_EXTENSION = {
3983
- "application/pdf": "pdf",
3984
- "text/plain": "txt",
3985
- "text/markdown": "md",
3986
- "text/html": "html",
3987
- "text/csv": "csv",
3988
- "application/json": "json",
3989
- "application/xml": "xml",
3990
- "application/msword": "doc",
3991
- "application/vnd.openxmlformats-officedocument.wordprocessingml.document": "docx",
3992
- "application/rtf": "rtf",
3993
- "application/vnd.oasis.opendocument.text": "odt",
3994
- "application/vnd.ms-excel": "xls",
3995
- "application/vnd.openxmlformats-officedocument.spreadsheetml.sheet": "xlsx",
3996
- "application/vnd.oasis.opendocument.spreadsheet": "ods",
3997
- "image/png": "png",
3998
- "image/jpeg": "jpg",
3999
- "image/gif": "gif",
4000
- "image/webp": "webp",
4001
- "image/svg+xml": "svg",
4002
- "image/tiff": "tiff",
4003
- "image/bmp": "bmp",
4004
- "video/mp4": "mp4",
4005
- "video/webm": "webm",
4006
- "video/quicktime": "mov",
4007
- "audio/mpeg": "mp3",
4008
- "audio/wav": "wav",
4009
- "audio/ogg": "ogg",
4010
- "message/rfc822": "eml"
4011
- };
4012
- function extensionFromMime(mime) {
4013
- if (!mime) return "";
4014
- return MIME_TO_EXTENSION[mime.toLowerCase()] ?? "";
4015
- }
4016
- function iconFromExtension(ext) {
4017
- if (VIDEO_EXTENSIONS3.has(ext)) return VidIcon;
4018
- if (AUDIO_EXTENSIONS3.has(ext)) return AudIcon;
4019
- if (IMAGE_EXTENSIONS3.has(ext)) return ImgIcon;
4020
- if (DOCX_EXTENSIONS2.has(ext)) return DocIcon;
4021
- if (XLSX_EXTENSIONS2.has(ext)) return XlsIcon;
4022
- if (EMAIL_EXTENSIONS3.has(ext)) return EmlIcon;
4023
- if (HTML_EXTENSIONS2.has(ext)) return HtmlIcon;
4024
- if (PDF_EXTENSIONS.has(ext)) return PdfIcon;
4025
- if (TEXT_EXTENSIONS2.has(ext)) return TextIcon;
4026
- return null;
4027
- }
4028
- function iconFromMime(mime) {
4029
- const m = mime.toLowerCase();
4030
- if (m.startsWith("image/")) return ImgIcon;
4031
- if (m.startsWith("video/")) return VidIcon;
4032
- if (m.startsWith("audio/")) return AudIcon;
4033
- if (m === "application/pdf") return PdfIcon;
4034
- if (m === "text/html") return HtmlIcon;
4035
- if (m === "message/rfc822" || m.includes("outlook")) return EmlIcon;
4036
- if (m.includes("word") || m === "application/rtf" || m.includes("opendocument.text"))
4037
- return DocIcon;
4038
- if (m.includes("sheet") || m.includes("excel") || m === "text/csv" || m.includes("opendocument.spreadsheet"))
4039
- return XlsIcon;
4040
- if (m.startsWith("text/") || m === "application/json" || m === "application/xml") return TextIcon;
4041
- return null;
4042
- }
4043
- function getFileTypeIcon(fileName, opts) {
4044
- return iconFromExtension(getFileExtension(fileName)) ?? (opts?.mime ? iconFromMime(opts.mime) : null) ?? (opts?.defaultToPdf ? PdfIcon : TextIcon);
4045
- }
4046
- var GoogleIcon = ({
4047
- size = 20,
4048
- className = "",
4049
- "aria-label": ariaLabel,
4050
- "aria-hidden": ariaHidden = true
4051
- }) => {
4052
- return /* @__PURE__ */ jsxs(
4053
- "svg",
3929
+ )
3930
+ );
3931
+ CardTitle.displayName = "CardTitle";
3932
+ var CardDescription = React.forwardRef(
3933
+ ({ className, ...props }, ref) => /* @__PURE__ */ jsx(
3934
+ "div",
4054
3935
  {
4055
- className,
4056
- width: size,
4057
- height: size,
4058
- viewBox: "0 0 24 24",
4059
- "aria-label": ariaLabel,
4060
- "aria-hidden": ariaHidden,
4061
- children: [
4062
- /* @__PURE__ */ jsx(
4063
- "path",
4064
- {
4065
- fill: "#4285F4",
4066
- d: "M22.56 12.25c0-.78-.07-1.53-.2-2.25H12v4.26h5.92c-.26 1.37-1.04 2.53-2.21 3.31v2.77h3.57c2.08-1.92 3.28-4.74 3.28-8.09z"
4067
- }
4068
- ),
4069
- /* @__PURE__ */ jsx(
4070
- "path",
4071
- {
4072
- fill: "#34A853",
4073
- d: "M12 23c2.97 0 5.46-.98 7.28-2.66l-3.57-2.77c-.98.66-2.23 1.06-3.71 1.06-2.86 0-5.29-1.93-6.16-4.53H2.18v2.84C3.99 20.53 7.7 23 12 23z"
4074
- }
4075
- ),
4076
- /* @__PURE__ */ jsx(
4077
- "path",
4078
- {
4079
- fill: "#FBBC05",
4080
- d: "M5.84 14.09c-.22-.66-.35-1.36-.35-2.09s.13-1.43.35-2.09V7.07H2.18C1.43 8.55 1 10.22 1 12s.43 3.45 1.18 4.93l2.85-2.22.81-.62z"
4081
- }
4082
- ),
4083
- /* @__PURE__ */ jsx(
4084
- "path",
4085
- {
4086
- fill: "#EA4335",
4087
- d: "M12 5.38c1.62 0 3.06.56 4.21 1.64l3.15-3.15C17.45 2.09 14.97 1 12 1 7.7 1 3.99 3.47 2.18 7.07l3.66 2.84c.87-2.6 3.3-4.53 6.16-4.53z"
4088
- }
4089
- )
4090
- ]
3936
+ ref,
3937
+ "data-slot": "card-description",
3938
+ className: cn("text-sm text-muted-foreground", className),
3939
+ ...props
4091
3940
  }
4092
- );
4093
- };
4094
- var OpenAIIcon = ({
4095
- size = 16,
4096
- className = "",
4097
- "aria-label": ariaLabel = "OpenAI",
4098
- "aria-hidden": ariaHidden = true
4099
- }) => /* @__PURE__ */ jsx(
4100
- "svg",
3941
+ )
3942
+ );
3943
+ CardDescription.displayName = "CardDescription";
3944
+ var CardContent = React.forwardRef(
3945
+ ({ className, ...props }, ref) => /* @__PURE__ */ jsx("div", { ref, "data-slot": "card-content", className: cn("p-6 pt-0", className), ...props })
3946
+ );
3947
+ CardContent.displayName = "CardContent";
3948
+ var CardFooter = React.forwardRef(
3949
+ ({ className, ...props }, ref) => /* @__PURE__ */ jsx(
3950
+ "div",
3951
+ {
3952
+ ref,
3953
+ "data-slot": "card-footer",
3954
+ className: cn("flex items-center p-6 pt-0", className),
3955
+ ...props
3956
+ }
3957
+ )
3958
+ );
3959
+ CardFooter.displayName = "CardFooter";
3960
+ var Label2 = React.forwardRef(({ className, ...props }, ref) => /* @__PURE__ */ jsx(
3961
+ "label",
3962
+ {
3963
+ ref,
3964
+ className: `text-sm font-medium leading-none peer-disabled:cursor-not-allowed peer-disabled:opacity-70 ${className || ""}`,
3965
+ ...props
3966
+ }
3967
+ ));
3968
+ Label2.displayName = "Label";
3969
+ var Separator2 = React.forwardRef(({ className, orientation = "horizontal", decorative = true, ...props }, ref) => /* @__PURE__ */ jsx(
3970
+ SeparatorPrimitive.Root,
3971
+ {
3972
+ ref,
3973
+ decorative,
3974
+ orientation,
3975
+ className: cn(
3976
+ "shrink-0 bg-border",
3977
+ orientation === "horizontal" ? "h-[1px] w-full" : "h-full w-[1px]",
3978
+ className
3979
+ ),
3980
+ ...props
3981
+ }
3982
+ ));
3983
+ Separator2.displayName = SeparatorPrimitive.Root.displayName;
3984
+ var Collapsible = CollapsiblePrimitive.Root;
3985
+ var CollapsibleTrigger2 = CollapsiblePrimitive.CollapsibleTrigger;
3986
+ var CollapsibleContent2 = CollapsiblePrimitive.CollapsibleContent;
3987
+ var Progress = React.forwardRef(({ className, value, ...props }, ref) => /* @__PURE__ */ jsx(
3988
+ ProgressPrimitive.Root,
3989
+ {
3990
+ ref,
3991
+ className: cn("relative h-2 w-full overflow-hidden rounded-full bg-primary/20", className),
3992
+ ...props,
3993
+ children: /* @__PURE__ */ jsx(
3994
+ ProgressPrimitive.Indicator,
3995
+ {
3996
+ className: "h-full w-full flex-1 bg-primary transition-all",
3997
+ style: { transform: `translateX(-${100 - (value || 0)}%)` }
3998
+ }
3999
+ )
4000
+ }
4001
+ ));
4002
+ Progress.displayName = ProgressPrimitive.Root.displayName;
4003
+ var RadioGroup = React.forwardRef(({ className, ...props }, ref) => {
4004
+ return /* @__PURE__ */ jsx(RadioGroupPrimitive.Root, { className: cn("grid gap-2", className), ...props, ref });
4005
+ });
4006
+ RadioGroup.displayName = RadioGroupPrimitive.Root.displayName;
4007
+ var RadioGroupItem = React.forwardRef(({ className, ...props }, ref) => {
4008
+ return /* @__PURE__ */ jsx(
4009
+ RadioGroupPrimitive.Item,
4010
+ {
4011
+ ref,
4012
+ className: cn(
4013
+ "relative aspect-square h-4 w-4 rounded-full border border-primary text-primary after:absolute after:left-1/2 after:top-1/2 after:hidden after:size-11 after:-translate-x-1/2 after:-translate-y-1/2 after:content-[''] pointer-coarse:after:block focus:outline-none focus-visible:ring-1 focus-visible:ring-ring disabled:cursor-not-allowed disabled:opacity-50",
4014
+ className
4015
+ ),
4016
+ ...props,
4017
+ children: /* @__PURE__ */ jsx(RadioGroupPrimitive.Indicator, { className: "flex items-center justify-center", children: /* @__PURE__ */ jsx(Circle, { className: "h-2.5 w-2.5 fill-current text-current" }) })
4018
+ }
4019
+ );
4020
+ });
4021
+ RadioGroupItem.displayName = RadioGroupPrimitive.Item.displayName;
4022
+ var Switch = React.forwardRef(({ className, ...props }, ref) => /* @__PURE__ */ jsx(
4023
+ SwitchPrimitives.Root,
4101
4024
  {
4102
- className,
4103
- width: size,
4104
- height: size,
4105
- viewBox: "0 0 24 24",
4106
- "aria-label": ariaLabel,
4107
- "aria-hidden": ariaHidden,
4025
+ className: cn(
4026
+ "peer relative inline-flex h-5 w-9 shrink-0 cursor-pointer items-center rounded-full border-2 border-transparent shadow-sm transition-colors focus-visible:outline-none focus-visible:ring-1 focus-visible:ring-ring disabled:cursor-not-allowed disabled:opacity-50 data-[state=checked]:bg-primary data-[state=unchecked]:bg-input dark:data-[state=unchecked]:bg-muted-foreground/45 after:absolute after:left-1/2 after:top-1/2 after:hidden after:size-11 after:-translate-x-1/2 after:-translate-y-1/2 after:content-[''] pointer-coarse:after:block",
4027
+ className
4028
+ ),
4029
+ ...props,
4030
+ ref,
4108
4031
  children: /* @__PURE__ */ jsx(
4109
- "path",
4032
+ SwitchPrimitives.Thumb,
4110
4033
  {
4111
- fill: "#10A37F",
4112
- d: "M22.2819 9.8211a5.9847 5.9847 0 0 0-.5157-4.9108 6.0462 6.0462 0 0 0-6.5098-2.9A6.0651 6.0651 0 0 0 4.9807 4.1818a5.9847 5.9847 0 0 0-3.9977 2.9 6.0462 6.0462 0 0 0 .7427 7.0966 5.98 5.98 0 0 0 .511 4.9107 6.051 6.051 0 0 0 6.5146 2.9001A5.9847 5.9847 0 0 0 13.2599 24a6.0557 6.0557 0 0 0 5.7718-4.2058 5.9894 5.9894 0 0 0 3.9977-2.9001 6.0557 6.0557 0 0 0-.7475-7.0729zm-9.022 12.6081a4.4755 4.4755 0 0 1-2.8764-1.0408l.1419-.0804 4.7783-2.7582a.7948.7948 0 0 0 .3927-.6813v-6.7369l2.02 1.1686a.071.071 0 0 1 .038.052v5.5826a4.504 4.504 0 0 1-4.4945 4.4944zm-9.6607-4.1254a4.4708 4.4708 0 0 1-.5346-3.0137l.142.0852 4.783 2.7582a.7712.7712 0 0 0 .7806 0l5.8428-3.3685v2.3324a.0804.0804 0 0 1-.0332.0615L9.74 19.9502a4.4992 4.4992 0 0 1-6.1408-1.6464zM2.3408 7.8956a4.485 4.485 0 0 1 2.3655-1.9728V11.6a.7664.7664 0 0 0 .3879.6765l5.8144 3.3543-2.0201 1.1685a.0757.0757 0 0 1-.071 0l-4.8303-2.7865A4.504 4.504 0 0 1 2.3408 7.872zm16.5963 3.8558L13.1038 8.364 15.1192 7.2a.0757.0757 0 0 1 .071 0l4.8303 2.7913a4.4944 4.4944 0 0 1-.6765 8.1042v-5.6772a.79.79 0 0 0-.407-.667zm2.0107-3.0231l-.142-.0852-4.7735-2.7818a.7759.7759 0 0 0-.7854 0L9.409 9.2297V6.8974a.0662.0662 0 0 1 .0284-.0615l4.8303-2.7866a4.4992 4.4992 0 0 1 6.6802 4.66zM8.3065 12.863l-2.02-1.1638a.0804.0804 0 0 1-.038-.0567V6.0742a4.4992 4.4992 0 0 1 7.3757-3.4537l-.142.0805L8.704 5.459a.7948.7948 0 0 0-.3927.6813zm1.0976-2.3654l2.602-1.4998 2.6069 1.4998v2.9994l-2.5974 1.4997-2.6067-1.4997Z"
4034
+ className: cn(
4035
+ "pointer-events-none block h-4 w-4 rounded-full bg-background shadow-lg ring-0 transition-transform data-[state=checked]:translate-x-4 data-[state=unchecked]:translate-x-0"
4036
+ )
4113
4037
  }
4114
4038
  )
4115
4039
  }
4116
- );
4117
- var ClaudeIcon = ({
4118
- size = 16,
4119
- className = "",
4120
- "aria-label": ariaLabel = "Claude",
4121
- "aria-hidden": ariaHidden = true
4122
- }) => /* @__PURE__ */ jsx(
4123
- "svg",
4040
+ ));
4041
+ Switch.displayName = SwitchPrimitives.Root.displayName;
4042
+ var Tabs = TabsPrimitive.Root;
4043
+ var TabsList = React.forwardRef(({ className, ...props }, ref) => /* @__PURE__ */ jsx(
4044
+ TabsPrimitive.List,
4124
4045
  {
4125
- className,
4126
- width: size,
4127
- height: size,
4128
- viewBox: "0 0 24 24",
4129
- "aria-label": ariaLabel,
4130
- "aria-hidden": ariaHidden,
4131
- children: /* @__PURE__ */ jsx(
4132
- "path",
4133
- {
4134
- fill: "#D97757",
4135
- d: "m4.7144 15.9555 4.7174-2.6471.079-.2307-.079-.1275h-.2307l-.7893-.0486-2.6956-.0729-2.3375-.0971-2.2646-.1214-.5707-.1215-.5343-.7042.0546-.3522.4797-.3218.686.0608 1.5179.1032 2.2767.1578 1.6514.0972 2.4468.255h.3886l.0546-.1579-.1336-.0971-.1032-.0972L6.973 9.8356l-2.55-1.6879-1.3356-.9714-.7225-.4918-.3643-.4614-.1578-1.0078.6557-.7225.8803.0607.2246.0607.8925.686 1.9064 1.4754 2.4893 1.8336.3643.3035.1457-.1032.0182-.0728-.164-.2733-1.3539-2.4467-1.445-2.4893-.6435-1.032-.17-.6194c-.0607-.255-.1032-.4674-.1032-.7285L6.287.1335 6.6997 0l.9957.1336.419.3642.6192 1.4147 1.0018 2.2282 1.5543 3.0296.4553.8985.2429.8318.091.255h.1579v-.1457l.1275-1.706.2368-2.0947.2307-2.6957.0789-.7589.3764-.9107.7468-.4918.5828.2793.4797.686-.0668.4433-.2853 1.8517-.5586 2.9021-.3643 1.9429h.2125l.2429-.2429.9835-1.3053 1.6514-2.0643.7286-.8196.85-.9046.5464-.4311h1.0321l.759 1.1293-.34 1.1657-1.0625 1.3478-.8804 1.1414-1.2628 1.7-.7893 1.36.0729.1093.1882-.0183 2.8535-.607 1.5421-.2794 1.8396-.3157.8318.3886.091.3946-.3278.8075-1.967.4857-2.3072.4614-3.4364.8136-.0425.0304.0486.0607 1.5482.1457.6618.0364h1.621l3.0175.2247.7892.522.4736.6376-.079.4857-1.2142.6193-1.6393-.3886-3.825-.9107-1.3113-.3279h-.1822v.1093l1.0929 1.0686 2.0035 1.8092 2.5075 2.3314.1275.5768-.3218.4554-.34-.0486-2.2039-1.6575-.85-.7468-1.9246-1.621h-.1275v.17l.4432.6496 2.3436 3.5214.1214 1.0807-.17.3521-.6071.2125-.6679-.1214-1.3721-1.9246L14.38 17.959l-1.1414-1.9428-.1397.079-.674 7.2552-.3156.3703-.7286.2793-.6071-.4614-.3218-.7468.3218-1.4753.3886-1.9246.3157-1.53.2853-1.9004.17-.6314-.0121-.0425-.1397.0182-1.4328 1.9672-2.1796 2.9446-1.7243 1.8456-.4128.164-.7164-.3704.0667-.6618.4008-.5889 2.386-3.0357 1.4389-1.882.929-1.0868-.0062-.1579h-.0546l-6.3385 4.1164-1.1293.1457-.4857-.4554.0608-.7467.2307-.2429 1.9064-1.3114Z"
4136
- }
4137
- )
4046
+ ref,
4047
+ className: cn(
4048
+ "inline-flex h-9 pointer-coarse:h-auto items-center justify-center rounded-lg bg-muted p-1 text-muted-foreground",
4049
+ className
4050
+ ),
4051
+ ...props
4138
4052
  }
4139
- );
4140
- var GeminiIcon = ({
4141
- size = 16,
4142
- className = "",
4143
- "aria-label": ariaLabel = "Gemini",
4144
- "aria-hidden": ariaHidden = true
4145
- }) => /* @__PURE__ */ jsxs(
4146
- "svg",
4053
+ ));
4054
+ TabsList.displayName = TabsPrimitive.List.displayName;
4055
+ var TabsTrigger = React.forwardRef(({ className, ...props }, ref) => /* @__PURE__ */ jsx(
4056
+ TabsPrimitive.Trigger,
4147
4057
  {
4148
- className,
4149
- width: size,
4150
- height: size,
4151
- viewBox: "0 0 24 24",
4152
- "aria-label": ariaLabel,
4153
- "aria-hidden": ariaHidden,
4154
- children: [
4155
- /* @__PURE__ */ jsx("defs", { children: /* @__PURE__ */ jsxs("linearGradient", { id: "geminiGradient", x1: "0%", y1: "0%", x2: "100%", y2: "100%", children: [
4156
- /* @__PURE__ */ jsx("stop", { offset: "0%", stopColor: "#1BA1E3" }),
4157
- /* @__PURE__ */ jsx("stop", { offset: "25%", stopColor: "#5489D6" }),
4158
- /* @__PURE__ */ jsx("stop", { offset: "50%", stopColor: "#9B72CB" }),
4159
- /* @__PURE__ */ jsx("stop", { offset: "75%", stopColor: "#D96570" }),
4160
- /* @__PURE__ */ jsx("stop", { offset: "100%", stopColor: "#F49C46" })
4161
- ] }) }),
4162
- /* @__PURE__ */ jsx(
4163
- "path",
4164
- {
4165
- fill: "url(#geminiGradient)",
4166
- d: "M11.04 19.32Q12 21.51 12 24q0-2.49.93-4.68.96-2.19 2.58-3.81t3.81-2.55Q21.51 12 24 12q-2.49 0-4.68-.93a12.3 12.3 0 0 1-3.81-2.58 12.3 12.3 0 0 1-2.58-3.81Q12 2.49 12 0q0 2.49-.96 4.68-.93 2.19-2.55 3.81a12.3 12.3 0 0 1-3.81 2.58Q2.49 12 0 12q2.49 0 4.68.96 2.19.93 3.81 2.55t2.55 3.81"
4167
- }
4168
- )
4169
- ]
4058
+ ref,
4059
+ className: cn(
4060
+ "inline-flex items-center justify-center whitespace-nowrap rounded-md px-3 py-1 text-sm pointer-coarse:min-h-11 font-medium ring-offset-background transition-all focus-visible:outline-none focus-visible:ring-2 focus-visible:ring-ring focus-visible:ring-offset-2 disabled:pointer-events-none disabled:opacity-50 data-[state=active]:bg-background data-[state=active]:text-foreground data-[state=active]:shadow",
4061
+ className
4062
+ ),
4063
+ ...props
4064
+ }
4065
+ ));
4066
+ TabsTrigger.displayName = TabsPrimitive.Trigger.displayName;
4067
+ var TabsContent = React.forwardRef(({ className, ...props }, ref) => /* @__PURE__ */ jsx(
4068
+ TabsPrimitive.Content,
4069
+ {
4070
+ ref,
4071
+ className: cn(
4072
+ "mt-2 ring-offset-background focus-visible:outline-none focus-visible:ring-2 focus-visible:ring-ring focus-visible:ring-offset-2",
4073
+ className
4074
+ ),
4075
+ ...props
4170
4076
  }
4077
+ ));
4078
+ TabsContent.displayName = TabsPrimitive.Content.displayName;
4079
+ var Table = React.forwardRef(
4080
+ ({ className, ...props }, ref) => /* @__PURE__ */ jsx("div", { className: "relative w-full overflow-auto", children: /* @__PURE__ */ jsx("table", { ref, className: cn("w-full caption-bottom text-sm", className), ...props }) })
4171
4081
  );
4172
- var FireworksIcon = ({
4173
- size = 16,
4174
- className = "",
4175
- "aria-label": ariaLabel = "Fireworks AI",
4176
- "aria-hidden": ariaHidden = true
4177
- }) => /* @__PURE__ */ jsxs(
4178
- "svg",
4082
+ Table.displayName = "Table";
4083
+ var TableHeader = React.forwardRef(({ className, ...props }, ref) => /* @__PURE__ */ jsx("thead", { ref, className: cn("[&_tr]:border-b", className), ...props }));
4084
+ TableHeader.displayName = "TableHeader";
4085
+ var TableBody = React.forwardRef(({ className, ...props }, ref) => /* @__PURE__ */ jsx("tbody", { ref, className: cn("[&_tr:last-child]:border-0", className), ...props }));
4086
+ TableBody.displayName = "TableBody";
4087
+ var TableFooter = React.forwardRef(({ className, ...props }, ref) => /* @__PURE__ */ jsx(
4088
+ "tfoot",
4179
4089
  {
4180
- className,
4181
- width: size,
4182
- height: size,
4183
- viewBox: "-2 6 36 20",
4184
- preserveAspectRatio: "xMidYMid meet",
4185
- fill: "none",
4186
- style: { minWidth: size, minHeight: size },
4187
- "aria-label": ariaLabel,
4188
- "aria-hidden": ariaHidden,
4189
- children: [
4190
- /* @__PURE__ */ jsx(
4191
- "path",
4192
- {
4193
- fill: "#6720FF",
4194
- d: "M15.9851 19.1274C15.0969 19.1274 14.2999 18.6001 13.96 17.7838L9.86258 8H12.2608L15.9991 16.9499L19.7339 8H22.1321L18.0102 17.7873C17.6686 18.6001 16.8733 19.1274 15.9851 19.1274Z"
4195
- }
4090
+ ref,
4091
+ className: cn("border-t bg-muted/50 font-medium [&>tr]:last:border-b-0", className),
4092
+ ...props
4093
+ }
4094
+ ));
4095
+ TableFooter.displayName = "TableFooter";
4096
+ var TableRow = React.forwardRef(
4097
+ ({ className, ...props }, ref) => /* @__PURE__ */ jsx(
4098
+ "tr",
4099
+ {
4100
+ ref,
4101
+ className: cn(
4102
+ "border-b transition-colors hover:bg-muted/50 data-[state=selected]:bg-muted",
4103
+ className
4196
4104
  ),
4197
- /* @__PURE__ */ jsx(
4198
- "path",
4199
- {
4200
- fill: "#6720FF",
4201
- d: "M21.3316 23.8029C20.4469 23.8029 19.6533 23.2792 19.31 22.4698C18.9649 21.6535 19.1436 20.7215 19.7672 20.0891L27.2299 12.5302L28.1618 14.7287L21.3298 21.636L31.068 21.5817L32 23.7802L21.3333 23.8065L21.3298 23.8029H21.3316Z"
4202
- }
4105
+ ...props
4106
+ }
4107
+ )
4108
+ );
4109
+ TableRow.displayName = "TableRow";
4110
+ var TableHead = React.forwardRef(
4111
+ ({ className, ...props }, ref) => /* @__PURE__ */ jsx(
4112
+ "th",
4113
+ {
4114
+ ref,
4115
+ className: cn(
4116
+ "h-10 px-2 text-left align-middle font-medium text-muted-foreground [&:has([role=checkbox])]:pr-0 [&>[role=checkbox]]:translate-y-[2px]",
4117
+ className
4203
4118
  ),
4204
- /* @__PURE__ */ jsx(
4205
- "path",
4206
- {
4207
- fill: "#6720FF",
4208
- d: "M0 23.7766L0.931955 21.5781L10.6702 21.6324L3.83993 14.7234L4.77189 12.5249L12.2345 20.0838C12.8582 20.7145 13.0386 21.65 12.6918 22.4645C12.3484 23.2756 11.5513 23.7977 10.6702 23.7977L0.00350359 23.7731L0 23.7766Z"
4209
- }
4210
- )
4211
- ]
4212
- }
4119
+ ...props
4120
+ }
4121
+ )
4213
4122
  );
4214
- function ProviderIcon({
4215
- modelName,
4216
- provider,
4217
- size = 16,
4218
- className = ""
4219
- }) {
4220
- const m = (modelName ?? "").toLowerCase();
4221
- const p = (provider ?? "").toLowerCase();
4222
- if (m.includes("gpt") || p === "openai") {
4223
- return /* @__PURE__ */ jsx(OpenAIIcon, { size, className });
4224
- }
4225
- if (m.includes("claude") || p === "anthropic") {
4226
- return /* @__PURE__ */ jsx(ClaudeIcon, { size, className });
4227
- }
4228
- if (m.includes("gemini") || p.startsWith("vertex_ai")) {
4229
- return /* @__PURE__ */ jsx(GeminiIcon, { size, className });
4123
+ TableHead.displayName = "TableHead";
4124
+ var TableCell = React.forwardRef(
4125
+ ({ className, ...props }, ref) => /* @__PURE__ */ jsx(
4126
+ "td",
4127
+ {
4128
+ ref,
4129
+ className: cn(
4130
+ "p-2 align-middle [&:has([role=checkbox])]:pr-0 [&>[role=checkbox]]:translate-y-[2px]",
4131
+ className
4132
+ ),
4133
+ ...props
4134
+ }
4135
+ )
4136
+ );
4137
+ TableCell.displayName = "TableCell";
4138
+ var TableCaption = React.forwardRef(({ className, ...props }, ref) => /* @__PURE__ */ jsx("caption", { ref, className: cn("mt-4 text-sm text-muted-foreground", className), ...props }));
4139
+ TableCaption.displayName = "TableCaption";
4140
+ var Slider = React.forwardRef(
4141
+ ({ className, rangeClassName, ...props }, ref) => /* @__PURE__ */ jsxs(
4142
+ SliderPrimitive.Root,
4143
+ {
4144
+ ref,
4145
+ className: cn("relative flex w-full touch-none select-none items-center", className),
4146
+ ...props,
4147
+ children: [
4148
+ /* @__PURE__ */ jsx(SliderPrimitive.Track, { className: "relative h-1.5 w-full grow overflow-hidden rounded-full bg-primary/20", children: /* @__PURE__ */ jsx(SliderPrimitive.Range, { className: cn("absolute h-full bg-primary", rangeClassName) }) }),
4149
+ /* @__PURE__ */ jsx(SliderPrimitive.Thumb, { className: "block h-4 w-4 rounded-full border border-primary/50 bg-background shadow transition-colors focus-visible:outline-none focus-visible:ring-1 focus-visible:ring-ring disabled:pointer-events-none disabled:opacity-50" })
4150
+ ]
4151
+ }
4152
+ )
4153
+ );
4154
+ Slider.displayName = SliderPrimitive.Root.displayName;
4155
+ var toggleVariants = cva(
4156
+ "inline-flex items-center justify-center gap-2 rounded-md text-sm font-medium transition-colors hover:bg-muted hover:text-muted-foreground focus-visible:outline-none focus-visible:ring-1 focus-visible:ring-ring disabled:pointer-events-none disabled:opacity-50 data-[state=on]:bg-accent data-[state=on]:text-accent-foreground [&_svg]:pointer-events-none [&_svg]:size-4 [&_svg]:shrink-0",
4157
+ {
4158
+ variants: {
4159
+ variant: {
4160
+ default: "bg-transparent",
4161
+ outline: "border border-input bg-transparent shadow-sm hover:bg-accent hover:text-accent-foreground"
4162
+ },
4163
+ size: {
4164
+ default: "h-9 px-2 min-w-9 pointer-coarse:h-11 pointer-coarse:min-w-11",
4165
+ sm: "h-8 px-1.5 min-w-8 pointer-coarse:h-11 pointer-coarse:min-w-11",
4166
+ lg: "h-10 px-2.5 min-w-10 pointer-coarse:h-11 pointer-coarse:min-w-11"
4167
+ }
4168
+ },
4169
+ defaultVariants: {
4170
+ variant: "default",
4171
+ size: "default"
4172
+ }
4230
4173
  }
4231
- if (p === "google") {
4232
- return /* @__PURE__ */ jsx(GoogleIcon, { size, className });
4174
+ );
4175
+ var Toggle = React.forwardRef(({ className, variant, size, ...props }, ref) => /* @__PURE__ */ jsx(
4176
+ TogglePrimitive.Root,
4177
+ {
4178
+ ref,
4179
+ className: cn(toggleVariants({ variant, size, className })),
4180
+ ...props
4233
4181
  }
4234
- if (p === "fireworks_ai") {
4235
- return /* @__PURE__ */ jsx(FireworksIcon, { size, className });
4182
+ ));
4183
+ Toggle.displayName = TogglePrimitive.Root.displayName;
4184
+ var ToggleGroupContext = React.createContext({
4185
+ size: "default",
4186
+ variant: "default"
4187
+ });
4188
+ var ToggleGroup = React.forwardRef(({ className, variant, size, children, ...props }, ref) => /* @__PURE__ */ jsx(
4189
+ ToggleGroupPrimitive.Root,
4190
+ {
4191
+ ref,
4192
+ className: cn("flex items-center justify-center gap-1", className),
4193
+ ...props,
4194
+ children: /* @__PURE__ */ jsx(ToggleGroupContext.Provider, { value: { variant, size }, children })
4236
4195
  }
4196
+ ));
4197
+ ToggleGroup.displayName = ToggleGroupPrimitive.Root.displayName;
4198
+ var ToggleGroupItem = React.forwardRef(({ className, children, variant, size, ...props }, ref) => {
4199
+ const context = React.useContext(ToggleGroupContext);
4237
4200
  return /* @__PURE__ */ jsx(
4238
- Crown,
4201
+ ToggleGroupPrimitive.Item,
4239
4202
  {
4240
- className,
4241
- style: { width: size, height: size, color: "#EAB308", fill: "#EAB308" }
4203
+ ref,
4204
+ className: cn(
4205
+ toggleVariants({
4206
+ variant: context.variant || variant,
4207
+ size: context.size || size
4208
+ }),
4209
+ className
4210
+ ),
4211
+ ...props,
4212
+ children
4242
4213
  }
4243
4214
  );
4215
+ });
4216
+ ToggleGroupItem.displayName = ToggleGroupPrimitive.Item.displayName;
4217
+ var Popover = PopoverPrimitive.Root;
4218
+ var PopoverTrigger = PopoverPrimitive.Trigger;
4219
+ var PopoverAnchor = PopoverPrimitive.Anchor;
4220
+ function PopoverPortal({
4221
+ container,
4222
+ ...props
4223
+ }) {
4224
+ const fallback = usePortalContainer();
4225
+ return /* @__PURE__ */ jsx(PopoverPrimitive.Portal, { container: container ?? fallback, ...props });
4244
4226
  }
4245
-
4246
- // src/icons/arbi-mark.ts
4247
- var ARBI_MARK_SRC = "data:image/svg+xml,%3Csvg%20xmlns=%22http://www.w3.org/2000/svg%22%20xmlns:xlink=%22http://www.w3.org/1999/xlink%22%20width=%22500%22%20zoomAndPan=%22magnify%22%20viewBox=%220%200%20375%20374.999991%22%20height=%22500%22%20preserveAspectRatio=%22xMidYMid%20meet%22%20version=%221.0%22%3E%3Cdefs%3E%3Cg/%3E%3CclipPath%20id=%22413a615d81%22%3E%3Cpath%20d=%22M%20187.5%200%20C%2083.945312%200%200%2083.945312%200%20187.5%20C%200%20291.054688%2083.945312%20375%20187.5%20375%20C%20291.054688%20375%20375%20291.054688%20375%20187.5%20C%20375%2083.945312%20291.054688%200%20187.5%200%20Z%20M%20187.5%200%20%22%20clip-rule=%22nonzero%22/%3E%3C/clipPath%3E%3CclipPath%20id=%22b4114fb668%22%3E%3Cpath%20d=%22M%200%200%20L%20375%200%20L%20375%20375%20L%200%20375%20Z%20M%200%200%20%22%20clip-rule=%22nonzero%22/%3E%3C/clipPath%3E%3CclipPath%20id=%2202d2f74560%22%3E%3Cpath%20d=%22M%20187.5%200%20C%2083.945312%200%200%2083.945312%200%20187.5%20C%200%20291.054688%2083.945312%20375%20187.5%20375%20C%20291.054688%20375%20375%20291.054688%20375%20187.5%20C%20375%2083.945312%20291.054688%200%20187.5%200%20Z%20M%20187.5%200%20%22%20clip-rule=%22nonzero%22/%3E%3C/clipPath%3E%3CclipPath%20id=%2266f7fee432%22%3E%3Crect%20x=%220%22%20width=%22375%22%20y=%220%22%20height=%22375%22/%3E%3C/clipPath%3E%3CclipPath%20id=%2244a7358375%22%3E%3Cpath%20d=%22M%2066.527344%2066.527344%20L%20308.472656%2066.527344%20L%20308.472656%20308.472656%20L%2066.527344%20308.472656%20Z%20M%2066.527344%2066.527344%20%22%20clip-rule=%22nonzero%22/%3E%3C/clipPath%3E%3CclipPath%20id=%2206d1da3b78%22%3E%3Cpath%20d=%22M%20187.5%2066.527344%20C%20120.6875%2066.527344%2066.527344%20120.6875%2066.527344%20187.5%20C%2066.527344%20254.3125%20120.6875%20308.472656%20187.5%20308.472656%20C%20254.3125%20308.472656%20308.472656%20254.3125%20308.472656%20187.5%20C%20308.472656%20120.6875%20254.3125%2066.527344%20187.5%2066.527344%20Z%20M%20187.5%2066.527344%20%22%20clip-rule=%22nonzero%22/%3E%3C/clipPath%3E%3CclipPath%20id=%225f19be2713%22%3E%3Cpath%20d=%22M%200.527344%200.527344%20L%20242.472656%200.527344%20L%20242.472656%20242.472656%20L%200.527344%20242.472656%20Z%20M%200.527344%200.527344%20%22%20clip-rule=%22nonzero%22/%3E%3C/clipPath%3E%3CclipPath%20id=%22fde3ba0cc4%22%3E%3Cpath%20d=%22M%20121.5%200.527344%20C%2054.6875%200.527344%200.527344%2054.6875%200.527344%20121.5%20C%200.527344%20188.3125%2054.6875%20242.472656%20121.5%20242.472656%20C%20188.3125%20242.472656%20242.472656%20188.3125%20242.472656%20121.5%20C%20242.472656%2054.6875%20188.3125%200.527344%20121.5%200.527344%20Z%20M%20121.5%200.527344%20%22%20clip-rule=%22nonzero%22/%3E%3C/clipPath%3E%3CclipPath%20id=%2267bf874d33%22%3E%3Crect%20x=%220%22%20width=%22243%22%20y=%220%22%20height=%22243%22/%3E%3C/clipPath%3E%3CclipPath%20id=%2205f2bd6677%22%3E%3Cpath%20d=%22M%200%2098.171875%20L%20375%2098.171875%20L%20375%20375%20L%200%20375%20Z%20M%200%2098.171875%20%22%20clip-rule=%22nonzero%22/%3E%3C/clipPath%3E%3CclipPath%20id=%22a5274c9106%22%3E%3Cpath%20d=%22M%20187.5%2098.171875%20L%20404.023438%20508.144531%20L%20-29.023438%20508.144531%20Z%20M%20187.5%2098.171875%20%22%20clip-rule=%22nonzero%22/%3E%3C/clipPath%3E%3CclipPath%20id=%220f4217ffe3%22%3E%3Cpath%20d=%22M%200%200.171875%20L%20375%200.171875%20L%20375%20277%20L%200%20277%20Z%20M%200%200.171875%20%22%20clip-rule=%22nonzero%22/%3E%3C/clipPath%3E%3CclipPath%20id=%22ca1f5799a3%22%3E%3Cpath%20d=%22M%20187.5%200.171875%20L%20404.023438%20410.144531%20L%20-29.023438%20410.144531%20Z%20M%20187.5%200.171875%20%22%20clip-rule=%22nonzero%22/%3E%3C/clipPath%3E%3CclipPath%20id=%228bb016993a%22%3E%3Crect%20x=%220%22%20width=%22375%22%20y=%220%22%20height=%22277%22/%3E%3C/clipPath%3E%3CclipPath%20id=%2276af0040d9%22%3E%3Cpath%20d=%22M%200%20195.949219%20L%20375%20195.949219%20L%20375%20375%20L%200%20375%20Z%20M%200%20195.949219%20%22%20clip-rule=%22nonzero%22/%3E%3C/clipPath%3E%3CclipPath%20id=%221062f89594%22%3E%3Cpath%20d=%22M%200%200.949219%20L%20375%200.949219%20L%20375%20180%20L%200%20180%20Z%20M%200%200.949219%20%22%20clip-rule=%22nonzero%22/%3E%3C/clipPath%3E%3CclipPath%20id=%2217bc809498%22%3E%3Crect%20x=%220%22%20width=%22375%22%20y=%220%22%20height=%22180%22/%3E%3C/clipPath%3E%3CclipPath%20id=%22ad524f887e%22%3E%3Cpath%20d=%22M%202%2094%20L%20293%2094%20L%20293%20342%20L%202%20342%20Z%20M%202%2094%20%22%20clip-rule=%22nonzero%22/%3E%3C/clipPath%3E%3CclipPath%20id=%22ac73806eb1%22%3E%3Crect%20x=%220%22%20width=%22294%22%20y=%220%22%20height=%22342%22/%3E%3C/clipPath%3E%3C/defs%3E%3Crect%20x=%22-37.5%22%20width=%22450%22%20fill=%22%23ffffff%22%20y=%22-37.499999%22%20height=%22449.999989%22%20fill-opacity=%221%22/%3E%3Crect%20x=%22-37.5%22%20width=%22450%22%20fill=%22%23ffffff%22%20y=%22-37.499999%22%20height=%22449.999989%22%20fill-opacity=%221%22/%3E%3Cg%20clip-path=%22url(%23413a615d81)%22%3E%3Cg%20transform=%22matrix(1,%200,%200,%201,%200,%200)%22%3E%3Cg%20clip-path=%22url(%2366f7fee432)%22%3E%3Cg%20clip-path=%22url(%23b4114fb668)%22%3E%3Cg%20clip-path=%22url(%2302d2f74560)%22%3E%3Crect%20x=%22-82.5%22%20width=%22540%22%20fill=%22%2301adef%22%20height=%22539.999987%22%20y=%22-82.499998%22%20fill-opacity=%221%22/%3E%3C/g%3E%3C/g%3E%3C/g%3E%3C/g%3E%3C/g%3E%3Cg%20clip-path=%22url(%2344a7358375)%22%3E%3Cg%20clip-path=%22url(%2306d1da3b78)%22%3E%3Cg%20transform=%22matrix(1,%200,%200,%201,%2066,%2066)%22%3E%3Cg%20clip-path=%22url(%2367bf874d33)%22%3E%3Cg%20clip-path=%22url(%235f19be2713)%22%3E%3Cg%20clip-path=%22url(%23fde3ba0cc4)%22%3E%3Cpath%20fill=%22%23ffffff%22%20d=%22M%200.527344%200.527344%20L%20242.472656%200.527344%20L%20242.472656%20242.472656%20L%200.527344%20242.472656%20Z%20M%200.527344%200.527344%20%22%20fill-opacity=%221%22%20fill-rule=%22nonzero%22/%3E%3C/g%3E%3C/g%3E%3C/g%3E%3C/g%3E%3C/g%3E%3C/g%3E%3Cg%20clip-path=%22url(%2305f2bd6677)%22%3E%3Cg%20clip-path=%22url(%23a5274c9106)%22%3E%3Cg%20transform=%22matrix(1,%200,%200,%201,%200,%2098)%22%3E%3Cg%20clip-path=%22url(%238bb016993a)%22%3E%3Cg%20clip-path=%22url(%230f4217ffe3)%22%3E%3Cg%20clip-path=%22url(%23ca1f5799a3)%22%3E%3Cpath%20fill=%22%23ffffff%22%20d=%22M%20-29.023438%200.171875%20L%20403.371094%200.171875%20L%20403.371094%20410.144531%20L%20-29.023438%20410.144531%20Z%20M%20-29.023438%200.171875%20%22%20fill-opacity=%221%22%20fill-rule=%22nonzero%22/%3E%3C/g%3E%3C/g%3E%3C/g%3E%3C/g%3E%3C/g%3E%3C/g%3E%3Cg%20clip-path=%22url(%2376af0040d9)%22%3E%3Cg%20transform=%22matrix(1,%200,%200,%201,%200,%20195)%22%3E%3Cg%20clip-path=%22url(%2317bc809498)%22%3E%3Cg%20clip-path=%22url(%231062f89594)%22%3E%3Cpath%20fill=%22%23ffffff%22%20d=%22M%20-62.902344%200.949219%20L%20438.316406%200.949219%20L%20438.316406%20313.144531%20L%20-62.902344%20313.144531%20Z%20M%20-62.902344%200.949219%20%22%20fill-opacity=%221%22%20fill-rule=%22nonzero%22/%3E%3C/g%3E%3C/g%3E%3C/g%3E%3C/g%3E%3Cg%20transform=%22matrix(1,%200,%200,%201,%2040,%2033)%22%3E%3Cg%20clip-path=%22url(%23ac73806eb1)%22%3E%3Cg%20clip-path=%22url(%23ad524f887e)%22%3E%3Cg%20fill=%22%23202b61%22%20fill-opacity=%221%22%3E%3Cg%20transform=%22translate(7.369923,%20344.002374)%22%3E%3Cg%3E%3Cpath%20d=%22M%20192.15625%20-48.484375%20L%2086.640625%20-48.484375%20L%2067.03125%200%20L%20-4.984375%200%20L%20105.171875%20-249.5625%20L%20174.6875%20-249.5625%20L%20285.21875%200%20L%20211.765625%200%20Z%20M%20171.484375%20-100.53125%20L%20139.390625%20-180.390625%20L%20107.3125%20-100.53125%20Z%20M%20171.484375%20-100.53125%20%22/%3E%3C/g%3E%3C/g%3E%3C/g%3E%3C/g%3E%3C/g%3E%3C/g%3E%3Cpath%20stroke-linecap=%22butt%22%20transform=%22matrix(0.75,%200,%200,%200.75,%200.0000045,%20209.710181)%22%20fill=%22none%22%20stroke-linejoin=%22miter%22%20d=%22M%20-0.000006%2010.001009%20L%2088.703125%2010.001009%20%22%20stroke=%22%23202b61%22%20stroke-width=%2220%22%20stroke-opacity=%221%22%20stroke-miterlimit=%224%22/%3E%3Cpath%20stroke-linecap=%22butt%22%20transform=%22matrix(0.75,%200,%200,%200.75,%20308.473813,%20209.710181)%22%20fill=%22none%22%20stroke-linejoin=%22miter%22%20d=%22M%20-0.00154239%2010.001009%20L%2088.701588%2010.001009%20%22%20stroke=%22%23202b61%22%20stroke-width=%2220%22%20stroke-opacity=%221%22%20stroke-miterlimit=%224%22/%3E%3C/svg%3E";
4248
- var ArbiIcon = ({
4249
- size = 20,
4250
- className = "",
4251
- "aria-label": ariaLabel = "ARBI Docs",
4252
- "aria-hidden": ariaHidden = false
4253
- }) => {
4254
- return /* @__PURE__ */ jsx(
4255
- "img",
4256
- {
4257
- src: ARBI_MARK_SRC,
4258
- alt: ariaLabel,
4259
- className: `rounded object-contain ${className}`,
4260
- style: { width: size, height: size },
4261
- "aria-label": ariaLabel,
4262
- "aria-hidden": ariaHidden
4227
+ var PopoverContent = React.forwardRef(({ className, align = "center", sideOffset = 4, container, ...props }, ref) => /* @__PURE__ */ jsx(PopoverPortal, { container: container ?? void 0, children: /* @__PURE__ */ jsx(
4228
+ PopoverPrimitive.Content,
4229
+ {
4230
+ ref,
4231
+ align,
4232
+ sideOffset,
4233
+ collisionPadding: getCollisionPadding(),
4234
+ className: cn(
4235
+ "z-50 w-72 max-w-[calc(100vw-1rem)] max-h-[var(--radix-popover-content-available-height)] overflow-y-auto overscroll-contain rounded-md border border-border bg-popover p-4 text-popover-foreground shadow-lg outline-none data-[state=open]:animate-in data-[state=closed]:animate-out data-[state=closed]:fade-out-0 data-[state=open]:fade-in-0 data-[state=closed]:zoom-out-95 data-[state=open]:zoom-in-95 data-[side=bottom]:slide-in-from-top-2 data-[side=left]:slide-in-from-right-2 data-[side=right]:slide-in-from-left-2 data-[side=top]:slide-in-from-bottom-2 origin-[--radix-popover-content-transform-origin]",
4236
+ className
4237
+ ),
4238
+ ...props
4239
+ }
4240
+ ) }));
4241
+ PopoverContent.displayName = PopoverPrimitive.Content.displayName;
4242
+ var PopoverClose = PopoverPrimitive.Close;
4243
+ var FINE_OPEN_DELAY = 350;
4244
+ var FINE_CLOSE_DELAY = 180;
4245
+ var silentFocusMarks = /* @__PURE__ */ new WeakSet();
4246
+ function returnFocusToMark(mark) {
4247
+ silentFocusMarks.add(mark);
4248
+ mark.focus({ preventScroll: true });
4249
+ silentFocusMarks.delete(mark);
4250
+ }
4251
+ function isFocusVisible(el) {
4252
+ try {
4253
+ return el.matches(":focus-visible");
4254
+ } catch {
4255
+ return true;
4256
+ }
4257
+ }
4258
+ function isCoarse(pointerType) {
4259
+ if (pointerType === "touch" || pointerType === "pen") return true;
4260
+ if (pointerType === "mouse") return false;
4261
+ return typeof window !== "undefined" && !!window.matchMedia?.("(pointer: coarse)").matches;
4262
+ }
4263
+ function MarkMenu({
4264
+ as = "span",
4265
+ href,
4266
+ items,
4267
+ preview,
4268
+ menuLabel,
4269
+ shouldClickRunPrimary = true,
4270
+ openDelay = FINE_OPEN_DELAY,
4271
+ closeDelay = FINE_CLOSE_DELAY,
4272
+ testId,
4273
+ menuTestId,
4274
+ triggerRef: externalRef,
4275
+ className,
4276
+ children,
4277
+ onPointerDown,
4278
+ onPointerEnter,
4279
+ onPointerMove,
4280
+ onPointerLeave,
4281
+ onFocus,
4282
+ onBlur,
4283
+ onKeyDown,
4284
+ ...rest
4285
+ }) {
4286
+ const [open, setOpen] = useState(false);
4287
+ const [side, setSide] = useState("bottom");
4288
+ const menuId = useId();
4289
+ const triggerRef = useRef(null);
4290
+ const contentRef = useRef(null);
4291
+ const timer = useRef(null);
4292
+ const mode = useRef("hover");
4293
+ const lastPointer = useRef("mouse");
4294
+ const focusFirstOnOpen = useRef(false);
4295
+ const hoverArmed = useRef(false);
4296
+ const isEmpty = items.length === 0 && !preview;
4297
+ const ordered = [...items].sort((a, b) => Number(!!b.primary) - Number(!!a.primary));
4298
+ const primary = ordered[0];
4299
+ const clearTimer = () => {
4300
+ if (timer.current) clearTimeout(timer.current);
4301
+ timer.current = null;
4302
+ };
4303
+ useEffect(() => clearTimer, []);
4304
+ useEffect(() => {
4305
+ if (!open) return;
4306
+ const onDocumentPointerDown = (e) => {
4307
+ const target = e.target;
4308
+ if (triggerRef.current?.contains(target) || contentRef.current?.contains(target)) return;
4309
+ if (timer.current) clearTimeout(timer.current);
4310
+ setOpen(false);
4311
+ };
4312
+ document.addEventListener("pointerdown", onDocumentPointerDown, true);
4313
+ return () => document.removeEventListener("pointerdown", onDocumentPointerDown, true);
4314
+ }, [open]);
4315
+ const rows = () => Array.from(contentRef.current?.querySelectorAll('[role="menuitem"]') ?? []);
4316
+ const firstItem = () => rows()[0];
4317
+ const openWith = (next, focusFirst = false) => {
4318
+ clearTimer();
4319
+ mode.current = next;
4320
+ focusFirstOnOpen.current = focusFirst;
4321
+ setSide(next === "press" && isCoarse(lastPointer.current) ? "top" : "bottom");
4322
+ setOpen(true);
4323
+ if (focusFirst) {
4324
+ requestAnimationFrame(() => firstItem()?.focus());
4263
4325
  }
4264
- );
4265
- };
4266
- var ArbiBotHeadIcon = ({ size = 24, className = "" }) => {
4267
- const maskId = useId();
4268
- return /* @__PURE__ */ jsxs(
4269
- "svg",
4270
- {
4271
- xmlns: "http://www.w3.org/2000/svg",
4272
- width: size,
4273
- height: size,
4274
- viewBox: "30 -5 190 190",
4275
- preserveAspectRatio: "xMidYMid meet",
4276
- className,
4277
- children: [
4278
- /* @__PURE__ */ jsx("defs", { children: /* @__PURE__ */ jsx("mask", { id: maskId, children: /* @__PURE__ */ jsxs("g", { transform: "translate(0,250) scale(0.1,-0.1)", children: [
4279
- /* @__PURE__ */ jsx("rect", { x: "0", y: "0", width: "2500", height: "2500", fill: "white" }),
4280
- /* @__PURE__ */ jsx("circle", { cx: "855", cy: "1715", r: "190", fill: "black" }),
4281
- /* @__PURE__ */ jsx("circle", { cx: "855", cy: "1715", r: "50", fill: "white" }),
4282
- /* @__PURE__ */ jsx("circle", { cx: "1665", cy: "1700", r: "190", fill: "black" }),
4283
- /* @__PURE__ */ jsx("circle", { cx: "1665", cy: "1700", r: "50", fill: "white" })
4284
- ] }) }) }),
4285
- /* @__PURE__ */ jsxs("g", { mask: `url(#${maskId})`, children: [
4286
- /* @__PURE__ */ jsx(
4287
- "g",
4288
- {
4289
- transform: "translate(0,250) scale(0.1,-0.1)",
4290
- fill: "currentColor",
4291
- stroke: "currentColor",
4292
- strokeWidth: "100",
4293
- children: /* @__PURE__ */ jsx("path", { d: "M1038 2434 c-217 -39 -406 -154 -522 -318 -121 -170 -176 -376 -103 -384 l27 -3 0 -106 c0 -88 -3 -108 -17 -118 -15 -11 -16 -18 -5 -66 44 -188 209 -369 420 -459 l65 -28 -74 -7 c-283 -26 -444 -152 -535 -418 -70 -204 -73 -507 -5 -507 4 0 12 75 19 168 18 263 68 419 167 530 78 87 224 162 263 134 9 -6 43 -26 76 -43 224 -117 802 -95 948 38 38 34 165 -22 253 -111 117 -119 168 -268 187 -549 6 -92 15 -167 19 -167 89 0 53 415 -54 627 -88 173 -238 270 -458 295 l-99 11 75 32 c201 88 367 274 406 454 10 47 9 56 -5 66 -13 10 -16 32 -16 118 l0 106 28 3 c91 10 -12 297 -165 459 -202 214 -544 307 -895 243z m472 -84 c170 -43 323 -140 416 -264 47 -61 117 -197 128 -248 l6 -28 -65 0 c-64 0 -65 1 -78 33 -43 102 -109 136 -262 137 l-110 0 -38 -40 c-25 -27 -46 -40 -65 -41 -134 -5 -394 1 -410 10 -11 6 -30 24 -42 41 l-21 30 -112 0 c-156 -1 -219 -33 -262 -136 -14 -34 -14 -34 -80 -34 -76 0 -74 -7 -30 103 96 243 311 406 595 452 118 20 319 13 430 -15z m-561 -505 c97 -50 126 -174 61 -263 -118 -163 -380 -23 -309 165 35 93 162 143 248 98z m799 -15 c129 -96 69 -304 -92 -318 -189 -16 -265 218 -106 326 48 33 149 29 198 -8z m272 -389 c0 -23 -45 -110 -86 -168 -245 -343 -856 -408 -1231 -130 -90 67 -213 236 -213 294 0 11 132 13 765 13 457 0 765 -4 765 -9z" })
4294
- }
4295
- ),
4296
- /* @__PURE__ */ jsxs("g", { transform: "translate(0,250) scale(0.1,-0.1)", fill: "currentColor", stroke: "none", children: [
4297
- /* @__PURE__ */ jsx("path", { d: "M785 1777 c-60 -60 -59 -134 1 -186 92 -82 236 9 204 128 -25 93 -138 125 -205 58z m161 -29 c7 -22 -19 -52 -40 -45 -21 7 -30 35 -17 51 19 23 48 20 57 -6z" }),
4298
- /* @__PURE__ */ jsx("path", { d: "M1591 1803 c-128 -67 -85 -243 60 -243 83 0 141 99 105 178 -32 69 -103 97 -165 65z m127 -59 c4 -25 -19 -47 -41 -38 -22 8 -30 34 -16 51 17 20 53 12 57 -13z" }),
4299
- /* @__PURE__ */ jsx("path", { d: "M843 1347 c-9 -15 9 -63 41 -108 148 -202 565 -209 730 -12 37 44 60 103 47 116 -13 13 -810 17 -818 4z" })
4300
- ] })
4301
- ] })
4302
- ]
4326
+ };
4327
+ const close = (returnFocus = false) => {
4328
+ clearTimer();
4329
+ setOpen(false);
4330
+ if (returnFocus && triggerRef.current) returnFocusToMark(triggerRef.current);
4331
+ };
4332
+ const schedule = (action, delay) => {
4333
+ clearTimer();
4334
+ timer.current = setTimeout(action, delay);
4335
+ };
4336
+ const handlePointerDown = (e) => {
4337
+ lastPointer.current = e.pointerType;
4338
+ onPointerDown?.(e);
4339
+ };
4340
+ const handlePointerEnter = (e) => {
4341
+ onPointerEnter?.(e);
4342
+ if (isCoarse(e.pointerType) || isEmpty) return;
4343
+ lastPointer.current = e.pointerType;
4344
+ hoverArmed.current = true;
4345
+ };
4346
+ const handlePointerMove = (e) => {
4347
+ onPointerMove?.(e);
4348
+ if (!hoverArmed.current) return;
4349
+ hoverArmed.current = false;
4350
+ if (isCoarse(e.pointerType)) return;
4351
+ schedule(() => openWith("hover"), openDelay);
4352
+ };
4353
+ const handlePointerLeave = (e) => {
4354
+ onPointerLeave?.(e);
4355
+ hoverArmed.current = false;
4356
+ if (isCoarse(e.pointerType)) return;
4357
+ if (!open) return clearTimer();
4358
+ if (mode.current === "hover") schedule(() => close(), closeDelay);
4359
+ };
4360
+ const handleFocus = (e) => {
4361
+ onFocus?.(e);
4362
+ if (isEmpty || silentFocusMarks.has(e.currentTarget)) return;
4363
+ if (isFocusVisible(e.currentTarget)) schedule(() => openWith("focus"), openDelay);
4364
+ };
4365
+ const handleBlur = (e) => {
4366
+ onBlur?.(e);
4367
+ const next = e.relatedTarget;
4368
+ if (next && contentRef.current?.contains(next)) return;
4369
+ if (mode.current === "focus" || mode.current === "key") schedule(() => close(), closeDelay);
4370
+ else clearTimer();
4371
+ };
4372
+ const handleKeyDown = (e) => {
4373
+ onKeyDown?.(e);
4374
+ lastPointer.current = "keyboard";
4375
+ if (e.defaultPrevented || isEmpty) return;
4376
+ if (e.key === "Enter" || e.key === " " || e.key === "ArrowDown") {
4377
+ e.preventDefault();
4378
+ openWith("key", true);
4379
+ } else if (e.key === "Escape" && open) {
4380
+ e.preventDefault();
4381
+ e.stopPropagation();
4382
+ close(true);
4303
4383
  }
4304
- );
4305
- };
4306
- function ThreadVisibilityIcon({
4307
- shared,
4308
- className,
4309
- ...props
4310
- }) {
4311
- const Icon2 = shared ? MessageSquareShare : MessageSquareLock;
4312
- return /* @__PURE__ */ jsx(Icon2, { ...props, className: cn(shared ? "text-secondary" : "text-primary", className) });
4313
- }
4314
-
4315
- // src/entities/tag-kinds.ts
4316
- var KIND_ENTITY = {
4317
- label: "LABEL",
4318
- annotation: "ANNOTATION",
4319
- search: "SAVED_SEARCH",
4320
- issue: "ISSUE",
4321
- person: "PERSON",
4322
- organisation: "ORGANISATION"
4323
- };
4324
- function tagKindTitle(kind, { plural = false } = {}) {
4325
- return getEntityLabel(KIND_ENTITY[kind], plural ? "PLURAL" : "SINGULAR");
4326
- }
4327
- function tagKindNouns(kind) {
4328
- return {
4329
- singular: tagKindTitle(kind).toLowerCase(),
4330
- plural: tagKindTitle(kind, { plural: true }).toLowerCase()
4331
4384
  };
4332
- }
4333
- var VARIANT_STYLES = {
4334
- "mine-paid": {
4335
- pill: "text-primary",
4336
- icon: "text-primary"
4337
- },
4338
- other: {
4339
- pill: "text-secondary",
4340
- icon: "text-secondary"
4341
- },
4342
- "mine-free": {
4343
- pill: "text-muted-foreground",
4344
- icon: "text-muted-foreground"
4345
- },
4346
- common: {
4347
- pill: "",
4348
- icon: "text-muted-foreground"
4349
- }
4350
- };
4351
- function resolveVariant(relation, paid, hasCollaborators) {
4352
- if (relation === "common") return "common";
4353
- if (relation === "other") return "other";
4354
- if (relation === "mine") return paid ? "mine-paid" : "mine-free";
4355
- if (paid) return hasCollaborators ? "other" : "mine-paid";
4356
- return "mine-free";
4357
- }
4358
- function ProjectEntity({
4359
- name,
4360
- label,
4361
- icon,
4362
- subscription = "none",
4363
- hasCollaborators = false,
4364
- size = "sm",
4365
- className,
4366
- onClick,
4367
- relation,
4368
- isPaid,
4369
- tooltipContent
4370
- }) {
4371
- const paid = isPaid ?? (subscription === "active" || subscription === "past_due" || subscription === "dev");
4372
- const variant = resolveVariant(relation, paid, hasCollaborators);
4373
- const { pill, icon: iconClass } = VARIANT_STYLES[variant];
4374
- const iconSizeClass = size === "base" ? "h-4 w-4" : "h-3.5 w-3.5";
4375
- const iconNode = icon ?? /* @__PURE__ */ jsx(CreditCard, { className: cn(iconSizeClass, iconClass) });
4376
- return /* @__PURE__ */ jsx(
4377
- EntityPill,
4378
- {
4379
- icon: iconNode,
4380
- label: label ?? name,
4381
- size,
4382
- shape: "rounded",
4383
- className: cn(pill, className),
4384
- onClick,
4385
- tooltipContent
4385
+ const handleClick = (e) => {
4386
+ if (isEmpty) return;
4387
+ if (e.metaKey || e.ctrlKey || e.shiftKey || e.altKey) return;
4388
+ if (e.detail === 0 && lastPointer.current === "keyboard") {
4389
+ e.preventDefault();
4390
+ return;
4386
4391
  }
4387
- );
4388
- }
4389
- function VerifiedBadge({ className, label = "Identity verified" }) {
4390
- return /* @__PURE__ */ jsx(
4391
- BadgeCheck,
4392
- {
4393
- role: "img",
4394
- "aria-label": label,
4395
- "data-testid": "verified-badge",
4396
- className: cn("h-3.5 w-3.5 shrink-0 text-sky-500", className),
4397
- children: /* @__PURE__ */ jsx("title", { children: label })
4392
+ if (isCoarse(lastPointer.current)) {
4393
+ e.preventDefault();
4394
+ if (open) close();
4395
+ else openWith("press");
4396
+ return;
4397
+ }
4398
+ if (shouldClickRunPrimary && primary?.onSelect) {
4399
+ e.preventDefault();
4400
+ close();
4401
+ primary.onSelect();
4402
+ }
4403
+ };
4404
+ const handleMenuKeyDown = (e) => {
4405
+ const list = rows();
4406
+ const index = list.indexOf(document.activeElement);
4407
+ let target;
4408
+ if (e.key === "ArrowDown") target = list[(index + 1) % list.length];
4409
+ else if (e.key === "ArrowUp") target = list[(index - 1 + list.length) % list.length];
4410
+ else if (e.key === "Home") target = list[0];
4411
+ else if (e.key === "End") target = list[list.length - 1];
4412
+ else if (e.key === "Escape") {
4413
+ e.preventDefault();
4414
+ e.stopPropagation();
4415
+ close(true);
4416
+ return;
4417
+ } else if (e.key === "Tab") {
4418
+ close();
4419
+ return;
4398
4420
  }
4421
+ if (target) {
4422
+ e.preventDefault();
4423
+ target.focus();
4424
+ }
4425
+ };
4426
+ const choose = (item) => {
4427
+ const wasKey = mode.current === "key";
4428
+ close(wasKey);
4429
+ item.onSelect?.();
4430
+ };
4431
+ const setTriggerRef = useCallback(
4432
+ (el) => {
4433
+ triggerRef.current = el;
4434
+ if (typeof externalRef === "function") externalRef(el);
4435
+ else if (externalRef) externalRef.current = el;
4436
+ },
4437
+ [externalRef]
4399
4438
  );
4400
- }
4401
- var sizeClasses = {
4402
- xs: "h-5 w-5",
4403
- sm: "h-6 w-6",
4404
- md: "h-8 w-8",
4405
- lg: "h-10 w-10"
4406
- };
4407
- var textSizeClasses = {
4408
- xs: "text-xs",
4409
- sm: "text-xs",
4410
- md: "text-xs",
4411
- lg: "text-sm"
4412
- };
4413
- var presenceDotClasses = {
4414
- xs: "w-2 h-2 border",
4415
- sm: "w-2.5 h-2.5 border",
4416
- md: "w-3 h-3 border-2",
4417
- lg: "w-3.5 h-3.5 border-2"
4418
- };
4419
- var presencePositionClasses = {
4420
- xs: "-right-1 bottom-0",
4421
- sm: "-right-1 bottom-0",
4422
- md: "-right-1.5 -bottom-0.5",
4423
- lg: "-right-1.5 -bottom-0.5"
4424
- };
4425
- var PRESENCE_LABELS = {
4426
- connected: "Online",
4427
- connecting: "Connecting",
4428
- disconnected: "Offline",
4429
- error: "Connection problem",
4430
- hidden: "Status hidden"
4431
- };
4432
- var presenceColorClasses = {
4433
- connected: "bg-status-online",
4434
- connecting: "bg-status-connecting",
4435
- disconnected: "bg-status-away",
4436
- error: "bg-status-busy",
4437
- hidden: "bg-status-offline"
4438
- };
4439
- var UserEntity = memo(function UserEntity2({
4440
- size = "md",
4441
- variant = "pill",
4442
- className,
4443
- showTooltip = true,
4444
- interactive = true,
4445
- hasUnreadMessages = false,
4446
- initials = "",
4447
- displayName = "",
4448
- picture,
4449
- avatarImageClassName,
4450
- colorClass = "",
4451
- isAgent: isAgent2 = false,
4452
- isVerified = false,
4453
- agentStyle,
4454
- avatarStyle,
4455
- isMe = false,
4456
- displayStatus,
4457
- onClick,
4458
- tooltipContent,
4459
- empty = false
4460
- }) {
4461
- if (empty) {
4462
- return /* @__PURE__ */ jsx(
4463
- Avatar,
4439
+ const triggerProps = {
4440
+ ref: setTriggerRef,
4441
+ className,
4442
+ "data-testid": testId,
4443
+ "data-slot": "mark",
4444
+ "aria-haspopup": "true",
4445
+ "aria-expanded": open,
4446
+ "aria-controls": open ? menuId : void 0,
4447
+ onPointerDown: handlePointerDown,
4448
+ onPointerEnter: handlePointerEnter,
4449
+ onPointerMove: handlePointerMove,
4450
+ onPointerLeave: handlePointerLeave,
4451
+ onFocus: handleFocus,
4452
+ onBlur: handleBlur,
4453
+ onKeyDown: handleKeyDown,
4454
+ onClick: handleClick,
4455
+ ...rest
4456
+ };
4457
+ return /* @__PURE__ */ jsxs(Popover, { open: open && !isEmpty, children: [
4458
+ /* @__PURE__ */ jsx(PopoverAnchor, { asChild: true, children: as === "a" ? /* @__PURE__ */ jsx("a", { href, ...triggerProps, children }) : /* @__PURE__ */ jsx("span", { role: "button", tabIndex: 0, ...triggerProps, children }) }),
4459
+ /* @__PURE__ */ jsxs(
4460
+ PopoverContent,
4464
4461
  {
4465
- className: cn(sizeClasses[size], "border border-border", className),
4466
- "data-testid": "user-entity",
4467
- children: /* @__PURE__ */ jsx(AvatarFallback, { className: "bg-status-empty text-muted-foreground text-xs font-semibold", children: "?" })
4462
+ ref: contentRef,
4463
+ id: menuId,
4464
+ side,
4465
+ align: "start",
4466
+ sideOffset: 6,
4467
+ collisionPadding: 8,
4468
+ role: "group",
4469
+ "data-testid": menuTestId,
4470
+ "data-slot": "mark-menu",
4471
+ className: "w-auto min-w-[12rem] max-w-[min(22rem,calc(100vw-1rem))] p-1",
4472
+ onOpenAutoFocus: (e) => {
4473
+ e.preventDefault();
4474
+ if (focusFirstOnOpen.current) firstItem()?.focus();
4475
+ },
4476
+ onCloseAutoFocus: (e) => e.preventDefault(),
4477
+ onEscapeKeyDown: (e) => {
4478
+ e.preventDefault();
4479
+ close(true);
4480
+ },
4481
+ onInteractOutside: (e) => {
4482
+ if (triggerRef.current?.contains(e.target)) e.preventDefault();
4483
+ },
4484
+ onPointerEnter: clearTimer,
4485
+ onPointerLeave: (e) => {
4486
+ if (!isCoarse(e.pointerType) && mode.current === "hover")
4487
+ schedule(() => close(), closeDelay);
4488
+ },
4489
+ children: [
4490
+ preview && /* @__PURE__ */ jsx("div", { className: "px-2 py-1.5 text-sm", children: preview }),
4491
+ ordered.length > 0 && /* @__PURE__ */ jsx("div", { role: "menu", "aria-label": menuLabel, onKeyDown: handleMenuKeyDown, children: ordered.map((item) => {
4492
+ const rowClass = cn(
4493
+ "flex w-full cursor-pointer items-center rounded-sm px-2 py-1.5 text-left text-sm outline-none transition-colors hover:bg-accent focus-visible:bg-accent pointer-coarse:min-h-11 pointer-coarse:px-3",
4494
+ item.primary && "font-medium pointer-coarse:text-base",
4495
+ item.destructive && "text-destructive"
4496
+ );
4497
+ return item.href && !item.onSelect ? /* @__PURE__ */ jsx(
4498
+ "a",
4499
+ {
4500
+ role: "menuitem",
4501
+ tabIndex: -1,
4502
+ href: item.href,
4503
+ className: rowClass,
4504
+ "data-testid": item.testId,
4505
+ onClick: () => close(),
4506
+ children: item.label
4507
+ },
4508
+ item.id
4509
+ ) : /* @__PURE__ */ jsx(
4510
+ "button",
4511
+ {
4512
+ type: "button",
4513
+ role: "menuitem",
4514
+ tabIndex: -1,
4515
+ className: rowClass,
4516
+ "data-testid": item.testId,
4517
+ onClick: () => choose(item),
4518
+ children: item.label
4519
+ },
4520
+ item.id
4521
+ );
4522
+ }) })
4523
+ ]
4468
4524
  }
4469
- );
4525
+ )
4526
+ ] });
4527
+ }
4528
+ var Command = React.forwardRef(({ className, ...props }, ref) => /* @__PURE__ */ jsx(
4529
+ Command$1,
4530
+ {
4531
+ ref,
4532
+ className: cn(
4533
+ "flex h-full w-full flex-col overflow-hidden rounded-md bg-popover text-popover-foreground",
4534
+ className
4535
+ ),
4536
+ ...props
4470
4537
  }
4471
- const agentBadge = isAgent2 ? /* @__PURE__ */ jsx(ArbiBotHeadIcon, { className: "w-3.5 h-3.5 text-muted-foreground" }) : void 0;
4472
- const canMessage = interactive && !isMe && !isAgent2;
4473
- const showUnread = hasUnreadMessages && !isMe && !isAgent2;
4474
- const surfaceStyle = avatarStyle ?? agentStyle;
4475
- const avatarCore = /* @__PURE__ */ jsxs(
4476
- Avatar,
4477
- {
4478
- className: cn(
4479
- sizeClasses[size],
4480
- isAgent2 ? "rounded-full border-2 border-dashed" : "border border-white"
4481
- ),
4482
- style: surfaceStyle,
4483
- "data-testid": "user-entity",
4484
- children: [
4485
- picture && /* @__PURE__ */ jsx(AvatarImage, { src: picture, alt: initials, className: avatarImageClassName }),
4486
- /* @__PURE__ */ jsx(
4487
- AvatarFallback,
4488
- {
4489
- className: cn(
4490
- textSizeClasses[size],
4491
- "font-semibold leading-none",
4492
- isAgent2 ? "rounded-full bg-transparent" : `text-white ${colorClass}`
4493
- ),
4494
- style: surfaceStyle,
4495
- children: initials
4496
- }
4497
- )
4498
- ]
4499
- }
4500
- );
4501
- const statusDot = showUnread || displayStatus ? /* @__PURE__ */ jsx(
4502
- "span",
4503
- {
4504
- className: cn(
4505
- "absolute rounded-full border-white",
4506
- presenceDotClasses[size],
4507
- presencePositionClasses[size],
4508
- !showUnread && displayStatus ? presenceColorClasses[displayStatus] : ""
4509
- ),
4510
- style: showUnread ? { backgroundColor: "#00adef" } : void 0,
4511
- "data-testid": "user-entity-presence",
4512
- role: "img",
4513
- "aria-label": showUnread ? "Unread messages" : PRESENCE_LABELS[displayStatus],
4514
- title: showUnread ? "Unread messages" : PRESENCE_LABELS[displayStatus]
4515
- }
4516
- ) : null;
4517
- const avatarElement = statusDot ? /* @__PURE__ */ jsxs(
4518
- "div",
4538
+ ));
4539
+ Command.displayName = Command$1.displayName;
4540
+ var CommandDialog = ({ children, ...props }) => {
4541
+ return /* @__PURE__ */ jsx(Dialog, { ...props, children: /* @__PURE__ */ jsx(DialogContent, { className: "overflow-hidden p-0", children: /* @__PURE__ */ jsx(Command, { className: "[&_[cmdk-group-heading]]:px-2 [&_[cmdk-group-heading]]:font-medium [&_[cmdk-group-heading]]:text-muted-foreground [&_[cmdk-group]:not([hidden])_~[cmdk-group]]:pt-0 [&_[cmdk-group]]:px-2 [&_[cmdk-input-wrapper]_svg]:h-5 [&_[cmdk-input-wrapper]_svg]:w-5 [&_[cmdk-input]]:h-12 [&_[cmdk-item]]:px-2 [&_[cmdk-item]]:py-3 [&_[cmdk-item]_svg]:h-5 [&_[cmdk-item]_svg]:w-5", children }) }) });
4542
+ };
4543
+ var CommandInput = React.forwardRef(({ className, ...props }, ref) => /* @__PURE__ */ jsxs("div", { className: "flex items-center border-b px-3", "data-cmdk-input-wrapper": "", children: [
4544
+ /* @__PURE__ */ jsx(Search, { className: "mr-2 h-4 w-4 shrink-0 opacity-50" }),
4545
+ /* @__PURE__ */ jsx(
4546
+ Command$1.Input,
4519
4547
  {
4548
+ ref,
4520
4549
  className: cn(
4521
- "relative inline-block",
4522
- sizeClasses[size],
4523
- variant === "pill" ? "" : className
4524
- ),
4525
- children: [
4526
- avatarCore,
4527
- statusDot
4528
- ]
4529
- }
4530
- ) : /* @__PURE__ */ jsx("div", { className: cn("inline-block", variant === "pill" ? "" : className), children: avatarCore });
4531
- const pillAvatar = (
4532
- // shrink-0: when the pill is squeezed the NAME truncates away — the avatar
4533
- // must never collapse under it and overflow onto neighbouring text.
4534
- /* @__PURE__ */ jsxs("span", { className: cn("relative inline-block shrink-0", sizeClasses[size]), children: [
4535
- /* @__PURE__ */ jsx("span", { className: cn("block transition-opacity", canMessage && "group-hover/pill:opacity-0"), children: avatarCore }),
4536
- canMessage && /* @__PURE__ */ jsx(
4537
- "span",
4538
- {
4539
- "aria-hidden": true,
4540
- className: "absolute inset-0 flex items-center justify-center rounded-full bg-muted text-foreground opacity-0 transition-opacity group-hover/pill:opacity-100",
4541
- children: /* @__PURE__ */ jsx(MessageCircleMore, { className: size === "xs" ? "h-3 w-3" : "h-4 w-4" })
4542
- }
4550
+ "flex h-10 pointer-coarse:h-11 w-full rounded-md bg-transparent py-3 text-sm outline-none placeholder:text-muted-foreground disabled:cursor-not-allowed disabled:opacity-50",
4551
+ className
4543
4552
  ),
4544
- statusDot
4545
- ] })
4546
- );
4547
- const resolvedTooltip = showTooltip ? tooltipContent : void 0;
4548
- if (variant === "pill") {
4549
- const row = /* @__PURE__ */ jsxs(Fragment, { children: [
4550
- pillAvatar,
4551
- displayName && /* @__PURE__ */ jsx("span", { className: "min-w-0 max-w-[320px] truncate text-sm leading-tight", children: displayName }),
4552
- isVerified && !isAgent2 && /* @__PURE__ */ jsx(VerifiedBadge, {}),
4553
- agentBadge
4554
- ] });
4555
- const rowClass = "group/pill inline-flex min-w-0 items-center gap-2";
4556
- const clickable = interactive && !!onClick;
4557
- const clickableClass = "relative cursor-pointer rounded-md px-1 py-0.5 -mx-1 transition-colors hover:bg-muted/60 pointer-coarse:after:absolute pointer-coarse:after:inset-x-0 pointer-coarse:after:-inset-y-3 pointer-coarse:after:content-['']";
4558
- if (resolvedTooltip) {
4559
- return /* @__PURE__ */ jsxs(Tooltip, { children: [
4560
- /* @__PURE__ */ jsx(
4561
- TooltipTrigger,
4562
- {
4563
- type: "button",
4564
- onClick: clickable ? onClick : void 0,
4565
- onFocusCapture: (e) => e.stopPropagation(),
4566
- className: cn(rowClass, clickable && clickableClass, className),
4567
- "data-testid": "user-entity-pill",
4568
- children: row
4569
- }
4570
- ),
4571
- /* @__PURE__ */ jsx(TooltipContent, { className: "p-2", children: resolvedTooltip })
4572
- ] });
4573
- }
4574
- if (clickable) {
4575
- return /* @__PURE__ */ jsx(
4576
- "button",
4577
- {
4578
- type: "button",
4579
- onClick,
4580
- className: cn(rowClass, clickableClass, className),
4581
- "data-testid": "user-entity-pill",
4582
- children: row
4583
- }
4584
- );
4553
+ ...props
4585
4554
  }
4586
- return /* @__PURE__ */ jsx("span", { className: cn(rowClass, className), "data-testid": "user-entity-pill", children: row });
4555
+ )
4556
+ ] }));
4557
+ CommandInput.displayName = Command$1.Input.displayName;
4558
+ var CommandList = React.forwardRef(({ className, ...props }, ref) => /* @__PURE__ */ jsx(
4559
+ Command$1.List,
4560
+ {
4561
+ ref,
4562
+ className: cn("max-h-[min(300px,50dvh)] overflow-y-auto overflow-x-hidden", className),
4563
+ ...props
4587
4564
  }
4588
- if (showTooltip) {
4589
- return /* @__PURE__ */ jsxs(Tooltip, { children: [
4590
- /* @__PURE__ */ jsx(
4591
- TooltipTrigger,
4592
- {
4593
- onFocusCapture: (e) => e.stopPropagation(),
4594
- className: "touch-hit inline-flex",
4595
- children: avatarElement
4596
- }
4597
- ),
4598
- /* @__PURE__ */ jsx(TooltipContent, { className: "p-2", children: tooltipContent })
4599
- ] });
4565
+ ));
4566
+ CommandList.displayName = Command$1.List.displayName;
4567
+ var CommandEmpty = React.forwardRef((props, ref) => /* @__PURE__ */ jsx(Command$1.Empty, { ref, className: "py-6 text-center text-sm", ...props }));
4568
+ CommandEmpty.displayName = Command$1.Empty.displayName;
4569
+ var CommandGroup = React.forwardRef(({ className, ...props }, ref) => /* @__PURE__ */ jsx(
4570
+ Command$1.Group,
4571
+ {
4572
+ ref,
4573
+ className: cn(
4574
+ "overflow-hidden p-1 text-foreground [&_[cmdk-group-heading]]:px-2 [&_[cmdk-group-heading]]:py-1.5 [&_[cmdk-group-heading]]:text-sm [&_[cmdk-group-heading]]:font-medium [&_[cmdk-group-heading]]:text-muted-foreground",
4575
+ className
4576
+ ),
4577
+ ...props
4600
4578
  }
4601
- return avatarElement;
4602
- });
4603
- function AgentBadge({ className }) {
4604
- return /* @__PURE__ */ jsxs(
4605
- "span",
4606
- {
4607
- "data-testid": "agent-badge",
4608
- className: cn(
4609
- "inline-flex shrink-0 items-center gap-1 rounded-full border border-ai-accent/50",
4610
- "bg-ai-accent-soft px-2 py-0.5 text-xs font-bold uppercase tracking-wider text-ai-accent",
4611
- className
4612
- ),
4613
- children: [
4614
- /* @__PURE__ */ jsx(ArbiBotHeadIcon, { size: 14, className: "text-ai-accent" }),
4615
- "Agent"
4616
- ]
4579
+ ));
4580
+ CommandGroup.displayName = Command$1.Group.displayName;
4581
+ var CommandSeparator = React.forwardRef(({ className, ...props }, ref) => /* @__PURE__ */ jsx(
4582
+ Command$1.Separator,
4583
+ {
4584
+ ref,
4585
+ className: cn("-mx-1 h-px bg-border", className),
4586
+ ...props
4587
+ }
4588
+ ));
4589
+ CommandSeparator.displayName = Command$1.Separator.displayName;
4590
+ var CommandItem = React.forwardRef(({ className, ...props }, ref) => /* @__PURE__ */ jsx(
4591
+ Command$1.Item,
4592
+ {
4593
+ ref,
4594
+ className: cn(
4595
+ "relative flex cursor-default gap-2 select-none items-center rounded-sm px-2 py-1.5 pointer-coarse:min-h-11 text-sm outline-none data-[disabled=true]:pointer-events-none data-[selected=true]:bg-accent data-[selected=true]:text-accent-foreground data-[disabled=true]:opacity-50 [&_svg]:pointer-events-none [&_svg]:size-4 [&_svg]:shrink-0",
4596
+ className
4597
+ ),
4598
+ ...props
4599
+ }
4600
+ ));
4601
+ CommandItem.displayName = Command$1.Item.displayName;
4602
+ var CommandShortcut = ({ className, ...props }) => {
4603
+ return /* @__PURE__ */ jsx(
4604
+ "span",
4605
+ {
4606
+ className: cn("ml-auto text-sm tracking-widest text-muted-foreground", className),
4607
+ ...props
4617
4608
  }
4618
4609
  );
4619
- }
4620
- var PRESENCE_WORDS = {
4621
- connected: "Online",
4622
- connecting: "Connecting",
4623
- disconnected: "Offline",
4624
- error: "Connection problem",
4625
- hidden: null
4626
4610
  };
4627
- function PresenceLabel({
4628
- status,
4629
- className
4611
+ CommandShortcut.displayName = "CommandShortcut";
4612
+ var AI_COMPONENTS = {
4613
+ a: (p) => /* @__PURE__ */ jsx(
4614
+ "a",
4615
+ {
4616
+ className: "text-ai-accent underline underline-offset-2",
4617
+ target: "_blank",
4618
+ rel: "noopener noreferrer",
4619
+ ...p
4620
+ }
4621
+ ),
4622
+ // Redline marks: deletions in red strike, <ins>/<mark> additions accented.
4623
+ del: (p) => /* @__PURE__ */ jsx("del", { className: "rounded bg-destructive/10 text-destructive decoration-destructive/60", ...p }),
4624
+ ins: (p) => /* @__PURE__ */ jsx("ins", { className: "rounded bg-ai-accent-soft px-0.5 text-ai-accent no-underline", ...p }),
4625
+ mark: (p) => /* @__PURE__ */ jsx("mark", { className: "rounded bg-ai-accent-soft px-0.5 text-ai-accent", ...p }),
4626
+ thead: (p) => /* @__PURE__ */ jsx("thead", { className: "bg-secondary/60", ...p })
4627
+ };
4628
+ function AiMarkdown({
4629
+ children,
4630
+ className,
4631
+ isStreaming,
4632
+ allowHtml
4630
4633
  }) {
4631
- if (!status) return null;
4632
- const word = PRESENCE_WORDS[status];
4633
- if (!word) return null;
4634
- const online = status === "connected";
4635
- return /* @__PURE__ */ jsxs(
4636
- "span",
4634
+ return /* @__PURE__ */ jsx(
4635
+ MarkdownRenderer,
4637
4636
  {
4638
- "data-testid": "presence-label",
4639
- className: cn("inline-flex shrink-0 items-center gap-1 text-xs", className),
4640
- children: [
4641
- /* @__PURE__ */ jsx(
4642
- "span",
4643
- {
4644
- className: cn(
4645
- "size-1.5 rounded-full",
4646
- online ? "bg-status-online" : "bg-muted-foreground/50"
4647
- ),
4648
- "aria-hidden": "true"
4649
- }
4650
- ),
4651
- /* @__PURE__ */ jsx("span", { className: online ? "font-medium text-status-online" : "text-muted-foreground", children: word })
4652
- ]
4637
+ className: className ?? "text-sm",
4638
+ components: AI_COMPONENTS,
4639
+ isStreaming,
4640
+ allowHtml,
4641
+ testId: "ai-markdown",
4642
+ children
4653
4643
  }
4654
4644
  );
4655
4645
  }
4656
- var PACKAGE_BADGE_VARIANTS = [
4657
- "default",
4658
- "accent",
4659
- "secondary",
4660
- "destructive",
4661
- "outline"
4646
+ var TIERS = [
4647
+ { min: 0.7, tone: "bg-emerald-500", label: "High relevance" },
4648
+ { min: 0.4, tone: "bg-amber-500", label: "Medium relevance" },
4649
+ { min: -Infinity, tone: "bg-muted-foreground/40", label: "Low relevance" }
4662
4650
  ];
4663
- function isPackageBadgeVariant(v) {
4664
- return PACKAGE_BADGE_VARIANTS.some((known) => known === v);
4665
- }
4666
- function PackageStatusBadge({ variant, ...rest }) {
4667
- return /* @__PURE__ */ jsx(Badge, { variant: isPackageBadgeVariant(variant) ? variant : "outline", ...rest });
4668
- }
4669
- var registry = {
4670
- variants: {},
4671
- fallback: "outline",
4672
- Badge: PackageStatusBadge
4673
- };
4674
- function configureStatusRegistry(map, opts) {
4675
- Object.assign(registry.variants, map);
4676
- if (opts?.fallback) registry.fallback = opts.fallback;
4677
- if (opts?.Badge) registry.Badge = opts.Badge;
4678
- }
4679
- function getStatusVariant(status) {
4680
- return registry.variants[status] ?? registry.fallback;
4681
- }
4682
- function StatusPill({ status, label, variant, className, testId }) {
4683
- const Badge2 = registry.Badge;
4684
- return /* @__PURE__ */ jsx(Badge2, { variant: variant ?? getStatusVariant(status), className, "data-testid": testId, children: label ?? status });
4685
- }
4686
- var RAG_LABELS = { red: "At risk", amber: "Attention", green: "On track" };
4687
- function configureRagLabels(labels) {
4688
- RAG_LABELS = { ...RAG_LABELS, ...labels };
4651
+ function RelevanceDot({ score }) {
4652
+ if (score == null) return null;
4653
+ const tier = TIERS.find((t) => score >= t.min) ?? TIERS[TIERS.length - 1];
4654
+ return /* @__PURE__ */ jsx(
4655
+ "span",
4656
+ {
4657
+ role: "img",
4658
+ "aria-label": tier.label,
4659
+ title: `${tier.label} (${score.toFixed(2)})`,
4660
+ className: cn("size-1.5 shrink-0 rounded-full", tier.tone),
4661
+ "data-testid": "passage-relevance"
4662
+ }
4663
+ );
4689
4664
  }
4690
- function RagDot({
4691
- rag,
4692
- withLabel,
4693
- className
4665
+ function PassageCard({
4666
+ header,
4667
+ score,
4668
+ headerRight,
4669
+ active,
4670
+ onClick,
4671
+ footer,
4672
+ className,
4673
+ children,
4674
+ "data-testid": testId
4694
4675
  }) {
4695
- const color = rag === "red" ? "bg-destructive" : rag === "amber" ? "bg-warning" : "bg-success";
4696
- return /* @__PURE__ */ jsxs("span", { className: cn("inline-flex items-center gap-1.5", className), "data-testid": `rag-${rag}`, children: [
4697
- /* @__PURE__ */ jsx("span", { className: cn("size-2 rounded-full", color) }),
4698
- withLabel && /* @__PURE__ */ jsx("span", { className: "text-xs text-muted-foreground", children: RAG_LABELS[rag] })
4676
+ const body = /* @__PURE__ */ jsxs(Fragment, { children: [
4677
+ /* @__PURE__ */ jsxs("div", { className: "mb-1.5 flex items-center gap-2", children: [
4678
+ header,
4679
+ (score != null || headerRight) && /* @__PURE__ */ jsxs("div", { className: "ml-auto flex shrink-0 items-center gap-2", children: [
4680
+ /* @__PURE__ */ jsx(RelevanceDot, { score }),
4681
+ headerRight
4682
+ ] })
4683
+ ] }),
4684
+ /* @__PURE__ */ jsx("div", { className: "[&_mark]:rounded-sm [&_mark]:bg-ai-accent/20 [&_mark]:px-0.5 [&_mark]:font-medium [&_mark]:text-foreground", children })
4699
4685
  ] });
4700
- }
4701
-
4702
- // src/entities/colors.ts
4703
- var OPACITY_LIGHT = 0.15;
4704
- var OPACITY_MEDIUM = 1;
4705
- var OPACITY_BORDER = 0.3;
4706
- var PLACEHOLDER_COLOR = "#9ca3af";
4707
- var NEUTRAL_GRAY2 = "#64748b";
4708
- var BASE_COLORS2 = {
4709
- "0": "#10b981",
4710
- "1": "#3b82f6",
4711
- "2": "#8b5cf6",
4712
- "3": "#f43f5e",
4713
- "4": "#f59e0b",
4714
- "5": "#84cc16",
4715
- "6": "#a855f7",
4716
- "7": "#06b6d4",
4717
- "8": "#f97316",
4718
- "9": "#14b8a6",
4719
- a: "#ef4444",
4720
- b: "#6366f1",
4721
- c: "#ec4899",
4722
- d: "#22c55e",
4723
- e: "#eab308",
4724
- f: "#0ea5e9"
4725
- };
4726
- function hexToRgba(hex, opacity) {
4727
- const r = parseInt(hex.slice(1, 3), 16);
4728
- const g = parseInt(hex.slice(3, 5), 16);
4729
- const b = parseInt(hex.slice(5, 7), 16);
4730
- return `rgba(${r}, ${g}, ${b}, ${opacity})`;
4731
- }
4732
- function getEntityColor2(entityId, variant = "medium") {
4733
- const baseColor = BASE_COLORS2[entityId[4]] || BASE_COLORS2["0"];
4734
- switch (variant) {
4735
- case "light":
4736
- return hexToRgba(baseColor, OPACITY_LIGHT);
4737
- case "medium":
4738
- return hexToRgba(baseColor, OPACITY_MEDIUM);
4739
- case "text":
4740
- return baseColor;
4741
- }
4742
- }
4743
- function getEntityColorStyles(entityId) {
4744
- const baseColor = BASE_COLORS2[entityId[4]] || BASE_COLORS2["0"];
4745
- return {
4746
- backgroundColor: getEntityColor2(entityId, "light"),
4747
- color: baseColor,
4748
- borderColor: hexToRgba(baseColor, OPACITY_BORDER)
4749
- };
4750
- }
4751
- var getWorkspaceColor = (workspaceId, useWorkspaceColors) => {
4752
- const shouldUseWorkspaceColors = useWorkspaceColors !== void 0 ? useWorkspaceColors : true;
4753
- if (!shouldUseWorkspaceColors) return "hsl(var(--primary))";
4754
- const isValidId = workspaceId && workspaceId.startsWith("wrk-") && workspaceId.length >= 5;
4755
- if (!isValidId) return "hsl(var(--primary))";
4756
- return getEntityColor2(workspaceId, "medium");
4757
- };
4758
- var ShieldIcon = ({
4759
- char,
4760
- size = 24,
4761
- className = "",
4762
- workspaceColor,
4763
- isSelected = false,
4764
- ...props
4765
- }) => {
4766
- const fillColor = workspaceColor && workspaceColor !== "hsl(var(--primary))" ? workspaceColor : "transparent";
4767
- const strokeColor = isSelected ? "white" : workspaceColor && workspaceColor !== "hsl(var(--primary))" ? workspaceColor : "currentColor";
4768
4686
  return /* @__PURE__ */ jsxs(
4769
- "svg",
4687
+ "div",
4770
4688
  {
4771
- width: size,
4772
- height: size,
4773
- viewBox: "0 0 24 24",
4774
- fill: fillColor,
4775
- stroke: strokeColor,
4776
- strokeWidth: "2",
4777
- strokeLinecap: "round",
4778
- strokeLinejoin: "round",
4779
- className: `lucide lucide-square ${className}`,
4780
- ...props,
4689
+ className: cn(
4690
+ "group rounded-lg border border-border bg-card p-3 text-left transition-colors",
4691
+ onClick && "hover:border-ai-accent/40 focus-within:ring-2 focus-within:ring-ai-accent/40",
4692
+ active && "border-ai-accent/60 ring-1 ring-ai-accent/30",
4693
+ className
4694
+ ),
4781
4695
  children: [
4782
- /* @__PURE__ */ jsx("rect", { width: "18", height: "18", x: "3", y: "3", rx: "2" }),
4783
- char && /* @__PURE__ */ jsx(
4784
- "text",
4696
+ onClick ? /* @__PURE__ */ jsx(
4697
+ "div",
4785
4698
  {
4786
- x: "12",
4787
- y: "12.5",
4788
- textAnchor: "middle",
4789
- fontSize: "9",
4790
- fontFamily: "sans-serif",
4791
- fontWeight: "300",
4792
- dominantBaseline: "middle",
4793
- stroke: workspaceColor ? "white" : "currentColor",
4794
- strokeWidth: "0.8",
4795
- children: char.toUpperCase()
4699
+ role: "button",
4700
+ tabIndex: 0,
4701
+ onClick,
4702
+ onKeyDown: (e) => {
4703
+ if (e.key === "Enter" || e.key === " ") {
4704
+ e.preventDefault();
4705
+ onClick(e);
4706
+ }
4707
+ },
4708
+ "aria-current": active || void 0,
4709
+ "data-testid": testId,
4710
+ className: "cursor-pointer focus:outline-none",
4711
+ children: body
4796
4712
  }
4797
- )
4713
+ ) : /* @__PURE__ */ jsx("div", { "aria-current": active || void 0, "data-testid": testId, children: body }),
4714
+ footer
4798
4715
  ]
4799
4716
  }
4800
4717
  );
4801
- };
4802
-
4803
- // src/entities/agent-avatar-colors.ts
4804
- var BG_TO_COLOR = {
4805
- "bg-emerald-700": "#047857",
4806
- "bg-blue-700": "#1d4ed8",
4807
- "bg-purple-700": "#7e22ce",
4808
- "bg-amber-700": "#b45309",
4809
- "bg-rose-700": "#be123c",
4810
- "bg-red-700": "#b91c1c",
4811
- "bg-indigo-700": "#4338ca",
4812
- "bg-teal-700": "#0f766e",
4813
- "bg-cyan-700": "#0e7490",
4814
- "bg-sky-700": "#0369a1",
4815
- "bg-lime-700": "#4d7c0f",
4816
- "bg-orange-700": "#c2410c",
4817
- "bg-pink-700": "#be185d",
4818
- "bg-violet-700": "#6d28d9",
4819
- "bg-fuchsia-700": "#a21caf",
4820
- "bg-yellow-700": "#a16207"
4821
- };
4822
- function agentAvatarColors(bgColorClass) {
4823
- const color = BG_TO_COLOR[bgColorClass] || "#047857";
4824
- return { borderColor: color, color };
4825
- }
4826
-
4827
- // src/entities/media-type.ts
4828
- function getDottedExtension(fileName) {
4829
- if (!fileName) return "";
4830
- return fileName.substring(fileName.lastIndexOf(".")).toLowerCase();
4831
4718
  }
4832
- var DOWNLOAD_ONLY_EXTENSIONS = /* @__PURE__ */ new Set([
4833
- ".zip",
4834
- ".rar",
4835
- ".7z",
4836
- ".tar",
4837
- ".gz",
4838
- ".exe",
4839
- ".bin",
4840
- ".dmg",
4841
- ".iso",
4842
- ".apk",
4843
- ".msi",
4844
- ".dll",
4845
- ".so",
4846
- ".psd",
4847
- ".ai",
4848
- ".sketch"
4849
- ]);
4850
- var IMAGE_EXTENSIONS4 = /* @__PURE__ */ new Set([
4851
- ".jpg",
4852
- ".jpeg",
4853
- ".png",
4854
- ".gif",
4855
- ".bmp",
4856
- ".tiff",
4857
- ".tif",
4858
- ".webp"
4719
+ var TextIcon = FileText;
4720
+ var IMAGE_EXTENSIONS4 = /* @__PURE__ */ new Set(["jpg", "jpeg", "png", "gif", "bmp", "tiff", "tif", "webp", "svg"]);
4721
+ var VIDEO_EXTENSIONS4 = /* @__PURE__ */ new Set(["mp4", "mpeg", "mpg", "webm", "mov", "avi", "mkv"]);
4722
+ var AUDIO_EXTENSIONS4 = /* @__PURE__ */ new Set(["mp3", "wav", "m4a", "aac", "ogg", "flac"]);
4723
+ var DOCX_EXTENSIONS2 = /* @__PURE__ */ new Set(["doc", "docx", "odt", "rtf"]);
4724
+ var XLSX_EXTENSIONS2 = /* @__PURE__ */ new Set(["xls", "xlsx", "csv", "ods"]);
4725
+ var EMAIL_EXTENSIONS3 = /* @__PURE__ */ new Set(["eml", "msg"]);
4726
+ var HTML_EXTENSIONS2 = /* @__PURE__ */ new Set(["html", "htm", "mhtml"]);
4727
+ var PDF_EXTENSIONS = /* @__PURE__ */ new Set(["pdf"]);
4728
+ var TEXT_EXTENSIONS2 = /* @__PURE__ */ new Set([
4729
+ "txt",
4730
+ "text",
4731
+ "md",
4732
+ "markdown",
4733
+ "log",
4734
+ "json",
4735
+ "xml",
4736
+ "yaml",
4737
+ "yml"
4859
4738
  ]);
4860
- var VIDEO_EXTENSIONS4 = /* @__PURE__ */ new Set([".mp4", ".mpeg", ".mpg", ".webm", ".mov", ".avi", ".mkv"]);
4861
- var AUDIO_EXTENSIONS4 = /* @__PURE__ */ new Set([".mp3", ".wav", ".m4a", ".aac", ".ogg", ".flac"]);
4862
- function isImageFile(fileName) {
4863
- return IMAGE_EXTENSIONS4.has(getDottedExtension(fileName));
4864
- }
4865
- function isVideoFile(fileName) {
4866
- return VIDEO_EXTENSIONS4.has(getDottedExtension(fileName));
4867
- }
4868
- function isAudioFile(fileName) {
4869
- return AUDIO_EXTENSIONS4.has(getDottedExtension(fileName));
4870
- }
4871
- function isMediaFile(fileName) {
4872
- return isImageFile(fileName) || isVideoFile(fileName) || isAudioFile(fileName);
4873
- }
4874
- function usesOriginalBytesForViewer(fileName) {
4875
- return isMediaFile(fileName);
4876
- }
4877
- function isDownloadOnlyFile(fileName) {
4878
- return DOWNLOAD_ONLY_EXTENSIONS.has(getDottedExtension(fileName));
4739
+ function getFileExtension(fileName) {
4740
+ if (!fileName) return "";
4741
+ const dot = fileName.lastIndexOf(".");
4742
+ if (dot <= 0 || dot === fileName.length - 1) return "";
4743
+ return fileName.slice(dot + 1).toLowerCase();
4879
4744
  }
4880
-
4881
- // src/entities/file-type.ts
4882
- var EXT_LABELS = {
4883
- pdf: "PDF",
4884
- // Word / docs
4885
- doc: "Word",
4886
- docx: "Word",
4887
- rtf: "Word",
4888
- odt: "Word",
4889
- // Spreadsheets
4890
- xls: "Excel",
4891
- xlsx: "Excel",
4892
- ods: "Excel",
4893
- csv: "CSV",
4894
- tsv: "CSV",
4895
- // Slides
4896
- ppt: "PowerPoint",
4897
- pptx: "PowerPoint",
4898
- odp: "PowerPoint",
4899
- // Plain text / markup
4900
- txt: "Text",
4901
- log: "Text",
4902
- md: "Markdown",
4903
- markdown: "Markdown",
4904
- html: "HTML",
4905
- htm: "HTML",
4906
- xml: "XML",
4907
- json: "JSON",
4908
- yaml: "YAML",
4909
- yml: "YAML",
4910
- // Email
4911
- eml: "Email",
4912
- msg: "Email",
4913
- mbox: "Email",
4914
- pst: "Outlook",
4915
- ost: "Outlook",
4916
- // Images
4917
- jpg: "Image",
4918
- jpeg: "Image",
4919
- png: "Image",
4920
- gif: "Image",
4921
- bmp: "Image",
4922
- tif: "Image",
4923
- tiff: "Image",
4924
- webp: "Image",
4925
- svg: "Image",
4926
- heic: "Image",
4927
- heif: "Image",
4928
- // Audio
4929
- mp3: "Audio",
4930
- wav: "Audio",
4931
- m4a: "Audio",
4932
- aac: "Audio",
4933
- ogg: "Audio",
4934
- flac: "Audio",
4935
- opus: "Audio",
4936
- // Video
4937
- mp4: "Video",
4938
- webm: "Video",
4939
- mov: "Video",
4940
- avi: "Video",
4941
- mkv: "Video",
4942
- // Archives
4943
- zip: "Archive",
4944
- tar: "Archive",
4945
- gz: "Archive",
4946
- rar: "Archive",
4947
- "7z": "Archive"
4948
- };
4949
- var MIME_SUBTYPE_LABELS = {
4950
- // PDF
4951
- pdf: "PDF",
4952
- "x-pdf": "PDF",
4953
- // Word
4954
- msword: "Word",
4955
- "vnd.openxmlformats-officedocument.wordprocessingml.document": "Word",
4956
- "vnd.oasis.opendocument.text": "Word",
4957
- rtf: "Word",
4958
- // Excel
4959
- "vnd.ms-excel": "Excel",
4960
- "vnd.openxmlformats-officedocument.spreadsheetml.sheet": "Excel",
4961
- "vnd.oasis.opendocument.spreadsheet": "Excel",
4962
- csv: "CSV",
4963
- "tab-separated-values": "CSV",
4964
- // PowerPoint
4965
- "vnd.ms-powerpoint": "PowerPoint",
4966
- "vnd.openxmlformats-officedocument.presentationml.presentation": "PowerPoint",
4967
- "vnd.oasis.opendocument.presentation": "PowerPoint",
4968
- // Plain text / markup
4969
- plain: "Text",
4970
- html: "HTML",
4971
- xml: "XML",
4972
- json: "JSON",
4973
- markdown: "Markdown",
4974
- "x-markdown": "Markdown",
4975
- yaml: "YAML",
4976
- "x-yaml": "YAML",
4977
- // Email
4978
- rfc822: "Email",
4979
- "vnd.ms-outlook": "Email",
4980
- // Archives
4981
- zip: "Archive",
4982
- "x-zip-compressed": "Archive",
4983
- "x-tar": "Archive",
4984
- gzip: "Archive",
4985
- "x-7z-compressed": "Archive",
4986
- "x-rar-compressed": "Archive"
4987
- };
4988
- var MIME_TYPE_LABELS = {
4989
- image: "Image",
4990
- audio: "Audio",
4991
- video: "Video",
4992
- text: "Text"
4745
+ var MIME_TO_EXTENSION = {
4746
+ "application/pdf": "pdf",
4747
+ "text/plain": "txt",
4748
+ "text/markdown": "md",
4749
+ "text/html": "html",
4750
+ "text/csv": "csv",
4751
+ "application/json": "json",
4752
+ "application/xml": "xml",
4753
+ "application/msword": "doc",
4754
+ "application/vnd.openxmlformats-officedocument.wordprocessingml.document": "docx",
4755
+ "application/rtf": "rtf",
4756
+ "application/vnd.oasis.opendocument.text": "odt",
4757
+ "application/vnd.ms-excel": "xls",
4758
+ "application/vnd.openxmlformats-officedocument.spreadsheetml.sheet": "xlsx",
4759
+ "application/vnd.oasis.opendocument.spreadsheet": "ods",
4760
+ "image/png": "png",
4761
+ "image/jpeg": "jpg",
4762
+ "image/gif": "gif",
4763
+ "image/webp": "webp",
4764
+ "image/svg+xml": "svg",
4765
+ "image/tiff": "tiff",
4766
+ "image/bmp": "bmp",
4767
+ "video/mp4": "mp4",
4768
+ "video/webm": "webm",
4769
+ "video/quicktime": "mov",
4770
+ "audio/mpeg": "mp3",
4771
+ "audio/wav": "wav",
4772
+ "audio/ogg": "ogg",
4773
+ "message/rfc822": "eml"
4993
4774
  };
4994
- function lookupExt(ext) {
4995
- return EXT_LABELS[ext.toLowerCase().replace(/^\./, "")];
4775
+ function extensionFromMime(mime) {
4776
+ if (!mime) return "";
4777
+ return MIME_TO_EXTENSION[mime.toLowerCase()] ?? "";
4996
4778
  }
4997
- function lookupMime(mime) {
4998
- const base = mime.toLowerCase().split(";")[0].trim();
4999
- const slash = base.indexOf("/");
5000
- if (slash <= 0) return void 0;
5001
- const top = base.slice(0, slash);
5002
- const sub = base.slice(slash + 1);
5003
- return MIME_SUBTYPE_LABELS[sub] ?? MIME_TYPE_LABELS[top];
4779
+ function iconFromExtension(ext) {
4780
+ if (VIDEO_EXTENSIONS4.has(ext)) return VidIcon;
4781
+ if (AUDIO_EXTENSIONS4.has(ext)) return AudIcon;
4782
+ if (IMAGE_EXTENSIONS4.has(ext)) return ImgIcon;
4783
+ if (DOCX_EXTENSIONS2.has(ext)) return DocIcon;
4784
+ if (XLSX_EXTENSIONS2.has(ext)) return XlsIcon;
4785
+ if (EMAIL_EXTENSIONS3.has(ext)) return EmlIcon;
4786
+ if (HTML_EXTENSIONS2.has(ext)) return HtmlIcon;
4787
+ if (PDF_EXTENSIONS.has(ext)) return PdfIcon;
4788
+ if (TEXT_EXTENSIONS2.has(ext)) return TextIcon;
4789
+ return null;
5004
4790
  }
5005
- function extFromFileName(fileName) {
5006
- if (!fileName) return void 0;
5007
- const dot = fileName.lastIndexOf(".");
5008
- if (dot <= 0 || dot === fileName.length - 1) return void 0;
5009
- return fileName.slice(dot + 1);
4791
+ function iconFromMime(mime) {
4792
+ const m = mime.toLowerCase();
4793
+ if (m.startsWith("image/")) return ImgIcon;
4794
+ if (m.startsWith("video/")) return VidIcon;
4795
+ if (m.startsWith("audio/")) return AudIcon;
4796
+ if (m === "application/pdf") return PdfIcon;
4797
+ if (m === "text/html") return HtmlIcon;
4798
+ if (m === "message/rfc822" || m.includes("outlook")) return EmlIcon;
4799
+ if (m.includes("word") || m === "application/rtf" || m.includes("opendocument.text"))
4800
+ return DocIcon;
4801
+ if (m.includes("sheet") || m.includes("excel") || m === "text/csv" || m.includes("opendocument.spreadsheet"))
4802
+ return XlsIcon;
4803
+ if (m.startsWith("text/") || m === "application/json" || m === "application/xml") return TextIcon;
4804
+ return null;
5010
4805
  }
5011
- function friendlyFileType(fileType, fileName) {
5012
- if (fileType) {
5013
- const trimmed = fileType.trim();
5014
- if (trimmed.includes("/")) {
5015
- const fromMime = lookupMime(trimmed);
5016
- if (fromMime) return fromMime;
5017
- } else {
5018
- const fromExt = lookupExt(trimmed);
5019
- if (fromExt) return fromExt;
4806
+ function getFileTypeIcon(fileName, opts) {
4807
+ return iconFromExtension(getFileExtension(fileName)) ?? (opts?.mime ? iconFromMime(opts.mime) : null) ?? (opts?.defaultToPdf ? PdfIcon : TextIcon);
4808
+ }
4809
+ var GoogleIcon = ({
4810
+ size = 20,
4811
+ className = "",
4812
+ "aria-label": ariaLabel,
4813
+ "aria-hidden": ariaHidden = true
4814
+ }) => {
4815
+ return /* @__PURE__ */ jsxs(
4816
+ "svg",
4817
+ {
4818
+ className,
4819
+ width: size,
4820
+ height: size,
4821
+ viewBox: "0 0 24 24",
4822
+ "aria-label": ariaLabel,
4823
+ "aria-hidden": ariaHidden,
4824
+ children: [
4825
+ /* @__PURE__ */ jsx(
4826
+ "path",
4827
+ {
4828
+ fill: "#4285F4",
4829
+ d: "M22.56 12.25c0-.78-.07-1.53-.2-2.25H12v4.26h5.92c-.26 1.37-1.04 2.53-2.21 3.31v2.77h3.57c2.08-1.92 3.28-4.74 3.28-8.09z"
4830
+ }
4831
+ ),
4832
+ /* @__PURE__ */ jsx(
4833
+ "path",
4834
+ {
4835
+ fill: "#34A853",
4836
+ d: "M12 23c2.97 0 5.46-.98 7.28-2.66l-3.57-2.77c-.98.66-2.23 1.06-3.71 1.06-2.86 0-5.29-1.93-6.16-4.53H2.18v2.84C3.99 20.53 7.7 23 12 23z"
4837
+ }
4838
+ ),
4839
+ /* @__PURE__ */ jsx(
4840
+ "path",
4841
+ {
4842
+ fill: "#FBBC05",
4843
+ d: "M5.84 14.09c-.22-.66-.35-1.36-.35-2.09s.13-1.43.35-2.09V7.07H2.18C1.43 8.55 1 10.22 1 12s.43 3.45 1.18 4.93l2.85-2.22.81-.62z"
4844
+ }
4845
+ ),
4846
+ /* @__PURE__ */ jsx(
4847
+ "path",
4848
+ {
4849
+ fill: "#EA4335",
4850
+ d: "M12 5.38c1.62 0 3.06.56 4.21 1.64l3.15-3.15C17.45 2.09 14.97 1 12 1 7.7 1 3.99 3.47 2.18 7.07l3.66 2.84c.87-2.6 3.3-4.53 6.16-4.53z"
4851
+ }
4852
+ )
4853
+ ]
5020
4854
  }
4855
+ );
4856
+ };
4857
+ var OpenAIIcon = ({
4858
+ size = 16,
4859
+ className = "",
4860
+ "aria-label": ariaLabel = "OpenAI",
4861
+ "aria-hidden": ariaHidden = true
4862
+ }) => /* @__PURE__ */ jsx(
4863
+ "svg",
4864
+ {
4865
+ className,
4866
+ width: size,
4867
+ height: size,
4868
+ viewBox: "0 0 24 24",
4869
+ "aria-label": ariaLabel,
4870
+ "aria-hidden": ariaHidden,
4871
+ children: /* @__PURE__ */ jsx(
4872
+ "path",
4873
+ {
4874
+ fill: "#10A37F",
4875
+ d: "M22.2819 9.8211a5.9847 5.9847 0 0 0-.5157-4.9108 6.0462 6.0462 0 0 0-6.5098-2.9A6.0651 6.0651 0 0 0 4.9807 4.1818a5.9847 5.9847 0 0 0-3.9977 2.9 6.0462 6.0462 0 0 0 .7427 7.0966 5.98 5.98 0 0 0 .511 4.9107 6.051 6.051 0 0 0 6.5146 2.9001A5.9847 5.9847 0 0 0 13.2599 24a6.0557 6.0557 0 0 0 5.7718-4.2058 5.9894 5.9894 0 0 0 3.9977-2.9001 6.0557 6.0557 0 0 0-.7475-7.0729zm-9.022 12.6081a4.4755 4.4755 0 0 1-2.8764-1.0408l.1419-.0804 4.7783-2.7582a.7948.7948 0 0 0 .3927-.6813v-6.7369l2.02 1.1686a.071.071 0 0 1 .038.052v5.5826a4.504 4.504 0 0 1-4.4945 4.4944zm-9.6607-4.1254a4.4708 4.4708 0 0 1-.5346-3.0137l.142.0852 4.783 2.7582a.7712.7712 0 0 0 .7806 0l5.8428-3.3685v2.3324a.0804.0804 0 0 1-.0332.0615L9.74 19.9502a4.4992 4.4992 0 0 1-6.1408-1.6464zM2.3408 7.8956a4.485 4.485 0 0 1 2.3655-1.9728V11.6a.7664.7664 0 0 0 .3879.6765l5.8144 3.3543-2.0201 1.1685a.0757.0757 0 0 1-.071 0l-4.8303-2.7865A4.504 4.504 0 0 1 2.3408 7.872zm16.5963 3.8558L13.1038 8.364 15.1192 7.2a.0757.0757 0 0 1 .071 0l4.8303 2.7913a4.4944 4.4944 0 0 1-.6765 8.1042v-5.6772a.79.79 0 0 0-.407-.667zm2.0107-3.0231l-.142-.0852-4.7735-2.7818a.7759.7759 0 0 0-.7854 0L9.409 9.2297V6.8974a.0662.0662 0 0 1 .0284-.0615l4.8303-2.7866a4.4992 4.4992 0 0 1 6.6802 4.66zM8.3065 12.863l-2.02-1.1638a.0804.0804 0 0 1-.038-.0567V6.0742a4.4992 4.4992 0 0 1 7.3757-3.4537l-.142.0805L8.704 5.459a.7948.7948 0 0 0-.3927.6813zm1.0976-2.3654l2.602-1.4998 2.6069 1.4998v2.9994l-2.5974 1.4997-2.6067-1.4997Z"
4876
+ }
4877
+ )
5021
4878
  }
5022
- const fnExt = extFromFileName(fileName);
5023
- if (fnExt) {
5024
- const fromExt = lookupExt(fnExt);
5025
- if (fromExt) return fromExt;
4879
+ );
4880
+ var ClaudeIcon = ({
4881
+ size = 16,
4882
+ className = "",
4883
+ "aria-label": ariaLabel = "Claude",
4884
+ "aria-hidden": ariaHidden = true
4885
+ }) => /* @__PURE__ */ jsx(
4886
+ "svg",
4887
+ {
4888
+ className,
4889
+ width: size,
4890
+ height: size,
4891
+ viewBox: "0 0 24 24",
4892
+ "aria-label": ariaLabel,
4893
+ "aria-hidden": ariaHidden,
4894
+ children: /* @__PURE__ */ jsx(
4895
+ "path",
4896
+ {
4897
+ fill: "#D97757",
4898
+ d: "m4.7144 15.9555 4.7174-2.6471.079-.2307-.079-.1275h-.2307l-.7893-.0486-2.6956-.0729-2.3375-.0971-2.2646-.1214-.5707-.1215-.5343-.7042.0546-.3522.4797-.3218.686.0608 1.5179.1032 2.2767.1578 1.6514.0972 2.4468.255h.3886l.0546-.1579-.1336-.0971-.1032-.0972L6.973 9.8356l-2.55-1.6879-1.3356-.9714-.7225-.4918-.3643-.4614-.1578-1.0078.6557-.7225.8803.0607.2246.0607.8925.686 1.9064 1.4754 2.4893 1.8336.3643.3035.1457-.1032.0182-.0728-.164-.2733-1.3539-2.4467-1.445-2.4893-.6435-1.032-.17-.6194c-.0607-.255-.1032-.4674-.1032-.7285L6.287.1335 6.6997 0l.9957.1336.419.3642.6192 1.4147 1.0018 2.2282 1.5543 3.0296.4553.8985.2429.8318.091.255h.1579v-.1457l.1275-1.706.2368-2.0947.2307-2.6957.0789-.7589.3764-.9107.7468-.4918.5828.2793.4797.686-.0668.4433-.2853 1.8517-.5586 2.9021-.3643 1.9429h.2125l.2429-.2429.9835-1.3053 1.6514-2.0643.7286-.8196.85-.9046.5464-.4311h1.0321l.759 1.1293-.34 1.1657-1.0625 1.3478-.8804 1.1414-1.2628 1.7-.7893 1.36.0729.1093.1882-.0183 2.8535-.607 1.5421-.2794 1.8396-.3157.8318.3886.091.3946-.3278.8075-1.967.4857-2.3072.4614-3.4364.8136-.0425.0304.0486.0607 1.5482.1457.6618.0364h1.621l3.0175.2247.7892.522.4736.6376-.079.4857-1.2142.6193-1.6393-.3886-3.825-.9107-1.3113-.3279h-.1822v.1093l1.0929 1.0686 2.0035 1.8092 2.5075 2.3314.1275.5768-.3218.4554-.34-.0486-2.2039-1.6575-.85-.7468-1.9246-1.621h-.1275v.17l.4432.6496 2.3436 3.5214.1214 1.0807-.17.3521-.6071.2125-.6679-.1214-1.3721-1.9246L14.38 17.959l-1.1414-1.9428-.1397.079-.674 7.2552-.3156.3703-.7286.2793-.6071-.4614-.3218-.7468.3218-1.4753.3886-1.9246.3157-1.53.2853-1.9004.17-.6314-.0121-.0425-.1397.0182-1.4328 1.9672-2.1796 2.9446-1.7243 1.8456-.4128.164-.7164-.3704.0667-.6618.4008-.5889 2.386-3.0357 1.4389-1.882.929-1.0868-.0062-.1579h-.0546l-6.3385 4.1164-1.1293.1457-.4857-.4554.0608-.7467.2307-.2429 1.9064-1.3114Z"
4899
+ }
4900
+ )
5026
4901
  }
5027
- return "Other";
4902
+ );
4903
+ var GeminiIcon = ({
4904
+ size = 16,
4905
+ className = "",
4906
+ "aria-label": ariaLabel = "Gemini",
4907
+ "aria-hidden": ariaHidden = true
4908
+ }) => /* @__PURE__ */ jsxs(
4909
+ "svg",
4910
+ {
4911
+ className,
4912
+ width: size,
4913
+ height: size,
4914
+ viewBox: "0 0 24 24",
4915
+ "aria-label": ariaLabel,
4916
+ "aria-hidden": ariaHidden,
4917
+ children: [
4918
+ /* @__PURE__ */ jsx("defs", { children: /* @__PURE__ */ jsxs("linearGradient", { id: "geminiGradient", x1: "0%", y1: "0%", x2: "100%", y2: "100%", children: [
4919
+ /* @__PURE__ */ jsx("stop", { offset: "0%", stopColor: "#1BA1E3" }),
4920
+ /* @__PURE__ */ jsx("stop", { offset: "25%", stopColor: "#5489D6" }),
4921
+ /* @__PURE__ */ jsx("stop", { offset: "50%", stopColor: "#9B72CB" }),
4922
+ /* @__PURE__ */ jsx("stop", { offset: "75%", stopColor: "#D96570" }),
4923
+ /* @__PURE__ */ jsx("stop", { offset: "100%", stopColor: "#F49C46" })
4924
+ ] }) }),
4925
+ /* @__PURE__ */ jsx(
4926
+ "path",
4927
+ {
4928
+ fill: "url(#geminiGradient)",
4929
+ d: "M11.04 19.32Q12 21.51 12 24q0-2.49.93-4.68.96-2.19 2.58-3.81t3.81-2.55Q21.51 12 24 12q-2.49 0-4.68-.93a12.3 12.3 0 0 1-3.81-2.58 12.3 12.3 0 0 1-2.58-3.81Q12 2.49 12 0q0 2.49-.96 4.68-.93 2.19-2.55 3.81a12.3 12.3 0 0 1-3.81 2.58Q2.49 12 0 12q2.49 0 4.68.96 2.19.93 3.81 2.55t2.55 3.81"
4930
+ }
4931
+ )
4932
+ ]
4933
+ }
4934
+ );
4935
+ var FireworksIcon = ({
4936
+ size = 16,
4937
+ className = "",
4938
+ "aria-label": ariaLabel = "Fireworks AI",
4939
+ "aria-hidden": ariaHidden = true
4940
+ }) => /* @__PURE__ */ jsxs(
4941
+ "svg",
4942
+ {
4943
+ className,
4944
+ width: size,
4945
+ height: size,
4946
+ viewBox: "-2 6 36 20",
4947
+ preserveAspectRatio: "xMidYMid meet",
4948
+ fill: "none",
4949
+ style: { minWidth: size, minHeight: size },
4950
+ "aria-label": ariaLabel,
4951
+ "aria-hidden": ariaHidden,
4952
+ children: [
4953
+ /* @__PURE__ */ jsx(
4954
+ "path",
4955
+ {
4956
+ fill: "#6720FF",
4957
+ d: "M15.9851 19.1274C15.0969 19.1274 14.2999 18.6001 13.96 17.7838L9.86258 8H12.2608L15.9991 16.9499L19.7339 8H22.1321L18.0102 17.7873C17.6686 18.6001 16.8733 19.1274 15.9851 19.1274Z"
4958
+ }
4959
+ ),
4960
+ /* @__PURE__ */ jsx(
4961
+ "path",
4962
+ {
4963
+ fill: "#6720FF",
4964
+ d: "M21.3316 23.8029C20.4469 23.8029 19.6533 23.2792 19.31 22.4698C18.9649 21.6535 19.1436 20.7215 19.7672 20.0891L27.2299 12.5302L28.1618 14.7287L21.3298 21.636L31.068 21.5817L32 23.7802L21.3333 23.8065L21.3298 23.8029H21.3316Z"
4965
+ }
4966
+ ),
4967
+ /* @__PURE__ */ jsx(
4968
+ "path",
4969
+ {
4970
+ fill: "#6720FF",
4971
+ d: "M0 23.7766L0.931955 21.5781L10.6702 21.6324L3.83993 14.7234L4.77189 12.5249L12.2345 20.0838C12.8582 20.7145 13.0386 21.65 12.6918 22.4645C12.3484 23.2756 11.5513 23.7977 10.6702 23.7977L0.00350359 23.7731L0 23.7766Z"
4972
+ }
4973
+ )
4974
+ ]
4975
+ }
4976
+ );
4977
+ function ProviderIcon({
4978
+ modelName,
4979
+ provider,
4980
+ size = 16,
4981
+ className = ""
4982
+ }) {
4983
+ const m = (modelName ?? "").toLowerCase();
4984
+ const p = (provider ?? "").toLowerCase();
4985
+ if (m.includes("gpt") || p === "openai") {
4986
+ return /* @__PURE__ */ jsx(OpenAIIcon, { size, className });
4987
+ }
4988
+ if (m.includes("claude") || p === "anthropic") {
4989
+ return /* @__PURE__ */ jsx(ClaudeIcon, { size, className });
4990
+ }
4991
+ if (m.includes("gemini") || p.startsWith("vertex_ai")) {
4992
+ return /* @__PURE__ */ jsx(GeminiIcon, { size, className });
4993
+ }
4994
+ if (p === "google") {
4995
+ return /* @__PURE__ */ jsx(GoogleIcon, { size, className });
4996
+ }
4997
+ if (p === "fireworks_ai") {
4998
+ return /* @__PURE__ */ jsx(FireworksIcon, { size, className });
4999
+ }
5000
+ return /* @__PURE__ */ jsx(
5001
+ Crown,
5002
+ {
5003
+ className,
5004
+ style: { width: size, height: size, color: "#EAB308", fill: "#EAB308" }
5005
+ }
5006
+ );
5028
5007
  }
5008
+
5009
+ // src/icons/arbi-mark.ts
5010
+ var ARBI_MARK_SRC = "data:image/svg+xml,%3Csvg%20xmlns=%22http://www.w3.org/2000/svg%22%20xmlns:xlink=%22http://www.w3.org/1999/xlink%22%20width=%22500%22%20zoomAndPan=%22magnify%22%20viewBox=%220%200%20375%20374.999991%22%20height=%22500%22%20preserveAspectRatio=%22xMidYMid%20meet%22%20version=%221.0%22%3E%3Cdefs%3E%3Cg/%3E%3CclipPath%20id=%22413a615d81%22%3E%3Cpath%20d=%22M%20187.5%200%20C%2083.945312%200%200%2083.945312%200%20187.5%20C%200%20291.054688%2083.945312%20375%20187.5%20375%20C%20291.054688%20375%20375%20291.054688%20375%20187.5%20C%20375%2083.945312%20291.054688%200%20187.5%200%20Z%20M%20187.5%200%20%22%20clip-rule=%22nonzero%22/%3E%3C/clipPath%3E%3CclipPath%20id=%22b4114fb668%22%3E%3Cpath%20d=%22M%200%200%20L%20375%200%20L%20375%20375%20L%200%20375%20Z%20M%200%200%20%22%20clip-rule=%22nonzero%22/%3E%3C/clipPath%3E%3CclipPath%20id=%2202d2f74560%22%3E%3Cpath%20d=%22M%20187.5%200%20C%2083.945312%200%200%2083.945312%200%20187.5%20C%200%20291.054688%2083.945312%20375%20187.5%20375%20C%20291.054688%20375%20375%20291.054688%20375%20187.5%20C%20375%2083.945312%20291.054688%200%20187.5%200%20Z%20M%20187.5%200%20%22%20clip-rule=%22nonzero%22/%3E%3C/clipPath%3E%3CclipPath%20id=%2266f7fee432%22%3E%3Crect%20x=%220%22%20width=%22375%22%20y=%220%22%20height=%22375%22/%3E%3C/clipPath%3E%3CclipPath%20id=%2244a7358375%22%3E%3Cpath%20d=%22M%2066.527344%2066.527344%20L%20308.472656%2066.527344%20L%20308.472656%20308.472656%20L%2066.527344%20308.472656%20Z%20M%2066.527344%2066.527344%20%22%20clip-rule=%22nonzero%22/%3E%3C/clipPath%3E%3CclipPath%20id=%2206d1da3b78%22%3E%3Cpath%20d=%22M%20187.5%2066.527344%20C%20120.6875%2066.527344%2066.527344%20120.6875%2066.527344%20187.5%20C%2066.527344%20254.3125%20120.6875%20308.472656%20187.5%20308.472656%20C%20254.3125%20308.472656%20308.472656%20254.3125%20308.472656%20187.5%20C%20308.472656%20120.6875%20254.3125%2066.527344%20187.5%2066.527344%20Z%20M%20187.5%2066.527344%20%22%20clip-rule=%22nonzero%22/%3E%3C/clipPath%3E%3CclipPath%20id=%225f19be2713%22%3E%3Cpath%20d=%22M%200.527344%200.527344%20L%20242.472656%200.527344%20L%20242.472656%20242.472656%20L%200.527344%20242.472656%20Z%20M%200.527344%200.527344%20%22%20clip-rule=%22nonzero%22/%3E%3C/clipPath%3E%3CclipPath%20id=%22fde3ba0cc4%22%3E%3Cpath%20d=%22M%20121.5%200.527344%20C%2054.6875%200.527344%200.527344%2054.6875%200.527344%20121.5%20C%200.527344%20188.3125%2054.6875%20242.472656%20121.5%20242.472656%20C%20188.3125%20242.472656%20242.472656%20188.3125%20242.472656%20121.5%20C%20242.472656%2054.6875%20188.3125%200.527344%20121.5%200.527344%20Z%20M%20121.5%200.527344%20%22%20clip-rule=%22nonzero%22/%3E%3C/clipPath%3E%3CclipPath%20id=%2267bf874d33%22%3E%3Crect%20x=%220%22%20width=%22243%22%20y=%220%22%20height=%22243%22/%3E%3C/clipPath%3E%3CclipPath%20id=%2205f2bd6677%22%3E%3Cpath%20d=%22M%200%2098.171875%20L%20375%2098.171875%20L%20375%20375%20L%200%20375%20Z%20M%200%2098.171875%20%22%20clip-rule=%22nonzero%22/%3E%3C/clipPath%3E%3CclipPath%20id=%22a5274c9106%22%3E%3Cpath%20d=%22M%20187.5%2098.171875%20L%20404.023438%20508.144531%20L%20-29.023438%20508.144531%20Z%20M%20187.5%2098.171875%20%22%20clip-rule=%22nonzero%22/%3E%3C/clipPath%3E%3CclipPath%20id=%220f4217ffe3%22%3E%3Cpath%20d=%22M%200%200.171875%20L%20375%200.171875%20L%20375%20277%20L%200%20277%20Z%20M%200%200.171875%20%22%20clip-rule=%22nonzero%22/%3E%3C/clipPath%3E%3CclipPath%20id=%22ca1f5799a3%22%3E%3Cpath%20d=%22M%20187.5%200.171875%20L%20404.023438%20410.144531%20L%20-29.023438%20410.144531%20Z%20M%20187.5%200.171875%20%22%20clip-rule=%22nonzero%22/%3E%3C/clipPath%3E%3CclipPath%20id=%228bb016993a%22%3E%3Crect%20x=%220%22%20width=%22375%22%20y=%220%22%20height=%22277%22/%3E%3C/clipPath%3E%3CclipPath%20id=%2276af0040d9%22%3E%3Cpath%20d=%22M%200%20195.949219%20L%20375%20195.949219%20L%20375%20375%20L%200%20375%20Z%20M%200%20195.949219%20%22%20clip-rule=%22nonzero%22/%3E%3C/clipPath%3E%3CclipPath%20id=%221062f89594%22%3E%3Cpath%20d=%22M%200%200.949219%20L%20375%200.949219%20L%20375%20180%20L%200%20180%20Z%20M%200%200.949219%20%22%20clip-rule=%22nonzero%22/%3E%3C/clipPath%3E%3CclipPath%20id=%2217bc809498%22%3E%3Crect%20x=%220%22%20width=%22375%22%20y=%220%22%20height=%22180%22/%3E%3C/clipPath%3E%3CclipPath%20id=%22ad524f887e%22%3E%3Cpath%20d=%22M%202%2094%20L%20293%2094%20L%20293%20342%20L%202%20342%20Z%20M%202%2094%20%22%20clip-rule=%22nonzero%22/%3E%3C/clipPath%3E%3CclipPath%20id=%22ac73806eb1%22%3E%3Crect%20x=%220%22%20width=%22294%22%20y=%220%22%20height=%22342%22/%3E%3C/clipPath%3E%3C/defs%3E%3Crect%20x=%22-37.5%22%20width=%22450%22%20fill=%22%23ffffff%22%20y=%22-37.499999%22%20height=%22449.999989%22%20fill-opacity=%221%22/%3E%3Crect%20x=%22-37.5%22%20width=%22450%22%20fill=%22%23ffffff%22%20y=%22-37.499999%22%20height=%22449.999989%22%20fill-opacity=%221%22/%3E%3Cg%20clip-path=%22url(%23413a615d81)%22%3E%3Cg%20transform=%22matrix(1,%200,%200,%201,%200,%200)%22%3E%3Cg%20clip-path=%22url(%2366f7fee432)%22%3E%3Cg%20clip-path=%22url(%23b4114fb668)%22%3E%3Cg%20clip-path=%22url(%2302d2f74560)%22%3E%3Crect%20x=%22-82.5%22%20width=%22540%22%20fill=%22%2301adef%22%20height=%22539.999987%22%20y=%22-82.499998%22%20fill-opacity=%221%22/%3E%3C/g%3E%3C/g%3E%3C/g%3E%3C/g%3E%3C/g%3E%3Cg%20clip-path=%22url(%2344a7358375)%22%3E%3Cg%20clip-path=%22url(%2306d1da3b78)%22%3E%3Cg%20transform=%22matrix(1,%200,%200,%201,%2066,%2066)%22%3E%3Cg%20clip-path=%22url(%2367bf874d33)%22%3E%3Cg%20clip-path=%22url(%235f19be2713)%22%3E%3Cg%20clip-path=%22url(%23fde3ba0cc4)%22%3E%3Cpath%20fill=%22%23ffffff%22%20d=%22M%200.527344%200.527344%20L%20242.472656%200.527344%20L%20242.472656%20242.472656%20L%200.527344%20242.472656%20Z%20M%200.527344%200.527344%20%22%20fill-opacity=%221%22%20fill-rule=%22nonzero%22/%3E%3C/g%3E%3C/g%3E%3C/g%3E%3C/g%3E%3C/g%3E%3C/g%3E%3Cg%20clip-path=%22url(%2305f2bd6677)%22%3E%3Cg%20clip-path=%22url(%23a5274c9106)%22%3E%3Cg%20transform=%22matrix(1,%200,%200,%201,%200,%2098)%22%3E%3Cg%20clip-path=%22url(%238bb016993a)%22%3E%3Cg%20clip-path=%22url(%230f4217ffe3)%22%3E%3Cg%20clip-path=%22url(%23ca1f5799a3)%22%3E%3Cpath%20fill=%22%23ffffff%22%20d=%22M%20-29.023438%200.171875%20L%20403.371094%200.171875%20L%20403.371094%20410.144531%20L%20-29.023438%20410.144531%20Z%20M%20-29.023438%200.171875%20%22%20fill-opacity=%221%22%20fill-rule=%22nonzero%22/%3E%3C/g%3E%3C/g%3E%3C/g%3E%3C/g%3E%3C/g%3E%3C/g%3E%3Cg%20clip-path=%22url(%2376af0040d9)%22%3E%3Cg%20transform=%22matrix(1,%200,%200,%201,%200,%20195)%22%3E%3Cg%20clip-path=%22url(%2317bc809498)%22%3E%3Cg%20clip-path=%22url(%231062f89594)%22%3E%3Cpath%20fill=%22%23ffffff%22%20d=%22M%20-62.902344%200.949219%20L%20438.316406%200.949219%20L%20438.316406%20313.144531%20L%20-62.902344%20313.144531%20Z%20M%20-62.902344%200.949219%20%22%20fill-opacity=%221%22%20fill-rule=%22nonzero%22/%3E%3C/g%3E%3C/g%3E%3C/g%3E%3C/g%3E%3Cg%20transform=%22matrix(1,%200,%200,%201,%2040,%2033)%22%3E%3Cg%20clip-path=%22url(%23ac73806eb1)%22%3E%3Cg%20clip-path=%22url(%23ad524f887e)%22%3E%3Cg%20fill=%22%23202b61%22%20fill-opacity=%221%22%3E%3Cg%20transform=%22translate(7.369923,%20344.002374)%22%3E%3Cg%3E%3Cpath%20d=%22M%20192.15625%20-48.484375%20L%2086.640625%20-48.484375%20L%2067.03125%200%20L%20-4.984375%200%20L%20105.171875%20-249.5625%20L%20174.6875%20-249.5625%20L%20285.21875%200%20L%20211.765625%200%20Z%20M%20171.484375%20-100.53125%20L%20139.390625%20-180.390625%20L%20107.3125%20-100.53125%20Z%20M%20171.484375%20-100.53125%20%22/%3E%3C/g%3E%3C/g%3E%3C/g%3E%3C/g%3E%3C/g%3E%3C/g%3E%3Cpath%20stroke-linecap=%22butt%22%20transform=%22matrix(0.75,%200,%200,%200.75,%200.0000045,%20209.710181)%22%20fill=%22none%22%20stroke-linejoin=%22miter%22%20d=%22M%20-0.000006%2010.001009%20L%2088.703125%2010.001009%20%22%20stroke=%22%23202b61%22%20stroke-width=%2220%22%20stroke-opacity=%221%22%20stroke-miterlimit=%224%22/%3E%3Cpath%20stroke-linecap=%22butt%22%20transform=%22matrix(0.75,%200,%200,%200.75,%20308.473813,%20209.710181)%22%20fill=%22none%22%20stroke-linejoin=%22miter%22%20d=%22M%20-0.00154239%2010.001009%20L%2088.701588%2010.001009%20%22%20stroke=%22%23202b61%22%20stroke-width=%2220%22%20stroke-opacity=%221%22%20stroke-miterlimit=%224%22/%3E%3C/svg%3E";
5011
+ var ArbiIcon = ({
5012
+ size = 20,
5013
+ className = "",
5014
+ "aria-label": ariaLabel = "ARBI Docs",
5015
+ "aria-hidden": ariaHidden = false
5016
+ }) => {
5017
+ return /* @__PURE__ */ jsx(
5018
+ "img",
5019
+ {
5020
+ src: ARBI_MARK_SRC,
5021
+ alt: ariaLabel,
5022
+ className: `rounded object-contain ${className}`,
5023
+ style: { width: size, height: size },
5024
+ "aria-label": ariaLabel,
5025
+ "aria-hidden": ariaHidden
5026
+ }
5027
+ );
5028
+ };
5029
5029
  function nameInitials(name) {
5030
5030
  const parts = name.trim().split(/\s+/).filter(Boolean);
5031
5031
  if (!parts.length) return "?";
@@ -5199,5 +5199,5 @@ function UserMenu({
5199
5199
  }
5200
5200
 
5201
5201
  export { ARBI_MARK_SRC, AUDIO_MIME_PREFERENCE, AgentBadge, AiMarkdown, ArbiBotHeadIcon, ArbiIcon, AudIcon, BASE_COLORS2 as BASE_COLORS, Badge, COLUMN_LABEL_FALLBACKS, Card, CardContent, CardDescription, CardFooter, CardHeader, CardTitle, Checkbox, ClaudeIcon, Collapsible, CollapsibleContent2 as CollapsibleContent, CollapsibleTrigger2 as CollapsibleTrigger, Command, CommandDialog, CommandEmpty, CommandGroup, CommandInput, CommandItem, CommandList, CommandSeparator, CommandShortcut, DEFAULT_METADATA_TAGS, DebouncedInput, DocIcon, DocumentCard, DocumentEntity, ENTITY_MAPPINGS, EmlIcon, EntityIcon, EntityPill, FILE_TYPE_COLORS, FireworksIcon, GeminiIcon, GoogleIcon, HoverCard, HoverCardContent, HoverCardTrigger, HtmlIcon, IconToggle, ImgIcon, InlineMicButton, Input, Label2 as Label, MarkMenu, MicRecordingOverlay, MicWaveformIndicator, NEUTRAL_GRAY2 as NEUTRAL_GRAY, OpenAIIcon, PLACEHOLDER_COLOR, PassageCard, PdfIcon, Popover, PopoverAnchor, PopoverClose, PopoverContent, PopoverTrigger, PresenceLabel, Progress, ProjectEntity, ProviderIcon, RadioGroup, RadioGroupItem, RagDot, RelevanceDot, Select, SelectContent, SelectGroup, SelectItem, SelectLabel, SelectScrollDownButton, SelectScrollUpButton, SelectSeparator, SelectTrigger, SelectValue, Separator2 as Separator, ShieldIcon, Slider, StatusPill, Switch, TAG_TYPE_ICONS, TAG_TYPE_LABELS, Table, TableBody, TableCaption, TableCell, TableFooter, TableHead, TableHeader, TableRow, Tabs, TabsContent, TabsList, TabsTrigger, TagEntity, Textarea, ThreadVisibilityIcon, Toggle, ToggleGroup, ToggleGroupItem, Tooltip, TooltipContent, TooltipProvider, TooltipTrigger, TxtIcon, UserEntity, UserMenu, VIDEO_MIME_PREFERENCE, VISIBILITY_ICONS, VerifiedBadge, VerifiedToggle, VidIcon, VisibilityIcon, VisibilityToggle, XlsIcon, agentAvatarColors, badgeVariants, buildFolderTree, canonicalFolderPath, cardVariants, classifyMediaError, configureEntityRegistry, configureRagLabels, configureStatusRegistry, createChunkedRecorder, entityNoun, extensionFromMime, formatDocDate, formatElapsed, formatFolderLabel, formatFriendlyDate, friendlyFileType, getDocIcon, getDocumentAuthor, getDocumentDate, getDocumentNature, getDocumentSubject, getDocumentTitle, getEntityColor2 as getEntityColor, getEntityColorStyles, getEntityIcon, getEntityLabel, getFileExtension, getFileTypeIcon, getStatusVariant, getTagTypeIcon, getTagTypeLabel, getWorkspaceColor, isAudioFile, isDocumentAddableToConversation, isDownloadOnlyFile, isImageDocument, isImageFile, isMediaFile, isVideoFile, markdownToPlainText, markdownToPlainTextBlocks, pickRecorderMimeType, returnFocusToMark, tagKindNouns, tagKindTitle, toggleVariants, useAudioRecorder, useDictateContext, usesOriginalBytesForViewer };
5202
- //# sourceMappingURL=chunk-I4JYI6GY.js.map
5203
- //# sourceMappingURL=chunk-I4JYI6GY.js.map
5202
+ //# sourceMappingURL=chunk-KUGZXI7V.js.map
5203
+ //# sourceMappingURL=chunk-KUGZXI7V.js.map