@arbidocs/react 0.3.184 → 0.3.185

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.
package/dist/index.js CHANGED
@@ -1,21 +1,21 @@
1
- import { cn, Avatar, AvatarFallback, AvatarImage, Tooltip, TooltipTrigger, TooltipContent, Popover, PopoverTrigger, PopoverContent, AiMarkdown, Card, Button, Badge, MarkdownRenderer, Input, DropdownMenu, DropdownMenuTrigger, DropdownMenuContent, DropdownMenuItem, ScrollArea, Textarea, Slider, Dialog, DialogContent, DialogHeader, DialogTitle, DialogFooter, DropdownMenuLabel, DropdownMenuSeparator, Checkbox, useAudioRecorder, MicWaveformIndicator, IconToggle, classifyMediaError, formatElapsed } from './chunk-I256BUCX.js';
2
- export { AiMarkdown, Avatar, AvatarFallback, AvatarImage, Badge, Button, Card, CardContent, CardDescription, CardFooter, CardHeader, CardTitle, Checkbox, Collapsible, CollapsibleContent, CollapsibleTrigger, Command, CommandDialog, CommandEmpty, CommandGroup, CommandInput, CommandItem, CommandList, CommandSeparator, CommandShortcut, Dialog, DialogClose, DialogContent, DialogDescription, DialogFooter, DialogHeader, DialogOverlay, DialogPortal, DialogTitle, DialogTrigger, DictateProvider, DropdownMenu, DropdownMenuCheckboxItem, DropdownMenuContent, DropdownMenuGroup, DropdownMenuItem, DropdownMenuLabel, DropdownMenuPortal, DropdownMenuRadioGroup, DropdownMenuRadioItem, DropdownMenuSeparator, DropdownMenuShortcut, DropdownMenuSub, DropdownMenuSubContent, DropdownMenuSubTrigger, DropdownMenuTrigger, HoverCard, HoverCardContent, HoverCardTrigger, IconToggle, InlineMicButton, Input, Label, MarkdownRenderer, MarkdownStreamingContext, MicRecordingOverlay, MicWaveformIndicator, Popover, PopoverAnchor, PopoverContent, PopoverTrigger, Progress, RadioGroup, RadioGroupItem, ScrollArea, ScrollBar, Select, SelectContent, SelectGroup, SelectItem, SelectLabel, SelectScrollDownButton, SelectScrollUpButton, SelectSeparator, SelectTrigger, SelectValue, Separator, Slider, Switch, Table, TableBody, TableCaption, TableCell, TableFooter, TableHead, TableHeader, TableRow, Tabs, TabsContent, TabsList, TabsTrigger, Textarea, Toggle, ToggleGroup, ToggleGroupItem, Tooltip, TooltipContent, TooltipProvider, TooltipTrigger, badgeVariants, buttonVariants, cardVariants, cn, formatElapsed, markdownBaseComponents, splitMarkdownBlocks, toggleVariants, useAudioRecorder } from './chunk-I256BUCX.js';
1
+ import { useNotify, selectUnread, DEFAULT_NOTIFY_TONE } from './chunk-J3XEKOV5.js';
2
+ export { DEFAULT_NOTIFY_TONE, Toaster, notify, seedNotifications, selectUnread, toast, useNotify } from './chunk-J3XEKOV5.js';
3
+ import { cn, Popover, PopoverTrigger, PopoverContent, AiMarkdown, Card, Button, Badge, TagEntity, MarkdownRenderer, Input, FILE_TYPE_COLORS, getEntityIcon, DropdownMenu, DropdownMenuTrigger, DropdownMenuContent, DropdownMenuItem, ScrollArea, UserEntity, getEntityColorStyles, AgentBadge, Textarea, Slider, Dialog, DialogContent, DialogHeader, DialogTitle, DialogFooter, Avatar, AvatarImage, AvatarFallback, DropdownMenuLabel, DropdownMenuSeparator, DocumentEntity, Checkbox, useAudioRecorder, MicWaveformIndicator, IconToggle, classifyMediaError, formatElapsed, VidIcon, AudIcon, ImgIcon, EmlIcon, PdfIcon } from './chunk-YJAYST7S.js';
4
+ export { AgentBadge, AiMarkdown, ArbiBotHeadIcon, AudIcon, Avatar, AvatarFallback, AvatarImage, BASE_COLORS, Badge, Button, Card, CardContent, CardDescription, CardFooter, CardHeader, CardTitle, Checkbox, Collapsible, CollapsibleContent, CollapsibleTrigger, Command, CommandDialog, CommandEmpty, CommandGroup, CommandInput, CommandItem, CommandList, CommandSeparator, CommandShortcut, Dialog, DialogClose, DialogContent, DialogDescription, DialogFooter, DialogHeader, DialogOverlay, DialogPortal, DialogTitle, DialogTrigger, DictateProvider, DocumentEntity, DropdownMenu, DropdownMenuCheckboxItem, DropdownMenuContent, DropdownMenuGroup, DropdownMenuItem, DropdownMenuLabel, DropdownMenuPortal, DropdownMenuRadioGroup, DropdownMenuRadioItem, DropdownMenuSeparator, DropdownMenuShortcut, DropdownMenuSub, DropdownMenuSubContent, DropdownMenuSubTrigger, DropdownMenuTrigger, ENTITY_MAPPINGS, EmlIcon, EntityIcon, EntityPill, FILE_TYPE_COLORS, HoverCard, HoverCardContent, HoverCardTrigger, IconToggle, ImgIcon, InlineMicButton, Input, Label, MarkdownRenderer, MarkdownStreamingContext, MicRecordingOverlay, MicWaveformIndicator, NEUTRAL_GRAY, PLACEHOLDER_COLOR, PdfIcon, Popover, PopoverAnchor, PopoverContent, PopoverTrigger, PresenceLabel, Progress, ProjectEntity, RadioGroup, RadioGroupItem, RagDot, ScrollArea, ScrollBar, Select, SelectContent, SelectGroup, SelectItem, SelectLabel, SelectScrollDownButton, SelectScrollUpButton, SelectSeparator, SelectTrigger, SelectValue, Separator, Slider, StatusPill, Switch, TAG_TYPE_ICONS, TAG_TYPE_LABELS, Table, TableBody, TableCaption, TableCell, TableFooter, TableHead, TableHeader, TableRow, Tabs, TabsContent, TabsList, TabsTrigger, TagEntity, Textarea, Toggle, ToggleGroup, ToggleGroupItem, Tooltip, TooltipContent, TooltipProvider, TooltipTrigger, UserEntity, VISIBILITY_ICONS, VidIcon, VisibilityIcon, badgeVariants, buttonVariants, cardVariants, cn, configureEntityRegistry, configureRagLabels, configureStatusRegistry, formatElapsed, getDocIcon, getEntityColor, getEntityColorStyles, getEntityIcon, getEntityLabel, getStatusVariant, getTagTypeIcon, getTagTypeLabel, getWorkspaceColor, markdownBaseComponents, splitMarkdownBlocks, toggleVariants, useAudioRecorder } from './chunk-YJAYST7S.js';
3
5
  import { useArbi, ArbiProvider, AudioViewer, ImageViewer, VideoViewer } from './chunk-JKO3NR5L.js';
4
6
  export { ArbiProvider, useArbi } from './chunk-JKO3NR5L.js';
5
- import React2, { memo, useState, createContext, forwardRef, useMemo, useCallback, useId, useRef, useContext, useEffect, Fragment as Fragment$1 } from 'react';
7
+ import React, { memo, useState, createContext, useMemo, useCallback, useRef, useContext, useEffect, useId, Fragment as Fragment$1 } from 'react';
6
8
  import { useQuery, useMutation, useQueries, QueryClient, QueryClientProvider, useQueryClient } from '@tanstack/react-query';
7
9
  import { jsx, jsxs, Fragment } from 'react/jsx-runtime';
8
10
  import { connectWithReconnect, resolveCitations, summarizeCitations } from '@arbidocs/sdk/browser';
9
11
  export { Arbi, ArbiError } from '@arbidocs/sdk/browser';
10
- import { Link, Trash2, CheckCheck, Check, MessageCircleMore, MoreVertical, MessageSquareLock, Info, FileQuestion, BookOpen, Upload, LogOut, LayoutGrid, Bell, MessageSquare, CircleUserRound, Wrench, CreditCard, ClipboardList, UserPlus, UserStar, Settings2, Users, User, NotebookPen, NotebookText, StickyNote, FolderPlus, Hash, EyeOff, Eye, CaptionsOff, FolderOpen, MessageSquareMore, MessageSquarePlus, MessageSquareText, MessageSquareOff, MessagesSquare, Columns3Cog, SquarePlus, SquareM, ChevronsDown, Bot, Calendar, Search, Folder, List, SquareCheckBig, Loader2, AlertTriangle, ShieldCheck, Copy, Sparkles, FileText, GitCompareArrows, Download, Image as Image$1, CornerDownLeft, X, ArrowLeft, Send, Tags, Crown, Activity, Gauge, Gift, PartyPopper, UserCheck, FileX2, FileCheck2, Pencil, SquareArrowOutUpRight, BellOff, XCircle, CheckCircle2, ArrowRight, ChevronDown, MoreHorizontal, SquarePen, Mic, Pause, Play, Square, RotateCcw, Camera, Circle, FileX, SkipForward, CheckCircle } from 'lucide-react';
12
+ import { Link, Trash2, CheckCheck, Check, Loader2, AlertTriangle, ShieldCheck, Copy, Sparkles, FileText, GitCompareArrows, Download, Image as Image$1, Search, CornerDownLeft, X, ArrowLeft, Send, Tags, Crown, Info, Activity, Gauge, Gift, PartyPopper, UserCheck, MessageCircleMore, FileX2, FileCheck2, Pencil, FolderPlus, SquareArrowOutUpRight, Bell, BellOff, XCircle, CheckCircle2, MessagesSquare, ArrowRight, ChevronDown, LogOut, MoreHorizontal, SquarePen, Mic, Pause, Play, Square, RotateCcw, Camera, Circle, FileX, SkipForward, CheckCircle } from 'lucide-react';
11
13
  import { isMessageType } from '@arbidocs/client';
12
14
  export { isMessageType } from '@arbidocs/client';
13
15
  import { create } from 'zustand';
14
16
  import { diffWords } from 'diff';
15
17
  import { AnimatePresence, motion } from 'framer-motion';
16
18
  import ReactMarkdown from 'react-markdown';
17
- import { Toaster as Toaster$1, toast } from 'sonner';
18
- export { toast } from 'sonner';
19
19
  import Cropper from 'react-easy-crop';
20
20
  import { AgGridReact } from 'ag-grid-react';
21
21
  import { ModuleRegistry, AllCommunityModule } from 'ag-grid-community';
@@ -2205,350 +2205,6 @@ function DocSearch({
2205
2205
  ] })
2206
2206
  ] });
2207
2207
  }
2208
- var EntityPill = forwardRef(function EntityPill2({
2209
- icon,
2210
- label,
2211
- secondaryText,
2212
- size = "sm",
2213
- shape = "rounded",
2214
- className,
2215
- labelMaxWidth = "max-w-[320px]",
2216
- labelClassName,
2217
- fullWidth = false,
2218
- highlight = false,
2219
- onClick,
2220
- onIconClick,
2221
- onMoreClick,
2222
- moreContent,
2223
- href,
2224
- disabled = false,
2225
- tooltipContent,
2226
- tooltipSide = "bottom",
2227
- "data-testid": testId
2228
- }, ref) {
2229
- const shapeClass = shape === "pill" ? "rounded-full" : "rounded-md";
2230
- const sizeClasses2 = size === "base" ? "gap-1.5 px-1.5 py-0.5" : "gap-1 px-1";
2231
- const textSizeClass = size === "base" ? "text-base" : "text-sm";
2232
- const baseClasses = cn(
2233
- "group/pill items-center",
2234
- fullWidth ? "flex w-full" : "inline-flex",
2235
- sizeClasses2,
2236
- shapeClass,
2237
- "bg-muted",
2238
- "border border-border",
2239
- "transition-all",
2240
- className
2241
- );
2242
- const interactiveClasses = "cursor-pointer hover:bg-muted/80";
2243
- const disabledClasses = "cursor-default opacity-60";
2244
- const highlightClasses = "bg-primary text-primary-foreground hover:bg-primary hover:text-primary-foreground";
2245
- const mainContent = /* @__PURE__ */ jsxs(Fragment, { children: [
2246
- onIconClick ? /* @__PURE__ */ jsx(
2247
- "span",
2248
- {
2249
- role: "button",
2250
- tabIndex: 0,
2251
- className: "flex-shrink-0 cursor-pointer hover:opacity-70 transition-opacity",
2252
- onClick: (e) => {
2253
- e.stopPropagation();
2254
- onIconClick(e);
2255
- },
2256
- children: icon
2257
- }
2258
- ) : icon,
2259
- /* @__PURE__ */ jsx(
2260
- "span",
2261
- {
2262
- className: cn(
2263
- textSizeClass,
2264
- "font-medium truncate leading-tight min-w-0",
2265
- labelMaxWidth,
2266
- labelClassName
2267
- ),
2268
- children: label
2269
- }
2270
- ),
2271
- secondaryText && /* @__PURE__ */ jsx("span", { className: "text-xs text-muted-foreground flex-shrink-0 leading-none", children: secondaryText })
2272
- ] });
2273
- const tooltipWrap = (content, tip, side = tooltipSide, triggerClassName, triggerProps) => /* @__PURE__ */ jsxs(Tooltip, { children: [
2274
- /* @__PURE__ */ jsx(
2275
- TooltipTrigger,
2276
- {
2277
- onFocusCapture: (e) => e.stopPropagation(),
2278
- className: triggerClassName,
2279
- ...triggerProps,
2280
- children: content
2281
- }
2282
- ),
2283
- /* @__PURE__ */ jsx(TooltipContent, { side, className: "p-2", children: tip })
2284
- ] });
2285
- const mainAreaClass = cn("inline-flex items-center gap-1", fullWidth && "min-w-0 flex-1");
2286
- if (onMoreClick || moreContent) {
2287
- let mainArea;
2288
- if (tooltipContent) {
2289
- mainArea = tooltipWrap(
2290
- mainContent,
2291
- tooltipContent,
2292
- tooltipSide,
2293
- cn(mainAreaClass, disabled && "opacity-60"),
2294
- {
2295
- type: "button",
2296
- onClick: href ? onClick : disabled ? void 0 : onClick,
2297
- disabled: disabled || void 0
2298
- }
2299
- );
2300
- } else if (href) {
2301
- mainArea = /* @__PURE__ */ jsx(
2302
- "a",
2303
- {
2304
- href,
2305
- target: "_blank",
2306
- rel: "noopener noreferrer",
2307
- className: mainAreaClass,
2308
- onClick,
2309
- children: mainContent
2310
- }
2311
- );
2312
- } else if (onClick) {
2313
- mainArea = /* @__PURE__ */ jsx(
2314
- "button",
2315
- {
2316
- type: "button",
2317
- onClick: disabled ? void 0 : onClick,
2318
- disabled,
2319
- className: cn("inline-flex items-center gap-1", disabled && "opacity-60"),
2320
- children: mainContent
2321
- }
2322
- );
2323
- } else {
2324
- mainArea = /* @__PURE__ */ jsx("span", { className: mainAreaClass, children: mainContent });
2325
- }
2326
- const moreArea = moreContent ? /* @__PURE__ */ jsx("span", { className: "flex-shrink-0 leading-none", children: moreContent }) : tooltipWrap(
2327
- /* @__PURE__ */ jsx(MoreVertical, { className: "w-3.5 h-3.5" }),
2328
- "Click for more",
2329
- tooltipSide,
2330
- "flex-shrink-0 leading-none text-muted-foreground hover:text-foreground",
2331
- {
2332
- type: "button",
2333
- onClick: (e) => {
2334
- e.stopPropagation();
2335
- onMoreClick?.(e);
2336
- }
2337
- }
2338
- );
2339
- return /* @__PURE__ */ jsxs(
2340
- "span",
2341
- {
2342
- ref,
2343
- className: cn(
2344
- baseClasses,
2345
- (onClick || href) && !disabled && interactiveClasses,
2346
- highlight && highlightClasses
2347
- ),
2348
- "data-testid": testId,
2349
- children: [
2350
- mainArea,
2351
- moreArea
2352
- ]
2353
- }
2354
- );
2355
- }
2356
- if (tooltipContent) {
2357
- if (href) {
2358
- return tooltipWrap(
2359
- /* @__PURE__ */ jsx(
2360
- "a",
2361
- {
2362
- href,
2363
- target: "_blank",
2364
- rel: "noopener noreferrer",
2365
- className: mainAreaClass,
2366
- onClick,
2367
- children: mainContent
2368
- }
2369
- ),
2370
- tooltipContent,
2371
- tooltipSide,
2372
- cn(baseClasses, interactiveClasses),
2373
- { "data-testid": testId }
2374
- );
2375
- }
2376
- return tooltipWrap(
2377
- mainContent,
2378
- tooltipContent,
2379
- tooltipSide,
2380
- cn(
2381
- baseClasses,
2382
- onClick && !disabled ? interactiveClasses : "",
2383
- disabled ? disabledClasses : "",
2384
- highlight && highlightClasses
2385
- ),
2386
- {
2387
- type: "button",
2388
- ref,
2389
- onClick: onClick && !disabled ? onClick : void 0,
2390
- disabled: disabled || void 0,
2391
- "data-testid": testId
2392
- }
2393
- );
2394
- }
2395
- if (href) {
2396
- return /* @__PURE__ */ jsx(
2397
- "a",
2398
- {
2399
- ref,
2400
- href,
2401
- target: "_blank",
2402
- rel: "noopener noreferrer",
2403
- className: cn(baseClasses, interactiveClasses),
2404
- "data-testid": testId,
2405
- onClick,
2406
- children: mainContent
2407
- }
2408
- );
2409
- }
2410
- if (onClick) {
2411
- return /* @__PURE__ */ jsx(
2412
- "button",
2413
- {
2414
- ref,
2415
- type: "button",
2416
- onClick: disabled ? void 0 : onClick,
2417
- disabled,
2418
- className: cn(
2419
- baseClasses,
2420
- disabled ? disabledClasses : interactiveClasses,
2421
- highlight && highlightClasses
2422
- ),
2423
- "data-testid": testId,
2424
- children: mainContent
2425
- }
2426
- );
2427
- }
2428
- return /* @__PURE__ */ jsx(
2429
- "span",
2430
- {
2431
- ref,
2432
- className: cn(baseClasses, highlight && highlightClasses),
2433
- "data-testid": testId,
2434
- children: mainContent
2435
- }
2436
- );
2437
- });
2438
- var TAG_TYPE_LABELS = {
2439
- checkbox: "Checkbox",
2440
- select: "Select",
2441
- number: "Number",
2442
- text: "Text",
2443
- folder: "Folder",
2444
- search: "Saved Search",
2445
- date: "Date",
2446
- assistant: "AI Assistant"
2447
- };
2448
- var TAG_TYPE_ICONS = {
2449
- checkbox: SquareCheckBig,
2450
- select: List,
2451
- number: Hash,
2452
- text: NotebookPen,
2453
- folder: Folder,
2454
- search: Search,
2455
- date: Calendar,
2456
- assistant: Bot
2457
- };
2458
- function getTagTypeIcon(type) {
2459
- return TAG_TYPE_ICONS[type ?? "text"] || NotebookPen;
2460
- }
2461
- function getTagTypeLabel(type) {
2462
- const t = type ?? "text";
2463
- return TAG_TYPE_LABELS[t] || t;
2464
- }
2465
- var BASE_COLORS = {
2466
- "0": "#10b981",
2467
- "1": "#3b82f6",
2468
- "2": "#8b5cf6",
2469
- "3": "#f43f5e",
2470
- "4": "#f59e0b",
2471
- "5": "#84cc16",
2472
- "6": "#a855f7",
2473
- "7": "#06b6d4",
2474
- "8": "#f97316",
2475
- "9": "#14b8a6",
2476
- a: "#ef4444",
2477
- b: "#6366f1",
2478
- c: "#ec4899",
2479
- d: "#22c55e",
2480
- e: "#eab308",
2481
- f: "#0ea5e9"
2482
- };
2483
- function getEntityColor(entityId) {
2484
- return BASE_COLORS[entityId[4]] || BASE_COLORS["0"];
2485
- }
2486
- function TagEntity({
2487
- tag,
2488
- size = "md",
2489
- className = "",
2490
- onClick,
2491
- showTooltip = true,
2492
- tooltipContent
2493
- }) {
2494
- const tagType = tag.tag_type?.type ?? "text";
2495
- const iconSize = size === "sm" ? 12 : size === "md" ? 14 : 16;
2496
- const Icon = getTagTypeIcon(tagType);
2497
- const sizeClasses2 = {
2498
- sm: "p-0.5",
2499
- md: "p-1",
2500
- lg: "p-1.5"
2501
- };
2502
- const tagColor = tag.color ?? getEntityColor(tag.external_id);
2503
- const iconElement = /* @__PURE__ */ jsx(
2504
- "span",
2505
- {
2506
- className: `inline-flex items-center justify-center rounded-md text-white flex-shrink-0 ${sizeClasses2[size]}`,
2507
- style: { backgroundColor: tagColor },
2508
- children: /* @__PURE__ */ jsx(Icon, { size: iconSize, className: "flex-shrink-0" })
2509
- }
2510
- );
2511
- const pillSize = size === "lg" ? "base" : "sm";
2512
- const defaultTooltip = /* @__PURE__ */ jsxs("div", { className: "flex flex-col gap-2", children: [
2513
- /* @__PURE__ */ jsxs("div", { className: "flex items-center gap-2", children: [
2514
- /* @__PURE__ */ jsx(
2515
- "span",
2516
- {
2517
- className: "inline-flex items-center justify-center rounded-md text-white p-1",
2518
- style: { backgroundColor: tagColor },
2519
- children: /* @__PURE__ */ jsx(Icon, { size: 16 })
2520
- }
2521
- ),
2522
- /* @__PURE__ */ jsx("span", { className: "font-medium text-sm", children: tag.name })
2523
- ] }),
2524
- /* @__PURE__ */ jsxs("div", { className: "flex flex-col gap-1.5 text-sm", children: [
2525
- /* @__PURE__ */ jsxs("div", { className: "flex items-center gap-2", children: [
2526
- /* @__PURE__ */ jsx("span", { className: "text-muted-foreground", children: "Type:" }),
2527
- /* @__PURE__ */ jsx("span", { children: getTagTypeLabel(tagType) })
2528
- ] }),
2529
- tag.doctag_count != null && /* @__PURE__ */ jsxs("div", { className: "flex items-center gap-2", children: [
2530
- /* @__PURE__ */ jsx("span", { className: "text-muted-foreground", children: "Documents:" }),
2531
- /* @__PURE__ */ jsx(Badge, { variant: "secondary", className: "h-5 min-w-[20px] justify-center", children: tag.doctag_count ?? 0 })
2532
- ] }),
2533
- tag.shared != null && /* @__PURE__ */ jsx("div", { className: "flex items-center gap-2", children: /* @__PURE__ */ jsx("span", { className: "text-muted-foreground", children: tag.shared ? "Shared" : "Private" }) })
2534
- ] })
2535
- ] });
2536
- const resolvedTooltip = showTooltip ? tooltipContent ?? defaultTooltip : void 0;
2537
- return /* @__PURE__ */ jsx(
2538
- EntityPill,
2539
- {
2540
- icon: iconElement,
2541
- label: tag.name,
2542
- size: pillSize,
2543
- shape: "rounded",
2544
- labelMaxWidth: "max-w-[180px]",
2545
- tooltipContent: resolvedTooltip,
2546
- onClick,
2547
- className,
2548
- "data-testid": `tag-entity-${tag.external_id}`
2549
- }
2550
- );
2551
- }
2552
2208
  function DocumentReview({
2553
2209
  docId,
2554
2210
  doc,
@@ -2560,7 +2216,7 @@ function DocumentReview({
2560
2216
  }) {
2561
2217
  const parsedQuery = useParsedDocument(docId, stage);
2562
2218
  const tagsQuery = useTags(workspaceId);
2563
- const tagNameById = React2.useMemo(() => {
2219
+ const tagNameById = React.useMemo(() => {
2564
2220
  const map = /* @__PURE__ */ new Map();
2565
2221
  for (const t of tagsQuery.data ?? []) {
2566
2222
  if (t.external_id) map.set(t.external_id, t.name ?? t.external_id.slice(0, 8));
@@ -2568,7 +2224,7 @@ function DocumentReview({
2568
2224
  return map;
2569
2225
  }, [tagsQuery.data]);
2570
2226
  const title = doc?.doc_metadata?.title || doc?.file_name || "Document";
2571
- const { findings, chunkToTag } = React2.useMemo(() => {
2227
+ const { findings, chunkToTag } = React.useMemo(() => {
2572
2228
  const list = [];
2573
2229
  const chunkTag = /* @__PURE__ */ new Map();
2574
2230
  for (const dt of doc?.doctags ?? []) {
@@ -2584,7 +2240,7 @@ function DocumentReview({
2584
2240
  }
2585
2241
  return { findings: list, chunkToTag: chunkTag };
2586
2242
  }, [doc?.doctags]);
2587
- const pages = React2.useMemo(() => {
2243
+ const pages = React.useMemo(() => {
2588
2244
  const chunks = parsedQuery.data?.chunks ?? [];
2589
2245
  const byPage = /* @__PURE__ */ new Map();
2590
2246
  for (const c of chunks) {
@@ -2594,9 +2250,9 @@ function DocumentReview({
2594
2250
  }
2595
2251
  return [...byPage.entries()].sort((a, b) => a[0] - b[0]);
2596
2252
  }, [parsedQuery.data]);
2597
- const scrollRef = React2.useRef(null);
2598
- const [flash, setFlash] = React2.useState(null);
2599
- const jumpToChunk = React2.useCallback((chunkId) => {
2253
+ const scrollRef = React.useRef(null);
2254
+ const [flash, setFlash] = React.useState(null);
2255
+ const jumpToChunk = React.useCallback((chunkId) => {
2600
2256
  const el = scrollRef.current?.querySelector(`[data-chunk-id="${chunkId}"]`);
2601
2257
  if (!el) return;
2602
2258
  el.scrollIntoView({ behavior: "smooth", block: "center" });
@@ -2604,7 +2260,7 @@ function DocumentReview({
2604
2260
  window.setTimeout(() => setFlash((c) => c === chunkId ? null : c), 1600);
2605
2261
  }, []);
2606
2262
  const parsedReady = !parsedQuery.isLoading && !!parsedQuery.data;
2607
- React2.useEffect(() => {
2263
+ React.useEffect(() => {
2608
2264
  if (!activeChunkId || !parsedReady) return;
2609
2265
  const raf = window.requestAnimationFrame(() => jumpToChunk(activeChunkId));
2610
2266
  return () => window.cancelAnimationFrame(raf);
@@ -3333,7 +2989,7 @@ var CitationPopover = ({
3333
2989
  }
3334
2990
  );
3335
2991
  };
3336
- var CitationLink = React2.forwardRef(
2992
+ var CitationLink = React.forwardRef(
3337
2993
  ({ citationNum, isActive, isStreaming, children, ...props }, ref) => /* @__PURE__ */ jsxs(
3338
2994
  "span",
3339
2995
  {
@@ -3353,86 +3009,7 @@ var CitationLink = React2.forwardRef(
3353
3009
  )
3354
3010
  );
3355
3011
  CitationLink.displayName = "CitationLink";
3356
- var CitationRenderer = React2.memo(CitationRendererComponent);
3357
-
3358
- // src/icons/colors.ts
3359
- var NEUTRAL_GRAY = "#64748b";
3360
- var FILE_TYPE_COLORS = {
3361
- pdf: "#ef4444",
3362
- // red
3363
- doc: "#3b82f6",
3364
- // blue (Word docs)
3365
- docx: "#3b82f6",
3366
- // blue
3367
- html: "#0284c7",
3368
- // sky-600 (web files)
3369
- img: "#8b5cf6",
3370
- // violet-500 (images)
3371
- vid: "#10b981",
3372
- // emerald-500 (video)
3373
- aud: "#f59e0b",
3374
- // amber-500 (audio)
3375
- xls: "#16a34a",
3376
- // green-600 (Excel)
3377
- eml: "#0d9488",
3378
- // teal-600 (email)
3379
- txt: NEUTRAL_GRAY,
3380
- // gray (plain text)
3381
- generic: NEUTRAL_GRAY,
3382
- // gray (unknown)
3383
- white: "#ffffff"
3384
- // for strokes/text on colored backgrounds
3385
- };
3386
- var PdfIcon = ({ size = 16, className = "" }) => {
3387
- return /* @__PURE__ */ jsxs(
3388
- "svg",
3389
- {
3390
- width: size,
3391
- height: size,
3392
- viewBox: "0 0 24 24",
3393
- fill: "none",
3394
- xmlns: "http://www.w3.org/2000/svg",
3395
- className,
3396
- children: [
3397
- /* @__PURE__ */ jsx(
3398
- "path",
3399
- {
3400
- d: "M14 2H6a2 2 0 0 0-2 2v16a2 2 0 0 0 2 2h12a2 2 0 0 0 2-2V8l-6-6z",
3401
- fill: FILE_TYPE_COLORS.pdf,
3402
- stroke: FILE_TYPE_COLORS.pdf,
3403
- strokeWidth: "1",
3404
- strokeLinecap: "round",
3405
- strokeLinejoin: "round"
3406
- }
3407
- ),
3408
- /* @__PURE__ */ jsx(
3409
- "path",
3410
- {
3411
- d: "M14 2v6h6",
3412
- fill: "none",
3413
- stroke: FILE_TYPE_COLORS.white,
3414
- strokeWidth: "1",
3415
- strokeLinecap: "round",
3416
- strokeLinejoin: "round"
3417
- }
3418
- ),
3419
- /* @__PURE__ */ jsx(
3420
- "text",
3421
- {
3422
- x: "12",
3423
- y: "16",
3424
- fontSize: "6",
3425
- fill: "white",
3426
- textAnchor: "middle",
3427
- fontWeight: "bold",
3428
- fontFamily: "Arial, sans-serif",
3429
- children: "PDF"
3430
- }
3431
- )
3432
- ]
3433
- }
3434
- );
3435
- };
3012
+ var CitationRenderer = React.memo(CitationRendererComponent);
3436
3013
  var DocIcon = ({ size = 16, className = "" }) => {
3437
3014
  return /* @__PURE__ */ jsxs(
3438
3015
  "svg",
@@ -3633,207 +3210,6 @@ var XlsIcon = ({ size = 16, className = "" }) => {
3633
3210
  }
3634
3211
  );
3635
3212
  };
3636
- var AudIcon = ({ size = 16, className = "" }) => {
3637
- return /* @__PURE__ */ jsxs(
3638
- "svg",
3639
- {
3640
- width: size,
3641
- height: size,
3642
- viewBox: "0 0 24 24",
3643
- fill: "none",
3644
- xmlns: "http://www.w3.org/2000/svg",
3645
- className,
3646
- children: [
3647
- /* @__PURE__ */ jsx(
3648
- "path",
3649
- {
3650
- d: "M14 2H6a2 2 0 0 0-2 2v16a2 2 0 0 0 2 2h12a2 2 0 0 0 2-2V8l-6-6z",
3651
- fill: FILE_TYPE_COLORS.aud,
3652
- stroke: FILE_TYPE_COLORS.aud,
3653
- strokeWidth: "1",
3654
- strokeLinecap: "round",
3655
- strokeLinejoin: "round"
3656
- }
3657
- ),
3658
- /* @__PURE__ */ jsx(
3659
- "path",
3660
- {
3661
- d: "M14 2v6h6",
3662
- fill: "none",
3663
- stroke: FILE_TYPE_COLORS.white,
3664
- strokeWidth: "1",
3665
- strokeLinecap: "round",
3666
- strokeLinejoin: "round"
3667
- }
3668
- ),
3669
- /* @__PURE__ */ jsx(
3670
- "text",
3671
- {
3672
- x: "12",
3673
- y: "16",
3674
- fontSize: "6",
3675
- fill: "white",
3676
- textAnchor: "middle",
3677
- fontWeight: "bold",
3678
- fontFamily: "Arial, sans-serif",
3679
- children: "AUD"
3680
- }
3681
- )
3682
- ]
3683
- }
3684
- );
3685
- };
3686
- var ImgIcon = ({ size = 16, className = "" }) => {
3687
- return /* @__PURE__ */ jsxs(
3688
- "svg",
3689
- {
3690
- width: size,
3691
- height: size,
3692
- viewBox: "0 0 24 24",
3693
- fill: "none",
3694
- xmlns: "http://www.w3.org/2000/svg",
3695
- className,
3696
- children: [
3697
- /* @__PURE__ */ jsx(
3698
- "path",
3699
- {
3700
- d: "M14 2H6a2 2 0 0 0-2 2v16a2 2 0 0 0 2 2h12a2 2 0 0 0 2-2V8l-6-6z",
3701
- fill: FILE_TYPE_COLORS.img,
3702
- stroke: FILE_TYPE_COLORS.img,
3703
- strokeWidth: "1",
3704
- strokeLinecap: "round",
3705
- strokeLinejoin: "round"
3706
- }
3707
- ),
3708
- /* @__PURE__ */ jsx(
3709
- "path",
3710
- {
3711
- d: "M14 2v6h6",
3712
- fill: "none",
3713
- stroke: FILE_TYPE_COLORS.white,
3714
- strokeWidth: "1",
3715
- strokeLinecap: "round",
3716
- strokeLinejoin: "round"
3717
- }
3718
- ),
3719
- /* @__PURE__ */ jsx(
3720
- "text",
3721
- {
3722
- x: "12",
3723
- y: "16",
3724
- fontSize: "6",
3725
- fill: "white",
3726
- textAnchor: "middle",
3727
- fontWeight: "bold",
3728
- fontFamily: "Arial, sans-serif",
3729
- children: "IMG"
3730
- }
3731
- )
3732
- ]
3733
- }
3734
- );
3735
- };
3736
- var VidIcon = ({ size = 16, className = "" }) => {
3737
- return /* @__PURE__ */ jsxs(
3738
- "svg",
3739
- {
3740
- width: size,
3741
- height: size,
3742
- viewBox: "0 0 24 24",
3743
- fill: "none",
3744
- xmlns: "http://www.w3.org/2000/svg",
3745
- className,
3746
- children: [
3747
- /* @__PURE__ */ jsx(
3748
- "path",
3749
- {
3750
- d: "M14 2H6a2 2 0 0 0-2 2v16a2 2 0 0 0 2 2h12a2 2 0 0 0 2-2V8l-6-6z",
3751
- fill: FILE_TYPE_COLORS.vid,
3752
- stroke: FILE_TYPE_COLORS.vid,
3753
- strokeWidth: "1",
3754
- strokeLinecap: "round",
3755
- strokeLinejoin: "round"
3756
- }
3757
- ),
3758
- /* @__PURE__ */ jsx(
3759
- "path",
3760
- {
3761
- d: "M14 2v6h6",
3762
- fill: "none",
3763
- stroke: FILE_TYPE_COLORS.white,
3764
- strokeWidth: "1",
3765
- strokeLinecap: "round",
3766
- strokeLinejoin: "round"
3767
- }
3768
- ),
3769
- /* @__PURE__ */ jsx(
3770
- "text",
3771
- {
3772
- x: "12",
3773
- y: "16",
3774
- fontSize: "6",
3775
- fill: "white",
3776
- textAnchor: "middle",
3777
- fontWeight: "bold",
3778
- fontFamily: "Arial, sans-serif",
3779
- children: "VID"
3780
- }
3781
- )
3782
- ]
3783
- }
3784
- );
3785
- };
3786
- var EmlIcon = ({ size = 16, className = "" }) => {
3787
- return /* @__PURE__ */ jsxs(
3788
- "svg",
3789
- {
3790
- width: size,
3791
- height: size,
3792
- viewBox: "0 0 24 24",
3793
- fill: "none",
3794
- xmlns: "http://www.w3.org/2000/svg",
3795
- className,
3796
- children: [
3797
- /* @__PURE__ */ jsx(
3798
- "path",
3799
- {
3800
- d: "M14 2H6a2 2 0 0 0-2 2v16a2 2 0 0 0 2 2h12a2 2 0 0 0 2-2V8l-6-6z",
3801
- fill: FILE_TYPE_COLORS.eml,
3802
- stroke: FILE_TYPE_COLORS.eml,
3803
- strokeWidth: "1",
3804
- strokeLinecap: "round",
3805
- strokeLinejoin: "round"
3806
- }
3807
- ),
3808
- /* @__PURE__ */ jsx(
3809
- "path",
3810
- {
3811
- d: "M14 2v6h6",
3812
- fill: "none",
3813
- stroke: FILE_TYPE_COLORS.white,
3814
- strokeWidth: "1",
3815
- strokeLinecap: "round",
3816
- strokeLinejoin: "round"
3817
- }
3818
- ),
3819
- /* @__PURE__ */ jsx(
3820
- "rect",
3821
- {
3822
- x: "7",
3823
- y: "12",
3824
- width: "10",
3825
- height: "7",
3826
- rx: "1",
3827
- fill: "none",
3828
- stroke: "white",
3829
- strokeWidth: "1.2"
3830
- }
3831
- ),
3832
- /* @__PURE__ */ jsx("path", { d: "M7 13l5 3 5-3", fill: "none", stroke: "white", strokeWidth: "1.2", strokeLinejoin: "round" })
3833
- ]
3834
- }
3835
- );
3836
- };
3837
3213
  var FileIcon = ({ size = 16, className = "" }) => {
3838
3214
  return /* @__PURE__ */ jsxs(
3839
3215
  "svg",
@@ -4131,80 +3507,40 @@ function ProviderIcon({
4131
3507
  return /* @__PURE__ */ jsx(OpenAIIcon, { size, className });
4132
3508
  }
4133
3509
  if (m.includes("claude") || p === "anthropic") {
4134
- return /* @__PURE__ */ jsx(ClaudeIcon, { size, className });
4135
- }
4136
- if (m.includes("gemini") || p.startsWith("vertex_ai")) {
4137
- return /* @__PURE__ */ jsx(GeminiIcon, { size, className });
4138
- }
4139
- if (p === "google") {
4140
- return /* @__PURE__ */ jsx(GoogleIcon, { size, className });
4141
- }
4142
- if (p === "fireworks_ai") {
4143
- return /* @__PURE__ */ jsx(FireworksIcon, { size, className });
4144
- }
4145
- return /* @__PURE__ */ jsx(
4146
- Crown,
4147
- {
4148
- className,
4149
- style: { width: size, height: size, color: "#EAB308", fill: "#EAB308" }
4150
- }
4151
- );
4152
- }
4153
- var ArbiIcon = ({
4154
- size = 20,
4155
- className = "",
4156
- "aria-label": ariaLabel = "ARBI Docs",
4157
- "aria-hidden": ariaHidden = false
4158
- }) => {
4159
- return /* @__PURE__ */ jsx(
4160
- "img",
4161
- {
4162
- src: "/favicon.svg",
4163
- alt: ariaLabel,
4164
- className: `rounded object-contain ${className}`,
4165
- style: { width: size, height: size },
4166
- "aria-label": ariaLabel,
4167
- "aria-hidden": ariaHidden
4168
- }
4169
- );
4170
- };
4171
- var ArbiBotHeadIcon = ({ size = 24, className = "" }) => {
4172
- const maskId = useId();
4173
- return /* @__PURE__ */ jsxs(
4174
- "svg",
4175
- {
4176
- xmlns: "http://www.w3.org/2000/svg",
4177
- width: size,
4178
- height: size,
4179
- viewBox: "30 -5 190 190",
4180
- preserveAspectRatio: "xMidYMid meet",
4181
- className,
4182
- children: [
4183
- /* @__PURE__ */ jsx("defs", { children: /* @__PURE__ */ jsx("mask", { id: maskId, children: /* @__PURE__ */ jsxs("g", { transform: "translate(0,250) scale(0.1,-0.1)", children: [
4184
- /* @__PURE__ */ jsx("rect", { x: "0", y: "0", width: "2500", height: "2500", fill: "white" }),
4185
- /* @__PURE__ */ jsx("circle", { cx: "855", cy: "1715", r: "190", fill: "black" }),
4186
- /* @__PURE__ */ jsx("circle", { cx: "855", cy: "1715", r: "50", fill: "white" }),
4187
- /* @__PURE__ */ jsx("circle", { cx: "1665", cy: "1700", r: "190", fill: "black" }),
4188
- /* @__PURE__ */ jsx("circle", { cx: "1665", cy: "1700", r: "50", fill: "white" })
4189
- ] }) }) }),
4190
- /* @__PURE__ */ jsxs("g", { mask: `url(#${maskId})`, children: [
4191
- /* @__PURE__ */ jsx(
4192
- "g",
4193
- {
4194
- transform: "translate(0,250) scale(0.1,-0.1)",
4195
- fill: "currentColor",
4196
- stroke: "currentColor",
4197
- strokeWidth: "100",
4198
- 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" })
4199
- }
4200
- ),
4201
- /* @__PURE__ */ jsxs("g", { transform: "translate(0,250) scale(0.1,-0.1)", fill: "currentColor", stroke: "none", children: [
4202
- /* @__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" }),
4203
- /* @__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" }),
4204
- /* @__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" })
4205
- ] })
4206
- ] })
4207
- ]
3510
+ return /* @__PURE__ */ jsx(ClaudeIcon, { size, className });
3511
+ }
3512
+ if (m.includes("gemini") || p.startsWith("vertex_ai")) {
3513
+ return /* @__PURE__ */ jsx(GeminiIcon, { size, className });
3514
+ }
3515
+ if (p === "google") {
3516
+ return /* @__PURE__ */ jsx(GoogleIcon, { size, className });
3517
+ }
3518
+ if (p === "fireworks_ai") {
3519
+ return /* @__PURE__ */ jsx(FireworksIcon, { size, className });
3520
+ }
3521
+ return /* @__PURE__ */ jsx(
3522
+ Crown,
3523
+ {
3524
+ className,
3525
+ style: { width: size, height: size, color: "#EAB308", fill: "#EAB308" }
3526
+ }
3527
+ );
3528
+ }
3529
+ var ArbiIcon = ({
3530
+ size = 20,
3531
+ className = "",
3532
+ "aria-label": ariaLabel = "ARBI Docs",
3533
+ "aria-hidden": ariaHidden = false
3534
+ }) => {
3535
+ return /* @__PURE__ */ jsx(
3536
+ "img",
3537
+ {
3538
+ src: "/favicon.svg",
3539
+ alt: ariaLabel,
3540
+ className: `rounded object-contain ${className}`,
3541
+ style: { width: size, height: size },
3542
+ "aria-label": ariaLabel,
3543
+ "aria-hidden": ariaHidden
4208
3544
  }
4209
3545
  );
4210
3546
  };
@@ -4256,754 +3592,6 @@ var ArbiBotIcon = ({ size = 24, className = "" }) => {
4256
3592
  }
4257
3593
  );
4258
3594
  };
4259
- function getDocumentTitle(document2, defaultValue = "") {
4260
- if (!document2) return defaultValue;
4261
- return document2.doc_metadata?.title || document2.file_name || defaultValue;
4262
- }
4263
- var MAX_LABEL_CHARS = 30;
4264
- function clampLabel(text) {
4265
- return text.length > MAX_LABEL_CHARS ? `${text.slice(0, MAX_LABEL_CHARS).trimEnd()}\u2026` : text;
4266
- }
4267
- var IMAGE_EXTENSIONS = /* @__PURE__ */ new Set(["jpg", "jpeg", "png", "gif", "bmp", "tiff", "tif", "webp"]);
4268
- var VIDEO_EXTENSIONS = /* @__PURE__ */ new Set(["mp4", "mpeg", "mpg", "webm", "mov", "avi", "mkv"]);
4269
- var AUDIO_EXTENSIONS = /* @__PURE__ */ new Set(["mp3", "wav", "m4a", "aac", "ogg", "flac"]);
4270
- var EMAIL_EXTENSIONS = /* @__PURE__ */ new Set(["eml", "msg"]);
4271
- function getDocIcon(fileName, iconSize = 14) {
4272
- const ext = fileName?.split(".").pop()?.toLowerCase();
4273
- if (ext && VIDEO_EXTENSIONS.has(ext)) return /* @__PURE__ */ jsx(VidIcon, { size: iconSize, className: "flex-shrink-0" });
4274
- if (ext && AUDIO_EXTENSIONS.has(ext)) return /* @__PURE__ */ jsx(AudIcon, { size: iconSize, className: "flex-shrink-0" });
4275
- if (ext && IMAGE_EXTENSIONS.has(ext)) return /* @__PURE__ */ jsx(ImgIcon, { size: iconSize, className: "flex-shrink-0" });
4276
- if (ext && EMAIL_EXTENSIONS.has(ext)) return /* @__PURE__ */ jsx(EmlIcon, { size: iconSize, className: "flex-shrink-0" });
4277
- return /* @__PURE__ */ jsx(PdfIcon, { size: iconSize, className: "flex-shrink-0" });
4278
- }
4279
- function DocumentEntity({
4280
- doc,
4281
- icon,
4282
- size = "sm",
4283
- labelMaxWidth,
4284
- labelClassName,
4285
- onClick,
4286
- onIconClick,
4287
- viewing,
4288
- iconBadge,
4289
- actions,
4290
- tooltipContent,
4291
- className,
4292
- fullWidth,
4293
- noClamp
4294
- }) {
4295
- const title = getDocumentTitle(doc);
4296
- const ext = doc.file_name?.split(".").pop()?.toLowerCase();
4297
- const iconSize = size === "base" ? 16 : 14;
4298
- const eyeSizeClass = size === "base" ? "h-4 w-4" : "h-3.5 w-3.5";
4299
- const baseIcon = icon ?? getDocIcon(doc.file_name, iconSize);
4300
- const displayIcon = viewing || iconBadge ? /* @__PURE__ */ jsxs("span", { className: "relative inline-flex flex-shrink-0 items-center justify-center", children: [
4301
- viewing ? /* @__PURE__ */ jsx(Eye, { className: cn("text-primary-foreground", eyeSizeClass) }) : baseIcon,
4302
- iconBadge
4303
- ] }) : baseIcon;
4304
- const defaultTooltip = /* @__PURE__ */ jsxs("div", { className: "flex flex-col gap-1 text-xs max-w-[440px]", children: [
4305
- doc.folder && // `flex-wrap` so a deep folder path wraps WITHIN the balloon instead of
4306
- // spilling out of it (each path segment is atomic and wraps as a unit;
4307
- // `min-w-0` + `break-all` lets a single over-long segment break too).
4308
- /* @__PURE__ */ jsxs("span", { className: "flex flex-wrap items-center gap-0.5 text-muted-foreground", children: [
4309
- /* @__PURE__ */ jsx(FolderOpen, { className: "h-3 w-3 text-yellow-600 shrink-0" }),
4310
- doc.folder.split("/").map((part, i, arr) => /* @__PURE__ */ jsxs("span", { className: "flex min-w-0 items-center gap-0.5", children: [
4311
- i > 0 && /* @__PURE__ */ jsx("span", { className: "text-muted-foreground/50 mx-0.5", children: "/" }),
4312
- /* @__PURE__ */ jsx("span", { className: `break-all ${i < arr.length - 1 ? "text-muted-foreground/70" : ""}`, children: part })
4313
- ] }, i))
4314
- ] }),
4315
- /* @__PURE__ */ jsxs("span", { className: "font-medium break-words", children: [
4316
- title,
4317
- ext ? `.${ext}` : ""
4318
- ] })
4319
- ] });
4320
- return /* @__PURE__ */ jsx(
4321
- EntityPill,
4322
- {
4323
- icon: displayIcon,
4324
- size,
4325
- label: fullWidth || noClamp ? title : clampLabel(title),
4326
- labelMaxWidth: labelMaxWidth ?? "max-w-[140px]",
4327
- labelClassName,
4328
- fullWidth,
4329
- onClick,
4330
- onIconClick,
4331
- moreContent: actions,
4332
- className,
4333
- highlight: viewing,
4334
- tooltipContent: tooltipContent ?? defaultTooltip
4335
- }
4336
- );
4337
- }
4338
- var VARIANT_STYLES = {
4339
- "mine-paid": {
4340
- pill: "bg-primary/10 text-primary border-border/60",
4341
- icon: "text-primary"
4342
- },
4343
- other: {
4344
- pill: "bg-secondary/10 text-secondary border-border/60",
4345
- icon: "text-secondary"
4346
- },
4347
- "mine-free": {
4348
- pill: "bg-muted-foreground/10 text-muted-foreground border-border/60",
4349
- icon: "text-muted-foreground"
4350
- },
4351
- common: {
4352
- pill: "",
4353
- icon: "text-muted-foreground"
4354
- }
4355
- };
4356
- function resolveVariant(relation, paid, hasCollaborators) {
4357
- if (relation === "common") return "common";
4358
- if (relation === "other") return "other";
4359
- if (relation === "mine") return paid ? "mine-paid" : "mine-free";
4360
- if (paid) return hasCollaborators ? "other" : "mine-paid";
4361
- return "mine-free";
4362
- }
4363
- function ProjectEntity({
4364
- name,
4365
- label,
4366
- icon,
4367
- subscription = "none",
4368
- hasCollaborators = false,
4369
- size = "sm",
4370
- className,
4371
- onClick,
4372
- relation,
4373
- isPaid,
4374
- tooltipContent
4375
- }) {
4376
- const paid = isPaid ?? (subscription === "active" || subscription === "past_due" || subscription === "dev");
4377
- const variant = resolveVariant(relation, paid, hasCollaborators);
4378
- const { pill, icon: iconClass } = VARIANT_STYLES[variant];
4379
- const iconSizeClass = size === "base" ? "h-4 w-4" : "h-3.5 w-3.5";
4380
- const iconNode = icon ?? /* @__PURE__ */ jsx(CreditCard, { className: cn(iconSizeClass, iconClass) });
4381
- return /* @__PURE__ */ jsx(
4382
- EntityPill,
4383
- {
4384
- icon: iconNode,
4385
- label: label ?? name,
4386
- size,
4387
- shape: "rounded",
4388
- className: cn(pill, className),
4389
- onClick,
4390
- tooltipContent
4391
- }
4392
- );
4393
- }
4394
- var sizeClasses = {
4395
- xs: "h-5 w-5",
4396
- sm: "h-6 w-6",
4397
- md: "h-8 w-8",
4398
- lg: "h-10 w-10"
4399
- };
4400
- var textSizeClasses = {
4401
- xs: "text-xs",
4402
- sm: "text-xs",
4403
- md: "text-xs",
4404
- lg: "text-sm"
4405
- };
4406
- var presenceDotClasses = {
4407
- xs: "w-2 h-2 border",
4408
- sm: "w-2.5 h-2.5 border",
4409
- md: "w-3 h-3 border-2",
4410
- lg: "w-3.5 h-3.5 border-2"
4411
- };
4412
- var presencePositionClasses = {
4413
- xs: "-right-1 bottom-0",
4414
- sm: "-right-1 bottom-0",
4415
- md: "-right-1.5 -bottom-0.5",
4416
- lg: "-right-1.5 -bottom-0.5"
4417
- };
4418
- var PRESENCE_LABELS = {
4419
- connected: "Online",
4420
- connecting: "Connecting",
4421
- disconnected: "Offline",
4422
- error: "Connection problem",
4423
- hidden: "Status hidden"
4424
- };
4425
- var presenceColorClasses = {
4426
- connected: "bg-status-online",
4427
- connecting: "bg-status-connecting",
4428
- disconnected: "bg-status-away",
4429
- error: "bg-status-busy",
4430
- hidden: "bg-status-offline"
4431
- };
4432
- var UserEntity = memo(function UserEntity2({
4433
- size = "md",
4434
- variant = "pill",
4435
- className,
4436
- showTooltip = true,
4437
- interactive = true,
4438
- hasUnreadMessages = false,
4439
- initials = "",
4440
- displayName = "",
4441
- picture,
4442
- colorClass = "",
4443
- isAgent = false,
4444
- agentStyle,
4445
- avatarStyle,
4446
- isMe = false,
4447
- displayStatus,
4448
- onClick,
4449
- tooltipContent,
4450
- empty = false
4451
- }) {
4452
- if (empty) {
4453
- return /* @__PURE__ */ jsx(
4454
- Avatar,
4455
- {
4456
- className: cn(sizeClasses[size], "border border-border", className),
4457
- "data-testid": "user-entity",
4458
- children: /* @__PURE__ */ jsx(AvatarFallback, { className: "bg-status-empty text-muted-foreground text-xs font-semibold", children: "?" })
4459
- }
4460
- );
4461
- }
4462
- const agentBadge = isAgent ? /* @__PURE__ */ jsx(ArbiBotHeadIcon, { className: "w-3.5 h-3.5 text-muted-foreground" }) : void 0;
4463
- const canMessage = interactive && !isMe && !isAgent;
4464
- const showUnread = hasUnreadMessages && !isMe && !isAgent;
4465
- const surfaceStyle = avatarStyle ?? agentStyle;
4466
- const avatarCore = /* @__PURE__ */ jsxs(
4467
- Avatar,
4468
- {
4469
- className: cn(
4470
- sizeClasses[size],
4471
- isAgent ? "rounded-full border-2 border-dashed" : "border border-white"
4472
- ),
4473
- style: surfaceStyle,
4474
- "data-testid": "user-entity",
4475
- children: [
4476
- picture && /* @__PURE__ */ jsx(AvatarImage, { src: picture, alt: initials }),
4477
- /* @__PURE__ */ jsx(
4478
- AvatarFallback,
4479
- {
4480
- className: cn(
4481
- textSizeClasses[size],
4482
- "font-semibold leading-none",
4483
- isAgent ? "rounded-full bg-transparent" : `text-white ${colorClass}`
4484
- ),
4485
- style: surfaceStyle,
4486
- children: initials
4487
- }
4488
- )
4489
- ]
4490
- }
4491
- );
4492
- const statusDot = showUnread || displayStatus ? /* @__PURE__ */ jsx(
4493
- "span",
4494
- {
4495
- className: cn(
4496
- "absolute rounded-full border-white",
4497
- presenceDotClasses[size],
4498
- presencePositionClasses[size],
4499
- !showUnread && displayStatus ? presenceColorClasses[displayStatus] : ""
4500
- ),
4501
- style: showUnread ? { backgroundColor: "#00adef" } : void 0,
4502
- "data-testid": "user-entity-presence",
4503
- role: "img",
4504
- "aria-label": showUnread ? "Unread messages" : PRESENCE_LABELS[displayStatus],
4505
- title: showUnread ? "Unread messages" : PRESENCE_LABELS[displayStatus]
4506
- }
4507
- ) : null;
4508
- const avatarElement = statusDot ? /* @__PURE__ */ jsxs(
4509
- "div",
4510
- {
4511
- className: cn(
4512
- "relative inline-block",
4513
- sizeClasses[size],
4514
- variant === "pill" ? "" : className
4515
- ),
4516
- children: [
4517
- avatarCore,
4518
- statusDot
4519
- ]
4520
- }
4521
- ) : /* @__PURE__ */ jsx("div", { className: cn("inline-block", variant === "pill" ? "" : className), children: avatarCore });
4522
- const pillAvatar = (
4523
- // shrink-0: when the pill is squeezed the NAME truncates away — the avatar
4524
- // must never collapse under it and overflow onto neighbouring text.
4525
- /* @__PURE__ */ jsxs("span", { className: cn("relative inline-block shrink-0", sizeClasses[size]), children: [
4526
- /* @__PURE__ */ jsx("span", { className: cn("block transition-opacity", canMessage && "group-hover/pill:opacity-0"), children: avatarCore }),
4527
- canMessage && /* @__PURE__ */ jsx(
4528
- "span",
4529
- {
4530
- "aria-hidden": true,
4531
- className: "absolute inset-0 flex items-center justify-center rounded-full bg-muted text-foreground opacity-0 transition-opacity group-hover/pill:opacity-100",
4532
- children: /* @__PURE__ */ jsx(MessageCircleMore, { className: size === "xs" ? "h-3 w-3" : "h-4 w-4" })
4533
- }
4534
- ),
4535
- statusDot
4536
- ] })
4537
- );
4538
- const resolvedTooltip = showTooltip ? tooltipContent : void 0;
4539
- if (variant === "pill") {
4540
- const row = /* @__PURE__ */ jsxs(Fragment, { children: [
4541
- pillAvatar,
4542
- displayName && /* @__PURE__ */ jsx("span", { className: "min-w-0 max-w-[320px] truncate text-sm leading-tight", children: displayName }),
4543
- agentBadge
4544
- ] });
4545
- const rowClass = "group/pill inline-flex min-w-0 items-center gap-2";
4546
- const clickable = interactive && !!onClick;
4547
- const clickableClass = "cursor-pointer rounded-md px-1 py-0.5 -mx-1 transition-colors hover:bg-muted/60";
4548
- if (resolvedTooltip) {
4549
- return /* @__PURE__ */ jsxs(Tooltip, { children: [
4550
- /* @__PURE__ */ jsx(
4551
- TooltipTrigger,
4552
- {
4553
- type: "button",
4554
- onClick: clickable ? onClick : void 0,
4555
- onFocusCapture: (e) => e.stopPropagation(),
4556
- className: cn(rowClass, clickable && clickableClass, className),
4557
- "data-testid": "user-entity-pill",
4558
- children: row
4559
- }
4560
- ),
4561
- /* @__PURE__ */ jsx(TooltipContent, { className: "p-2", children: resolvedTooltip })
4562
- ] });
4563
- }
4564
- if (clickable) {
4565
- return /* @__PURE__ */ jsx(
4566
- "button",
4567
- {
4568
- type: "button",
4569
- onClick,
4570
- className: cn(rowClass, clickableClass, className),
4571
- "data-testid": "user-entity-pill",
4572
- children: row
4573
- }
4574
- );
4575
- }
4576
- return /* @__PURE__ */ jsx("span", { className: cn(rowClass, className), "data-testid": "user-entity-pill", children: row });
4577
- }
4578
- if (showTooltip) {
4579
- return /* @__PURE__ */ jsxs(Tooltip, { children: [
4580
- /* @__PURE__ */ jsx(TooltipTrigger, { onFocusCapture: (e) => e.stopPropagation(), className: "inline-flex", children: avatarElement }),
4581
- /* @__PURE__ */ jsx(TooltipContent, { className: "p-2", children: tooltipContent })
4582
- ] });
4583
- }
4584
- return avatarElement;
4585
- });
4586
- function AgentBadge({ className }) {
4587
- return /* @__PURE__ */ jsxs(
4588
- "span",
4589
- {
4590
- "data-testid": "agent-badge",
4591
- className: cn(
4592
- "inline-flex shrink-0 items-center gap-1 rounded-full border border-ai-accent/50",
4593
- "bg-ai-accent-soft px-2 py-0.5 text-[11px] font-bold uppercase tracking-wider text-ai-accent",
4594
- className
4595
- ),
4596
- children: [
4597
- /* @__PURE__ */ jsx(ArbiBotHeadIcon, { size: 14, className: "text-ai-accent" }),
4598
- "Agent"
4599
- ]
4600
- }
4601
- );
4602
- }
4603
- var PRESENCE_WORDS = {
4604
- connected: "Online",
4605
- connecting: "Connecting",
4606
- disconnected: "Offline",
4607
- error: "Connection problem",
4608
- hidden: null
4609
- };
4610
- function PresenceLabel({
4611
- status,
4612
- className
4613
- }) {
4614
- if (!status) return null;
4615
- const word = PRESENCE_WORDS[status];
4616
- if (!word) return null;
4617
- const online = status === "connected";
4618
- return /* @__PURE__ */ jsxs(
4619
- "span",
4620
- {
4621
- "data-testid": "presence-label",
4622
- className: cn("inline-flex shrink-0 items-center gap-1 text-xs", className),
4623
- children: [
4624
- /* @__PURE__ */ jsx(
4625
- "span",
4626
- {
4627
- className: cn(
4628
- "size-1.5 rounded-full",
4629
- online ? "bg-status-online" : "bg-muted-foreground/50"
4630
- ),
4631
- "aria-hidden": "true"
4632
- }
4633
- ),
4634
- /* @__PURE__ */ jsx("span", { className: online ? "font-medium text-status-online" : "text-muted-foreground", children: word })
4635
- ]
4636
- }
4637
- );
4638
- }
4639
- var PACKAGE_BADGE_VARIANTS = [
4640
- "default",
4641
- "accent",
4642
- "secondary",
4643
- "destructive",
4644
- "outline"
4645
- ];
4646
- function isPackageBadgeVariant(v) {
4647
- return PACKAGE_BADGE_VARIANTS.some((known) => known === v);
4648
- }
4649
- function PackageStatusBadge({ variant, ...rest }) {
4650
- return /* @__PURE__ */ jsx(Badge, { variant: isPackageBadgeVariant(variant) ? variant : "outline", ...rest });
4651
- }
4652
- var registry = {
4653
- variants: {},
4654
- fallback: "outline",
4655
- Badge: PackageStatusBadge
4656
- };
4657
- function configureStatusRegistry(map, opts) {
4658
- Object.assign(registry.variants, map);
4659
- if (opts?.fallback) registry.fallback = opts.fallback;
4660
- if (opts?.Badge) registry.Badge = opts.Badge;
4661
- }
4662
- function getStatusVariant(status) {
4663
- return registry.variants[status] ?? registry.fallback;
4664
- }
4665
- function StatusPill({ status, label, variant, className, testId }) {
4666
- const Badge2 = registry.Badge;
4667
- return /* @__PURE__ */ jsx(Badge2, { variant: variant ?? getStatusVariant(status), className, "data-testid": testId, children: label ?? status });
4668
- }
4669
- var RAG_LABELS = { red: "At risk", amber: "Attention", green: "On track" };
4670
- function configureRagLabels(labels) {
4671
- RAG_LABELS = { ...RAG_LABELS, ...labels };
4672
- }
4673
- function RagDot({
4674
- rag,
4675
- withLabel,
4676
- className
4677
- }) {
4678
- const color = rag === "red" ? "bg-destructive" : rag === "amber" ? "bg-warning" : "bg-success";
4679
- return /* @__PURE__ */ jsxs("span", { className: cn("inline-flex items-center gap-1.5", className), "data-testid": `rag-${rag}`, children: [
4680
- /* @__PURE__ */ jsx("span", { className: cn("size-2 rounded-full", color) }),
4681
- withLabel && /* @__PURE__ */ jsx("span", { className: "text-xs text-muted-foreground", children: RAG_LABELS[rag] })
4682
- ] });
4683
- }
4684
- var ENTITY_MAPPINGS = {
4685
- PRODUCT: {
4686
- NAMES: {
4687
- SINGULAR: "ARBI Docs"
4688
- },
4689
- ICONS: {
4690
- DEFAULT: MessageSquareLock
4691
- }
4692
- },
4693
- SECTION: {
4694
- NAMES: {
4695
- SINGULAR: "Section"
4696
- },
4697
- ICONS: {
4698
- DEFAULT: ChevronsDown
4699
- }
4700
- },
4701
- WORKSPACE: {
4702
- NAMES: {
4703
- SINGULAR: "Workspace",
4704
- PLURAL: "Workspaces"
4705
- },
4706
- ICONS: {
4707
- DEFAULT: SquareM,
4708
- NEW: SquarePlus,
4709
- LIST: LayoutGrid,
4710
- SETTINGS: Columns3Cog
4711
- }
4712
- },
4713
- CONVERSATION: {
4714
- NAMES: {
4715
- SINGULAR: "Chat",
4716
- PLURAL: "Chats",
4717
- NEW: "New ARBI Chat"
4718
- },
4719
- ICONS: {
4720
- DEFAULT: MessagesSquare,
4721
- OFF: MessageSquareOff,
4722
- ACTIVE: MessageSquareText,
4723
- NEW: MessageSquarePlus,
4724
- LIST: MessageSquareMore
4725
- }
4726
- },
4727
- DOCUMENT: {
4728
- NAMES: {
4729
- SINGULAR: "File",
4730
- PLURAL: "Files"
4731
- },
4732
- ICONS: {
4733
- DEFAULT: FolderOpen,
4734
- OFF: CaptionsOff
4735
- }
4736
- },
4737
- VIEWER: {
4738
- NAMES: {
4739
- SINGULAR: "Viewer",
4740
- PLURAL: "Viewers"
4741
- },
4742
- ICONS: {
4743
- DEFAULT: Eye,
4744
- OFF: EyeOff
4745
- }
4746
- },
4747
- TAG: {
4748
- NAMES: {
4749
- SINGULAR: "Field",
4750
- PLURAL: "Fields"
4751
- },
4752
- ICONS: {
4753
- DEFAULT: Hash,
4754
- NEW: FolderPlus
4755
- }
4756
- },
4757
- ANNOTATION: {
4758
- NAMES: {
4759
- SINGULAR: "Annotation",
4760
- PLURAL: "Annotations"
4761
- },
4762
- ICONS: {
4763
- DEFAULT: StickyNote,
4764
- NEW: StickyNote
4765
- }
4766
- },
4767
- // Workspace knowledge the assistant retains and recalls — durable free text,
4768
- // optionally grounded in source passages. Distinct from ANNOTATION, which is
4769
- // attached TO a document field; a NOTE is workspace-scoped and stands alone.
4770
- // Stored server-side as `memories` (mem-*); "Note" is the user-facing name.
4771
- NOTE: {
4772
- NAMES: {
4773
- SINGULAR: "Note",
4774
- PLURAL: "Notes"
4775
- },
4776
- ICONS: {
4777
- DEFAULT: NotebookText,
4778
- NEW: NotebookPen
4779
- }
4780
- },
4781
- USER: {
4782
- NAMES: {
4783
- SINGULAR: "User",
4784
- PLURAL: "Users"
4785
- },
4786
- ICONS: {
4787
- DEFAULT: User,
4788
- NEW: UserPlus,
4789
- SETTINGS: Settings2
4790
- }
4791
- },
4792
- WORKSPACEUSER: {
4793
- NAMES: {
4794
- SINGULAR: "Member",
4795
- PLURAL: "Members"
4796
- },
4797
- ICONS: {
4798
- DEFAULT: User,
4799
- PLURAL: Users,
4800
- NEW: UserPlus,
4801
- SETTINGS: Settings2
4802
- }
4803
- },
4804
- CONTACT: {
4805
- NAMES: {
4806
- SINGULAR: "Contact",
4807
- PLURAL: "Contacts"
4808
- },
4809
- ICONS: {
4810
- // A starred person, not an address-book card: contacts here are the
4811
- // people you talk to, and the star reads as "your people".
4812
- DEFAULT: UserStar,
4813
- NEW: UserPlus
4814
- }
4815
- },
4816
- TASK: {
4817
- NAMES: {
4818
- SINGULAR: "Job",
4819
- PLURAL: "Jobs"
4820
- },
4821
- ICONS: {
4822
- DEFAULT: ClipboardList
4823
- }
4824
- },
4825
- PROJECT: {
4826
- NAMES: {
4827
- SINGULAR: "Project",
4828
- PLURAL: "Projects"
4829
- },
4830
- ICONS: {
4831
- DEFAULT: CreditCard
4832
- }
4833
- },
4834
- SKILL: {
4835
- NAMES: {
4836
- SINGULAR: "Skill",
4837
- PLURAL: "Skills"
4838
- },
4839
- ICONS: {
4840
- DEFAULT: Wrench
4841
- }
4842
- },
4843
- ACCOUNT: {
4844
- NAMES: {
4845
- SINGULAR: "Account"
4846
- },
4847
- ICONS: {
4848
- DEFAULT: CircleUserRound
4849
- }
4850
- },
4851
- NOTIFICATIONS: {
4852
- NAMES: {
4853
- SINGULAR: "Activity",
4854
- PLURAL: "Activities"
4855
- },
4856
- ICONS: {
4857
- DEFAULT: Bell
4858
- }
4859
- },
4860
- MESSAGE: {
4861
- NAMES: {
4862
- SINGULAR: "Message",
4863
- PLURAL: "Messages"
4864
- },
4865
- ICONS: {
4866
- DEFAULT: MessageSquare
4867
- }
4868
- },
4869
- NOTIFICATION: {
4870
- NAMES: {
4871
- SINGULAR: "Notification",
4872
- PLURAL: "Notifications"
4873
- },
4874
- ICONS: {
4875
- DEFAULT: Bell
4876
- }
4877
- },
4878
- APP: {
4879
- NAMES: {
4880
- SINGULAR: "Application",
4881
- PLURAL: "Applications"
4882
- },
4883
- ICONS: {
4884
- DEFAULT: LayoutGrid,
4885
- HOME: LayoutGrid,
4886
- LOGOUT: LogOut,
4887
- UPLOAD: Upload
4888
- }
4889
- },
4890
- HELP: {
4891
- NAMES: {
4892
- SINGULAR: "Help",
4893
- PLURAL: "Help"
4894
- },
4895
- ICONS: {
4896
- DEFAULT: MessageSquareLock,
4897
- DOCS: BookOpen,
4898
- FAQ: FileQuestion,
4899
- ABOUT: Info
4900
- }
4901
- },
4902
- USERSHIELD: {
4903
- NAMES: {
4904
- SINGULAR: "User Shield",
4905
- PLURAL: "User Shields"
4906
- },
4907
- ICONS: {
4908
- DEFAULT: MessageSquareLock
4909
- }
4910
- }
4911
- };
4912
- function configureEntityRegistry(overrides) {
4913
- for (const [type, def] of Object.entries(overrides)) {
4914
- const target = ENTITY_MAPPINGS[type];
4915
- if (!target) continue;
4916
- if (def?.NAMES) Object.assign(target.NAMES, def.NAMES);
4917
- if (def?.ICONS) Object.assign(target.ICONS, def.ICONS);
4918
- }
4919
- }
4920
- var getEntityIcon = (entityType, variant = "DEFAULT") => {
4921
- const icons = ENTITY_MAPPINGS[entityType]?.ICONS;
4922
- return icons?.[variant] || icons?.DEFAULT;
4923
- };
4924
- var getEntityLabel = (entityType, form = "SINGULAR") => {
4925
- const entityMapping = ENTITY_MAPPINGS[entityType];
4926
- if (!entityMapping) return "";
4927
- const names = entityMapping.NAMES;
4928
- const singularName = names.SINGULAR || "";
4929
- if (form === "NEW") return names.NEW !== void 0 ? names.NEW : "New " + singularName;
4930
- if (form === "SHORT")
4931
- return names.SHORT !== void 0 ? names.SHORT : singularName.substring(0, 3) + ".";
4932
- if (form === "PLURAL") return names.PLURAL !== void 0 ? names.PLURAL : singularName + "s";
4933
- return singularName;
4934
- };
4935
- var EntityIcon = ({ entityType, variant = "DEFAULT", ...props }) => {
4936
- const IconComponent = getEntityIcon(entityType, variant);
4937
- return IconComponent ? React2.createElement(IconComponent, props) : null;
4938
- };
4939
- var VISIBILITY_ICONS = {
4940
- PRIVATE: MessageSquareLock,
4941
- SHARED: Users
4942
- };
4943
- var VisibilityIcon = ({
4944
- isShared,
4945
- ...props
4946
- }) => {
4947
- const IconComponent = isShared ? VISIBILITY_ICONS.SHARED : VISIBILITY_ICONS.PRIVATE;
4948
- return React2.createElement(IconComponent, props);
4949
- };
4950
-
4951
- // src/entities/colors.ts
4952
- var OPACITY_LIGHT = 0.15;
4953
- var OPACITY_MEDIUM = 1;
4954
- var OPACITY_BORDER = 0.3;
4955
- var PLACEHOLDER_COLOR = "#9ca3af";
4956
- var NEUTRAL_GRAY2 = "#64748b";
4957
- var BASE_COLORS2 = {
4958
- "0": "#10b981",
4959
- "1": "#3b82f6",
4960
- "2": "#8b5cf6",
4961
- "3": "#f43f5e",
4962
- "4": "#f59e0b",
4963
- "5": "#84cc16",
4964
- "6": "#a855f7",
4965
- "7": "#06b6d4",
4966
- "8": "#f97316",
4967
- "9": "#14b8a6",
4968
- a: "#ef4444",
4969
- b: "#6366f1",
4970
- c: "#ec4899",
4971
- d: "#22c55e",
4972
- e: "#eab308",
4973
- f: "#0ea5e9"
4974
- };
4975
- function hexToRgba(hex, opacity) {
4976
- const r = parseInt(hex.slice(1, 3), 16);
4977
- const g = parseInt(hex.slice(3, 5), 16);
4978
- const b = parseInt(hex.slice(5, 7), 16);
4979
- return `rgba(${r}, ${g}, ${b}, ${opacity})`;
4980
- }
4981
- function getEntityColor2(entityId, variant = "medium") {
4982
- const baseColor = BASE_COLORS2[entityId[4]] || BASE_COLORS2["0"];
4983
- switch (variant) {
4984
- case "light":
4985
- return hexToRgba(baseColor, OPACITY_LIGHT);
4986
- case "medium":
4987
- return hexToRgba(baseColor, OPACITY_MEDIUM);
4988
- case "text":
4989
- return baseColor;
4990
- }
4991
- }
4992
- function getEntityColorStyles(entityId) {
4993
- const baseColor = BASE_COLORS2[entityId[4]] || BASE_COLORS2["0"];
4994
- return {
4995
- backgroundColor: getEntityColor2(entityId, "light"),
4996
- color: baseColor,
4997
- borderColor: hexToRgba(baseColor, OPACITY_BORDER)
4998
- };
4999
- }
5000
- var getWorkspaceColor = (workspaceId, useWorkspaceColors) => {
5001
- const shouldUseWorkspaceColors = useWorkspaceColors !== void 0 ? useWorkspaceColors : true;
5002
- if (!shouldUseWorkspaceColors) return "hsl(var(--primary))";
5003
- const isValidId = workspaceId && workspaceId.startsWith("wrk-") && workspaceId.length >= 5;
5004
- if (!isValidId) return "hsl(var(--primary))";
5005
- return getEntityColor2(workspaceId, "medium");
5006
- };
5007
3595
  function getNotificationTypeMeta(type) {
5008
3596
  const WorkspaceIcon = getEntityIcon("WORKSPACE");
5009
3597
  switch (type) {
@@ -5191,65 +3779,6 @@ function ActivityFeed({
5191
3779
  );
5192
3780
  }) });
5193
3781
  }
5194
- var seq = 0;
5195
- var uid = () => `n${Date.now().toString(36)}${(seq++).toString(36)}`;
5196
- var useNotify = create((set) => ({
5197
- notifications: [],
5198
- markRead: (id) => set((s) => ({
5199
- notifications: s.notifications.map((n) => n.id === id ? { ...n, read: true } : n)
5200
- })),
5201
- markAllRead: () => set((s) => ({ notifications: s.notifications.map((n) => ({ ...n, read: true })) })),
5202
- removeNotification: (id) => set((s) => ({ notifications: s.notifications.filter((n) => n.id !== id) })),
5203
- clearNotifications: () => set({ notifications: [] }),
5204
- seed: (items) => set({ notifications: items }),
5205
- record: (note) => set((s) => ({ notifications: [note, ...s.notifications].slice(0, 50) })),
5206
- syncSource: (source, items) => set((s) => ({
5207
- notifications: [
5208
- ...items.map((n) => ({ ...n, source })),
5209
- ...s.notifications.filter((n) => n.source !== source)
5210
- ].sort((a, b) => b.ts - a.ts).slice(0, 100)
5211
- }))
5212
- }));
5213
- function make(variant) {
5214
- return (title, opts = {}) => {
5215
- toast[variant](title, {
5216
- description: opts.description,
5217
- duration: opts.duration,
5218
- action: opts.action,
5219
- icon: opts.icon
5220
- });
5221
- const id = uid();
5222
- if (opts.record !== false) {
5223
- useNotify.getState().record({
5224
- id,
5225
- title,
5226
- description: opts.description,
5227
- variant,
5228
- ts: Date.now(),
5229
- read: false,
5230
- href: opts.href,
5231
- ambient: opts.ambient
5232
- });
5233
- }
5234
- return id;
5235
- };
5236
- }
5237
- var notify = {
5238
- success: make("success"),
5239
- error: make("error"),
5240
- info: make("info"),
5241
- warning: make("warning")
5242
- };
5243
- function seedNotifications(items) {
5244
- useNotify.getState().seed(items);
5245
- }
5246
- var selectUnread = (s) => s.notifications.filter((n) => !n.read && !n.ambient).length;
5247
- var DEFAULT_NOTIFY_TONE = {
5248
- success: "text-green-600",
5249
- error: "text-destructive",
5250
- warning: "text-amber-500",
5251
- info: "text-blue-500"
5252
- };
5253
3782
 
5254
3783
  // src/directmessages/utils.ts
5255
3784
  function userInitials(user) {
@@ -5439,24 +3968,6 @@ function NotificationBell({
5439
3968
  )
5440
3969
  ] });
5441
3970
  }
5442
- var DEFAULT_TOAST_OPTIONS = {
5443
- classNames: {
5444
- toast: "group toast group-[.toaster]:bg-card group-[.toaster]:text-foreground group-[.toaster]:border group-[.toaster]:border-border group-[.toaster]:shadow-lg group-[.toaster]:rounded-lg",
5445
- description: "group-[.toast]:text-muted-foreground",
5446
- actionButton: "group-[.toast]:bg-primary group-[.toast]:text-primary-foreground",
5447
- cancelButton: "group-[.toast]:bg-muted group-[.toast]:text-muted-foreground"
5448
- }
5449
- };
5450
- function Toaster({ toastOptions, ...props }) {
5451
- return /* @__PURE__ */ jsx(
5452
- Toaster$1,
5453
- {
5454
- className: "toaster group",
5455
- toastOptions: toastOptions ?? DEFAULT_TOAST_OPTIONS,
5456
- ...props
5457
- }
5458
- );
5459
- }
5460
3971
  var DM_QUERY_KEY = ["arbi", "directMessages"];
5461
3972
  var CONTACTS_QUERY_KEY = ["arbi", "contacts"];
5462
3973
  function mergeContacts(threads, contacts) {
@@ -6545,7 +5056,7 @@ function DocumentTable({
6545
5056
  const rows = documents ?? query.data ?? [];
6546
5057
  const isLoading = !documents && query.isLoading;
6547
5058
  const tagsQuery = useTags(workspaceId);
6548
- const tagNameById = React2.useMemo(() => {
5059
+ const tagNameById = React.useMemo(() => {
6549
5060
  const map = /* @__PURE__ */ new Map();
6550
5061
  for (const t of tagsQuery.data ?? []) {
6551
5062
  if (t.external_id) map.set(t.external_id, t.name ?? t.external_id.slice(0, 8));
@@ -6558,15 +5069,15 @@ function DocumentTable({
6558
5069
  const setViewingDocId = useArbiUiStore((s) => s.setViewingDocId);
6559
5070
  const effectiveSelected = selectedIds ?? storeSelected;
6560
5071
  const emitSelection = onSelectionChange ?? storeSetSelected;
6561
- const gridApiRef = React2.useRef(null);
6562
- const openDocument = React2.useCallback(
5072
+ const gridApiRef = React.useRef(null);
5073
+ const openDocument = React.useCallback(
6563
5074
  (id) => {
6564
5075
  setViewingDocId(id);
6565
5076
  onOpenDocument?.(id);
6566
5077
  },
6567
5078
  [onOpenDocument, setViewingDocId]
6568
5079
  );
6569
- const applySelection = React2.useCallback(() => {
5080
+ const applySelection = React.useCallback(() => {
6570
5081
  const api = gridApiRef.current;
6571
5082
  if (!api) return;
6572
5083
  const wanted = new Set(effectiveSelected);
@@ -6576,10 +5087,10 @@ function DocumentTable({
6576
5087
  if (node.isSelected() !== shouldSelect) node.setSelected(shouldSelect);
6577
5088
  });
6578
5089
  }, [effectiveSelected]);
6579
- React2.useEffect(() => {
5090
+ React.useEffect(() => {
6580
5091
  applySelection();
6581
5092
  }, [applySelection]);
6582
- const columnDefs = React2.useMemo(
5093
+ const columnDefs = React.useMemo(
6583
5094
  () => [
6584
5095
  {
6585
5096
  colId: "select",
@@ -6687,7 +5198,7 @@ function DocumentTable({
6687
5198
  const id = e.data?.external_id;
6688
5199
  if (id) openDocument(id);
6689
5200
  };
6690
- const getRowId = React2.useCallback((params) => params.data.external_id, []);
5201
+ const getRowId = React.useCallback((params) => params.data.external_id, []);
6691
5202
  const autoHeight = height === "auto";
6692
5203
  const style = autoHeight ? {} : { height: typeof height === "number" ? `${height}px` : height, width: "100%" };
6693
5204
  if (isLoading) {
@@ -6729,16 +5240,16 @@ var STATUS_LABEL = {
6729
5240
  indexing: "Indexing",
6730
5241
  analysing: "Analysing"
6731
5242
  };
6732
- var IMAGE_EXTENSIONS2 = /* @__PURE__ */ new Set(["jpg", "jpeg", "png", "gif", "bmp", "tiff", "tif", "webp"]);
6733
- var VIDEO_EXTENSIONS2 = /* @__PURE__ */ new Set(["mp4", "mpeg", "mpg", "webm", "mov", "avi", "mkv"]);
6734
- var AUDIO_EXTENSIONS2 = /* @__PURE__ */ new Set(["mp3", "wav", "m4a", "aac", "ogg", "flac"]);
6735
- var EMAIL_EXTENSIONS2 = /* @__PURE__ */ new Set(["eml", "msg"]);
5243
+ var IMAGE_EXTENSIONS = /* @__PURE__ */ new Set(["jpg", "jpeg", "png", "gif", "bmp", "tiff", "tif", "webp"]);
5244
+ var VIDEO_EXTENSIONS = /* @__PURE__ */ new Set(["mp4", "mpeg", "mpg", "webm", "mov", "avi", "mkv"]);
5245
+ var AUDIO_EXTENSIONS = /* @__PURE__ */ new Set(["mp3", "wav", "m4a", "aac", "ogg", "flac"]);
5246
+ var EMAIL_EXTENSIONS = /* @__PURE__ */ new Set(["eml", "msg"]);
6736
5247
  function fileIcon(fileName, size) {
6737
5248
  const ext = fileName?.split(".").pop()?.toLowerCase();
6738
- if (ext && VIDEO_EXTENSIONS2.has(ext)) return /* @__PURE__ */ jsx(VidIcon, { size });
6739
- if (ext && AUDIO_EXTENSIONS2.has(ext)) return /* @__PURE__ */ jsx(AudIcon, { size });
6740
- if (ext && IMAGE_EXTENSIONS2.has(ext)) return /* @__PURE__ */ jsx(ImgIcon, { size });
6741
- if (ext && EMAIL_EXTENSIONS2.has(ext)) return /* @__PURE__ */ jsx(EmlIcon, { size });
5249
+ if (ext && VIDEO_EXTENSIONS.has(ext)) return /* @__PURE__ */ jsx(VidIcon, { size });
5250
+ if (ext && AUDIO_EXTENSIONS.has(ext)) return /* @__PURE__ */ jsx(AudIcon, { size });
5251
+ if (ext && IMAGE_EXTENSIONS.has(ext)) return /* @__PURE__ */ jsx(ImgIcon, { size });
5252
+ if (ext && EMAIL_EXTENSIONS.has(ext)) return /* @__PURE__ */ jsx(EmlIcon, { size });
6742
5253
  return /* @__PURE__ */ jsx(PdfIcon, { size });
6743
5254
  }
6744
5255
  function RenameField({
@@ -6747,7 +5258,7 @@ function RenameField({
6747
5258
  onCancel,
6748
5259
  testId
6749
5260
  }) {
6750
- const done = React2.useRef(false);
5261
+ const done = React.useRef(false);
6751
5262
  const commit = (value) => {
6752
5263
  if (done.current) return;
6753
5264
  done.current = true;
@@ -6835,8 +5346,8 @@ function DocumentCard({
6835
5346
  const normalised = (status ?? "").toLowerCase();
6836
5347
  const isProcessing = ACTIVE_STATUSES.has(normalised);
6837
5348
  const showStatusMarker = !isProcessing && TERMINAL_STATUSES2.has(normalised);
6838
- const [thumbFailed, setThumbFailed] = React2.useState(false);
6839
- const [thumbLandscape, setThumbLandscape] = React2.useState(false);
5349
+ const [thumbFailed, setThumbFailed] = React.useState(false);
5350
+ const [thumbLandscape, setThumbLandscape] = React.useState(false);
6840
5351
  const showThumbnail = !!thumbnailUrl && !thumbFailed && !isProcessing;
6841
5352
  return /* @__PURE__ */ jsxs(
6842
5353
  "div",
@@ -7040,14 +5551,14 @@ function DocumentGallery({
7040
5551
  const rows = documents ?? query.data ?? [];
7041
5552
  const isLoading = !documents && query.isLoading;
7042
5553
  const tagsQuery = useTags(workspaceId);
7043
- const tagNameById = React2.useMemo(() => {
5554
+ const tagNameById = React.useMemo(() => {
7044
5555
  const map = /* @__PURE__ */ new Map();
7045
5556
  for (const t of tagsQuery.data ?? []) {
7046
5557
  if (t.external_id) map.set(t.external_id, t.name ?? t.external_id.slice(0, 8));
7047
5558
  }
7048
5559
  return map;
7049
5560
  }, [tagsQuery.data]);
7050
- const docIds = React2.useMemo(
5561
+ const docIds = React.useMemo(
7051
5562
  () => rows.map((d) => d.external_id).filter((id) => !!id),
7052
5563
  [rows]
7053
5564
  );
@@ -7059,8 +5570,8 @@ function DocumentGallery({
7059
5570
  const setViewingDocId = useArbiUiStore((s) => s.setViewingDocId);
7060
5571
  const effectiveSelected = selectedIds ?? storeSelected;
7061
5572
  const emitSelection = onSelectionChange ?? storeSetSelected;
7062
- const selectedSet = React2.useMemo(() => new Set(effectiveSelected), [effectiveSelected]);
7063
- const toggleSelected = React2.useCallback(
5573
+ const selectedSet = React.useMemo(() => new Set(effectiveSelected), [effectiveSelected]);
5574
+ const toggleSelected = React.useCallback(
7064
5575
  (id) => {
7065
5576
  const next = new Set(effectiveSelected);
7066
5577
  if (next.has(id)) next.delete(id);
@@ -7069,7 +5580,7 @@ function DocumentGallery({
7069
5580
  },
7070
5581
  [effectiveSelected, emitSelection]
7071
5582
  );
7072
- const openDocument = React2.useCallback(
5583
+ const openDocument = React.useCallback(
7073
5584
  (id) => {
7074
5585
  setViewingDocId(id);
7075
5586
  onOpenDocument?.(id);
@@ -7078,7 +5589,7 @@ function DocumentGallery({
7078
5589
  );
7079
5590
  const arbi = useArbi();
7080
5591
  const queryClient = useQueryClient();
7081
- const [renamingId, setRenamingId] = React2.useState(null);
5592
+ const [renamingId, setRenamingId] = React.useState(null);
7082
5593
  const rename = useMutation({
7083
5594
  mutationFn: ({ doc, title }) => arbi.documents.update([
7084
5595
  { external_id: doc.external_id, doc_metadata: { ...doc.doc_metadata, title } }
@@ -7703,6 +6214,6 @@ function hasVideoTrack(blob) {
7703
6214
  });
7704
6215
  }
7705
6216
 
7706
- export { ActivityFeed, AgentBadge, AiActionCard, AiAnswer, AppleIcon, ArbiBotHeadIcon, ArbiBotIcon, ArbiChat, ArbiChatPanel, ArbiIcon, ArbiWebSocketProvider, ArtifactCanvas, AudIcon, BASE_COLORS2 as BASE_COLORS, ChatBubble, CitationRenderer, ClaudeIcon, CommandPalette, CommandPaletteProvider, ConversationList, DEFAULT_ASPECT_OPTIONS, DEFAULT_NOTIFY_TONE, DateSeparator, DirectMessages, DmAvatar, DmComposer, DocIcon, DocQaPanel, DocSearch, DocumentCard, DocumentCardMenu, DocumentEntity, DocumentGallery, DocumentReview, DocumentTable, DraftTitleControls, ENTITY_MAPPINGS, EmlIcon, EntityIcon, EntityPill, FILE_TYPE_COLORS, FileIcon, FireworksIcon, GeminiIcon, GitHubIcon, GoogleIcon, HtmlIcon, ImageCropModal, ImageCropper, ImgIcon, LinkedInIcon, MessageArtifactCard, MessageBubble2 as MessageBubble, MessageThread, NEUTRAL_GRAY2 as NEUTRAL_GRAY, NotificationBell, OpenAIIcon, PLACEHOLDER_COLOR, PassageCard, PdfIcon, PhotoCapture, PresenceLabel, ProjectEntity, ProviderIcon, RUN_WINDOW_MS, RagDot, RelevanceDot, SemanticSearch, StatusPill, TAG_TYPE_ICONS, TAG_TYPE_LABELS, TagEntity, Toaster, TxtIcon, TypingIndicator, UserEntity, UserMenu, VISIBILITY_ICONS, VidIcon, VideoCapture, VisibilityIcon, VoiceNoteRecorder, XlsIcon, annotateThread, arbiQueryKeys, captureFrameAsBlob, configureEntityRegistry, configureRagLabels, configureStatusRegistry, cropImage, dayKey, describeActivity, formatRelativeTime, getDocIcon, getEntityColor2 as getEntityColor, getEntityColorStyles, getEntityIcon, getEntityLabel, getNotificationTypeMeta, getStatusVariant, getTagTypeIcon, getTagTypeLabel, getWorkspaceActionText, getWorkspaceColor, getWorkspaceSentPhrase, hasVideoTrack, isWorkspaceNotificationType, notify, parseActivityContent, redlineStats, seedNotifications, selectUnread, textToArtifact, toRedlineMarkdown, useActivity, useAgents, useAiTask, useArbiConnected, useArbiDocumentSync, useArbiUiStore, useArbiWebSocket, useArbiWsContext, useArbiWsMessage, useArbiWsStatus, useArbiWsStore, useArbiWsTask, useArbiWsTasks, useAssistantQuery, useCameraStream, useCommandPalette, useConfigs, useConversations, useDeleteAgents, useDirectMessages, useDocuments, useFacts, useHealth, useNotify, useParsedDocument, useProjectInvoices, useProjectUsage, useProjects, useProjectsUsage, useSemanticSearch, useSessions, useTags, useTasks, useThumbnails, useUserUsageToday, useVideoRecorder, useWorkspaceDocs, useWorkspaces, userDisplayName, userInitials };
6217
+ export { ActivityFeed, AiActionCard, AiAnswer, AppleIcon, ArbiBotIcon, ArbiChat, ArbiChatPanel, ArbiIcon, ArbiWebSocketProvider, ArtifactCanvas, ChatBubble, CitationRenderer, ClaudeIcon, CommandPalette, CommandPaletteProvider, ConversationList, DEFAULT_ASPECT_OPTIONS, DateSeparator, DirectMessages, DmAvatar, DmComposer, DocIcon, DocQaPanel, DocSearch, DocumentCard, DocumentCardMenu, DocumentGallery, DocumentReview, DocumentTable, DraftTitleControls, FileIcon, FireworksIcon, GeminiIcon, GitHubIcon, GoogleIcon, HtmlIcon, ImageCropModal, ImageCropper, LinkedInIcon, MessageArtifactCard, MessageBubble2 as MessageBubble, MessageThread, NotificationBell, OpenAIIcon, PassageCard, PhotoCapture, ProviderIcon, RUN_WINDOW_MS, RelevanceDot, SemanticSearch, TxtIcon, TypingIndicator, UserMenu, VideoCapture, VoiceNoteRecorder, XlsIcon, annotateThread, arbiQueryKeys, captureFrameAsBlob, cropImage, dayKey, describeActivity, formatRelativeTime, getNotificationTypeMeta, getWorkspaceActionText, getWorkspaceSentPhrase, hasVideoTrack, isWorkspaceNotificationType, parseActivityContent, redlineStats, textToArtifact, toRedlineMarkdown, useActivity, useAgents, useAiTask, useArbiConnected, useArbiDocumentSync, useArbiUiStore, useArbiWebSocket, useArbiWsContext, useArbiWsMessage, useArbiWsStatus, useArbiWsStore, useArbiWsTask, useArbiWsTasks, useAssistantQuery, useCameraStream, useCommandPalette, useConfigs, useConversations, useDeleteAgents, useDirectMessages, useDocuments, useFacts, useHealth, useParsedDocument, useProjectInvoices, useProjectUsage, useProjects, useProjectsUsage, useSemanticSearch, useSessions, useTags, useTasks, useThumbnails, useUserUsageToday, useVideoRecorder, useWorkspaceDocs, useWorkspaces, userDisplayName, userInitials };
7707
6218
  //# sourceMappingURL=index.js.map
7708
6219
  //# sourceMappingURL=index.js.map