@arbidocs/react 0.4.2 → 0.4.3

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.
@@ -1 +1 @@
1
- {"version":3,"sources":["../src/chat/styles.ts","../src/chat/AuthScreen.tsx","../src/hooks.ts","../src/chat/WorkspaceScreen.tsx","../src/chat/MessageBubble.tsx","../src/chat/ChatView.tsx","../src/chat/ChatWidget.tsx","../src/chat/ArbiChat.tsx","../src/chat/ChatBubble.tsx","../src/websocket/store.ts","../src/websocket/context.ts","../src/websocket/ArbiWebSocketProvider.tsx","../src/websocket/hooks.ts","../src/websocket/documentSync.ts","../src/ai/engine.ts","../src/ai/redline.ts","../src/ai/AiAnswer.tsx","../src/ai/AiActionCard.tsx","../src/ai/ArtifactCanvas.tsx","../src/ai/MessageArtifactCard.tsx","../src/ai/DocSearch.tsx","../src/documents/DocumentReview.tsx","../src/ai/SemanticSearch.tsx","../src/ai/DocQaPanel.tsx","../src/ai/CitationRenderer.tsx","../src/icons/DocIcon.tsx","../src/icons/HtmlIcon.tsx","../src/icons/TxtIcon.tsx","../src/icons/XlsIcon.tsx","../src/icons/FileIcon.tsx","../src/icons/AppleIcon.tsx","../src/icons/GoogleIcon.tsx","../src/icons/GitHubIcon.tsx","../src/icons/LinkedInIcon.tsx","../src/icons/OpenAIIcon.tsx","../src/icons/ClaudeIcon.tsx","../src/icons/GeminiIcon.tsx","../src/icons/FireworksIcon.tsx","../src/icons/ProviderIcon.tsx","../src/icons/ArbiIcon.tsx","../src/icons/ArbiBotIcon.tsx","../src/notifications/notification-types.ts","../src/notifications/activity-types.ts","../src/notifications/ActivityFeed.tsx","../src/directmessages/utils.ts","../src/directmessages/useDirectMessages.ts","../src/directmessages/DmAvatar.tsx","../src/directmessages/ConversationList.tsx","../src/directmessages/grouping.ts","../src/directmessages/DateSeparator.tsx","../src/directmessages/MessageBubble.tsx","../src/directmessages/MessageThread.tsx","../src/directmessages/DmComposer.tsx","../src/directmessages/DirectMessages.tsx","../src/imagecrop/ImageCropper.tsx","../src/imagecrop/cropImage.ts","../src/imagecrop/ImageCropModal.tsx","../src/command/CommandPalette.tsx","../src/command/commandPaletteContext.ts","../src/command/CommandPaletteProvider.tsx","../src/store.ts","../src/documents/DocumentTable.tsx","../src/documents/DocumentCardMenu.tsx","../src/documents/DocumentGallery.tsx","../src/documents/VoiceNoteRecorder.tsx","../src/documents/DraftTitleControls.tsx","../src/documents/useCameraStream.ts","../src/documents/useVideoRecorder.ts","../src/documents/capture-frame.ts","../src/documents/PhotoCapture.tsx","../src/documents/VideoCapture.tsx","../src/documents/has-video-track.ts"],"names":["useArbi","useState","jsxs","jsx","useQuery","useMutation","useQueries","useMemo","resolveCitations","summarizeCitations","MarkdownRenderer","useRef","useEffect","useCallback","Fragment","QueryClient","QueryClientProvider","ArbiProvider","memo","TypingIndicator","ChatBubble","cn","Link","Trash2","CheckCheck","Check","create","createContext","useContext","isMessageType","connectWithReconnect","useQueryClient","diffWords","Loader2","AlertTriangle","AiMarkdown","ShieldCheck","Copy","Sparkles","Card","Button","FileText","Badge","GitCompareArrows","Download","AnimatePresence","motion","ImageIcon","Search","CornerDownLeft","React","X","TagEntity","PassageCard","ArrowLeft","Input","Send","Tags","notify","useLayoutEffect","ReactMarkdown","createPortal","MarkMenu","FILE_TYPE_COLORS","Crown","useId","getEntityIcon","MessageCircleMore","UserCheck","PartyPopper","Gift","Gauge","Activity","Info","SquareArrowOutUpRight","FolderPlus","Pencil","FileX2","FileCheck2","UserEntity","getEntityColorStyles","AgentBadge","formatRelativeTime","MessageBubble","MessagesSquare","ScrollArea","Textarea","Cropper","Slider","Dialog","DialogContent","DialogHeader","DialogTitle","DialogFooter","ArrowRight","ModuleRegistry","AllCommunityModule","DocumentEntity","AgGridReact","DropdownMenu","DropdownMenuTrigger","MoreHorizontal","DropdownMenuContent","DropdownMenuItem","SquarePen","DropdownMenuSeparator","DocumentCard","useAudioRecorder","Mic","MicWaveformIndicator","Pause","Play","Square","AudioViewer","RotateCcw","IconToggle","classifyMediaError","Camera","ImageViewer","formatElapsed","Circle","VideoViewer"],"mappings":"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","file":"index.cjs","sourcesContent":["import type { CSSProperties } from 'react'\nimport type { ArbiChatLabels, ArbiChatTheme, ResolvedLabels, ResolvedTheme } from './types'\n\n/**\n * Default theme matching the ARBI frontend color palette.\n *\n * - Primary action color: ARBI cyan (#00adef)\n * - Message bubbles: light gray (user) / light cyan (assistant)\n * - Text/border: standard ARBI grays\n * - Border radius: 8px (ARBI default)\n */\nconst DEFAULT_THEME: ArbiChatTheme = {\n primaryColor: '#00adef',\n backgroundColor: '#ffffff',\n surfaceColor: '#f9fafb',\n textColor: '#111827',\n mutedColor: '#6b7280',\n borderColor: '#e5e7eb',\n userBubbleColor: '#f3f4f6',\n userBubbleTextColor: '#111827',\n assistantBubbleColor: 'rgba(0, 173, 239, 0.08)',\n assistantBubbleTextColor: '#111827',\n borderRadius: '8px',\n fontFamily:\n \"-apple-system, BlinkMacSystemFont, 'Segoe UI', Roboto, 'Helvetica Neue', Arial, sans-serif\",\n}\n\nconst DEFAULT_LABELS: ResolvedLabels = {\n title: 'Chat',\n email: 'Email',\n password: 'Password',\n loginButton: 'Log in',\n loginButtonLoading: 'Logging in...',\n registerButton: 'Create account',\n sendCodeButton: 'Email me a code',\n haveCodeButton: 'I have an invitation code',\n verificationCode: 'Verification code',\n confirmPassword: 'Confirm password',\n firstName: 'First name',\n lastName: 'Last name',\n switchToRegister: 'Create account',\n switchToLogin: 'Back to login',\n selectWorkspace: 'Select a workspace',\n workspacePlaceholder: 'Choose...',\n continueButton: 'Continue',\n createWorkspace: 'Create new workspace',\n workspaceName: 'Workspace name',\n createButton: 'Create',\n changeWorkspace: 'Change workspace',\n documents: 'Documents',\n sendButton: 'Send',\n placeholder: 'Ask a question...',\n uploadButton: 'Upload',\n uploading: 'Uploading...',\n emptyNoDocs: 'No documents found in this workspace.',\n emptyNoSelection: 'Select at least one document to start chatting.',\n emptyReady: 'Ask a question about your documents.',\n}\n\nexport function getTheme(partial?: Partial<ArbiChatTheme>): ResolvedTheme {\n return { ...DEFAULT_THEME, ...partial }\n}\n\nexport function getLabels(partial?: ArbiChatLabels): ResolvedLabels {\n return { ...DEFAULT_LABELS, ...partial }\n}\n\n// ── Container ────────────────────────────────────────────────────────────────\n\nexport function containerStyle(\n theme: ResolvedTheme,\n width: string | number,\n height: string | number\n): CSSProperties {\n return {\n width: typeof width === 'number' ? `${width}px` : width,\n height: typeof height === 'number' ? `${height}px` : height,\n display: 'flex',\n flexDirection: 'column',\n fontFamily: theme.fontFamily,\n fontSize: '14px',\n lineHeight: '1.5',\n color: theme.textColor,\n backgroundColor: theme.backgroundColor,\n border: `1px solid ${theme.borderColor}`,\n borderRadius: theme.borderRadius,\n overflow: 'hidden',\n boxSizing: 'border-box',\n }\n}\n\nexport function headerStyle(theme: ResolvedTheme): CSSProperties {\n return {\n display: 'flex',\n alignItems: 'center',\n padding: '12px 16px',\n fontWeight: 600,\n fontSize: '15px',\n borderBottom: `1px solid ${theme.borderColor}`,\n flexShrink: 0,\n }\n}\n\nexport function bodyStyle(): CSSProperties {\n return {\n flex: 1,\n display: 'flex',\n flexDirection: 'column',\n overflow: 'hidden',\n }\n}\n\n// ── Forms ────────────────────────────────────────────────────────────────────\n\nexport function formContainerStyle(): CSSProperties {\n return {\n flex: 1,\n display: 'flex',\n flexDirection: 'column',\n justifyContent: 'center',\n padding: '24px 16px',\n gap: '12px',\n }\n}\n\nexport function labelStyle(theme: ResolvedTheme): CSSProperties {\n return {\n fontSize: '13px',\n fontWeight: 500,\n color: theme.textColor,\n marginBottom: '4px',\n }\n}\n\nexport function inputStyle(theme: ResolvedTheme): CSSProperties {\n return {\n width: '100%',\n padding: '8px 12px',\n fontSize: '14px',\n fontFamily: theme.fontFamily,\n color: theme.textColor,\n backgroundColor: theme.backgroundColor,\n border: `1px solid ${theme.borderColor}`,\n borderRadius: '8px',\n outline: 'none',\n boxSizing: 'border-box',\n }\n}\n\nexport function selectStyle(theme: ResolvedTheme): CSSProperties {\n return {\n ...inputStyle(theme),\n cursor: 'pointer',\n appearance: 'auto' as CSSProperties['appearance'],\n }\n}\n\nexport function buttonStyle(theme: ResolvedTheme, disabled?: boolean): CSSProperties {\n return {\n padding: '8px 16px',\n fontSize: '14px',\n fontWeight: 500,\n fontFamily: theme.fontFamily,\n color: '#ffffff',\n backgroundColor: disabled ? theme.mutedColor : theme.primaryColor,\n border: 'none',\n borderRadius: '8px',\n cursor: disabled ? 'not-allowed' : 'pointer',\n opacity: disabled ? 0.6 : 1,\n transition: 'opacity 150ms',\n }\n}\n\nexport function errorStyle(): CSSProperties {\n return {\n fontSize: '13px',\n color: '#ef4444',\n margin: '4px 0 0',\n }\n}\n\n// ── Chat view ────────────────────────────────────────────────────────────────\n\nexport function messagesContainerStyle(): CSSProperties {\n return {\n flex: 1,\n overflowY: 'auto',\n padding: '12px 16px',\n display: 'flex',\n flexDirection: 'column',\n gap: '8px',\n }\n}\n\nexport function messageBubbleStyle(\n theme: ResolvedTheme,\n role: 'user' | 'assistant'\n): CSSProperties {\n const isUser = role === 'user'\n return {\n maxWidth: '85%',\n padding: '8px 12px',\n borderRadius: '12px',\n fontSize: '14px',\n lineHeight: '1.5',\n wordBreak: 'break-word',\n whiteSpace: 'pre-wrap',\n alignSelf: isUser ? 'flex-end' : 'flex-start',\n backgroundColor: isUser ? theme.userBubbleColor : theme.assistantBubbleColor,\n color: isUser ? theme.userBubbleTextColor : theme.assistantBubbleTextColor,\n }\n}\n\nexport function inputBarStyle(theme: ResolvedTheme): CSSProperties {\n return {\n display: 'flex',\n gap: '8px',\n padding: '12px 16px',\n borderTop: `1px solid ${theme.borderColor}`,\n flexShrink: 0,\n }\n}\n\nexport function chatInputStyle(theme: ResolvedTheme): CSSProperties {\n return {\n ...inputStyle(theme),\n flex: 1,\n }\n}\n\nexport function sendButtonStyle(theme: ResolvedTheme, disabled?: boolean): CSSProperties {\n return {\n ...buttonStyle(theme, disabled),\n padding: '8px 14px',\n flexShrink: 0,\n }\n}\n\n// ── Document selector ────────────────────────────────────────────────────────\n\nexport function docSelectorStyle(theme: ResolvedTheme): CSSProperties {\n return {\n padding: '8px 16px',\n borderBottom: `1px solid ${theme.borderColor}`,\n flexShrink: 0,\n }\n}\n\nexport function docToggleStyle(theme: ResolvedTheme): CSSProperties {\n return {\n display: 'flex',\n alignItems: 'center',\n gap: '6px',\n fontSize: '13px',\n fontWeight: 500,\n color: theme.mutedColor,\n cursor: 'pointer',\n background: 'none',\n border: 'none',\n padding: 0,\n fontFamily: theme.fontFamily,\n }\n}\n\nexport function docListStyle(): CSSProperties {\n return {\n marginTop: '6px',\n display: 'flex',\n flexDirection: 'column',\n gap: '4px',\n maxHeight: '120px',\n overflowY: 'auto',\n }\n}\n\nexport function docItemStyle(theme: ResolvedTheme): CSSProperties {\n return {\n display: 'flex',\n alignItems: 'center',\n gap: '6px',\n fontSize: '13px',\n color: theme.textColor,\n cursor: 'pointer',\n textAlign: 'left',\n }\n}\n\nexport function emptyStateStyle(theme: ResolvedTheme): CSSProperties {\n return {\n flex: 1,\n display: 'flex',\n alignItems: 'center',\n justifyContent: 'center',\n color: theme.mutedColor,\n fontSize: '13px',\n padding: '24px',\n textAlign: 'center',\n }\n}\n\nexport function loadingContainerStyle(): CSSProperties {\n return {\n flex: 1,\n display: 'flex',\n alignItems: 'center',\n justifyContent: 'center',\n gap: '8px',\n fontSize: '13px',\n }\n}\n\nexport function brandingStyle(theme: ResolvedTheme): CSSProperties {\n return {\n display: 'flex',\n alignItems: 'center',\n justifyContent: 'center',\n gap: '4px',\n padding: '6px 16px',\n fontSize: '11px',\n color: theme.mutedColor,\n borderTop: `1px solid ${theme.borderColor}`,\n flexShrink: 0,\n userSelect: 'none',\n }\n}\n\nexport function brandingLinkStyle(theme: ResolvedTheme): CSSProperties {\n return {\n color: theme.mutedColor,\n fontWeight: 600,\n textDecoration: 'none',\n }\n}\n\n// ── Auth / Workspace creation ─────────────────────────────────────────────────\n\nexport function linkButtonStyle(theme: ResolvedTheme): CSSProperties {\n return {\n background: 'none',\n border: 'none',\n padding: 0,\n fontSize: '13px',\n color: theme.primaryColor,\n cursor: 'pointer',\n fontFamily: theme.fontFamily,\n textDecoration: 'underline',\n }\n}\n\nexport function secondaryButtonStyle(theme: ResolvedTheme, disabled?: boolean): CSSProperties {\n return {\n padding: '4px 10px',\n fontSize: '12px',\n fontWeight: 500,\n fontFamily: theme.fontFamily,\n color: disabled ? theme.mutedColor : theme.primaryColor,\n backgroundColor: 'transparent',\n border: `1px solid ${disabled ? theme.borderColor : theme.primaryColor}`,\n borderRadius: '6px',\n cursor: disabled ? 'not-allowed' : 'pointer',\n opacity: disabled ? 0.6 : 1,\n transition: 'opacity 150ms',\n whiteSpace: 'nowrap',\n }\n}\n\nexport function fileInputStyle(): CSSProperties {\n return { display: 'none' }\n}\n\nexport function agentStatusStyle(theme: ResolvedTheme): CSSProperties {\n return {\n fontSize: '12px',\n color: theme.mutedColor,\n fontStyle: 'italic',\n padding: '4px 0',\n alignSelf: 'flex-start',\n }\n}\n","import { useState, type FormEvent } from 'react'\nimport { useArbi } from '../useArbi'\nimport type { ResolvedLabels, ResolvedTheme } from './types'\nimport {\n formContainerStyle,\n labelStyle,\n inputStyle,\n buttonStyle,\n errorStyle,\n linkButtonStyle,\n} from './styles'\n\ninterface AuthScreenProps {\n theme: ResolvedTheme\n labels: ResolvedLabels\n onLogin: () => void\n}\n\ntype AuthMode = 'login' | 'register'\ntype RegisterStep = 'email' | 'verify'\n\nexport function AuthScreen({ theme, labels, onLogin }: AuthScreenProps) {\n const arbi = useArbi()\n const [mode, setMode] = useState<AuthMode>('login')\n const [step, setStep] = useState<RegisterStep>('email')\n\n const [email, setEmail] = useState('')\n const [password, setPassword] = useState('')\n const [confirmPw, setConfirmPw] = useState('')\n const [code, setCode] = useState('')\n const [firstName, setFirstName] = useState('')\n const [lastName, setLastName] = useState('')\n const [loading, setLoading] = useState(false)\n const [error, setError] = useState('')\n\n const resetForm = () => {\n setPassword('')\n setConfirmPw('')\n setCode('')\n setFirstName('')\n setLastName('')\n setError('')\n setStep('email')\n }\n\n const switchMode = (next: AuthMode) => {\n resetForm()\n setMode(next)\n }\n\n // ── Login ─────────────────────────────────────────────────────────────────\n\n const handleLogin = async (e: FormEvent) => {\n e.preventDefault()\n setLoading(true)\n setError('')\n try {\n await arbi.login(email, password)\n onLogin()\n } catch (err) {\n setError(err instanceof Error ? err.message : 'Login failed')\n } finally {\n setLoading(false)\n }\n }\n\n // ── Register: skip straight to verify (user already has a code) ────────────\n\n const handleHaveCode = () => {\n setError('')\n setStep('verify')\n }\n\n // ── Register: send code via email then go to verify ───────────────────────\n\n const handleEmailCode = async () => {\n if (!email) return\n setLoading(true)\n setError('')\n try {\n await arbi.requestVerification(email)\n setStep('verify')\n } catch (err) {\n setError(err instanceof Error ? err.message : 'Failed to send verification code')\n } finally {\n setLoading(false)\n }\n }\n\n // ── Register step 2: create account ───────────────────────────────────────\n\n const handleRegister = async (e: FormEvent) => {\n e.preventDefault()\n if (password !== confirmPw) {\n setError('Passwords do not match')\n return\n }\n setLoading(true)\n setError('')\n try {\n await arbi.register({ email, password, verificationCode: code, firstName, lastName })\n await arbi.login(email, password)\n onLogin()\n } catch (err) {\n setError(err instanceof Error ? err.message : 'Registration failed')\n } finally {\n setLoading(false)\n }\n }\n\n // ── Login form ────────────────────────────────────────────────────────────\n\n if (mode === 'login') {\n return (\n <form onSubmit={handleLogin} style={formContainerStyle()}>\n <div>\n <div style={labelStyle(theme)}>{labels.email}</div>\n <input\n type=\"email\"\n value={email}\n onChange={(e) => setEmail(e.target.value)}\n placeholder=\"you@example.com\"\n autoComplete=\"email\"\n required\n style={inputStyle(theme)}\n />\n </div>\n <div>\n <div style={labelStyle(theme)}>{labels.password}</div>\n <input\n type=\"password\"\n value={password}\n onChange={(e) => setPassword(e.target.value)}\n autoComplete=\"current-password\"\n required\n style={inputStyle(theme)}\n />\n </div>\n <button type=\"submit\" disabled={loading} style={buttonStyle(theme, loading)}>\n {loading ? labels.loginButtonLoading : labels.loginButton}\n </button>\n {error && <div style={errorStyle()}>{error}</div>}\n <div style={{ textAlign: 'center' }}>\n <button\n type=\"button\"\n onClick={() => switchMode('register')}\n style={linkButtonStyle(theme)}\n >\n {labels.switchToRegister}\n </button>\n </div>\n </form>\n )\n }\n\n // ── Register step 1: email + choose code method ────────────────────────────\n\n if (step === 'email') {\n const noEmail = !email.trim()\n return (\n <div style={formContainerStyle()}>\n <div>\n <div style={labelStyle(theme)}>{labels.email}</div>\n <input\n type=\"email\"\n value={email}\n onChange={(e) => setEmail(e.target.value)}\n placeholder=\"you@example.com\"\n autoComplete=\"email\"\n style={inputStyle(theme)}\n />\n </div>\n <div style={{ display: 'flex', gap: '8px' }}>\n <button\n type=\"button\"\n onClick={handleHaveCode}\n disabled={noEmail}\n style={{ ...buttonStyle(theme, noEmail), flex: 1 }}\n >\n {labels.haveCodeButton}\n </button>\n <button\n type=\"button\"\n onClick={handleEmailCode}\n disabled={noEmail || loading}\n style={{ ...buttonStyle(theme, noEmail || loading), flex: 1 }}\n >\n {loading ? '...' : labels.sendCodeButton}\n </button>\n </div>\n {error && <div style={errorStyle()}>{error}</div>}\n <div style={{ textAlign: 'center' }}>\n <button type=\"button\" onClick={() => switchMode('login')} style={linkButtonStyle(theme)}>\n {labels.switchToLogin}\n </button>\n </div>\n </div>\n )\n }\n\n // ── Register step 2: verify + create account ─────────────────────────────\n\n return (\n <form onSubmit={handleRegister} style={formContainerStyle()}>\n <div style={{ display: 'flex', gap: '8px' }}>\n <div style={{ flex: 1 }}>\n <div style={labelStyle(theme)}>{labels.firstName}</div>\n <input\n type=\"text\"\n value={firstName}\n onChange={(e) => setFirstName(e.target.value)}\n autoComplete=\"given-name\"\n required\n style={inputStyle(theme)}\n />\n </div>\n <div style={{ flex: 1 }}>\n <div style={labelStyle(theme)}>{labels.lastName}</div>\n <input\n type=\"text\"\n value={lastName}\n onChange={(e) => setLastName(e.target.value)}\n autoComplete=\"family-name\"\n required\n style={inputStyle(theme)}\n />\n </div>\n </div>\n <div>\n <div style={labelStyle(theme)}>{labels.verificationCode}</div>\n <input\n type=\"text\"\n value={code}\n onChange={(e) => setCode(e.target.value)}\n autoComplete=\"one-time-code\"\n required\n style={inputStyle(theme)}\n />\n </div>\n <div>\n <div style={labelStyle(theme)}>{labels.password}</div>\n <input\n type=\"password\"\n value={password}\n onChange={(e) => setPassword(e.target.value)}\n autoComplete=\"new-password\"\n required\n style={inputStyle(theme)}\n />\n </div>\n <div>\n <div style={labelStyle(theme)}>{labels.confirmPassword}</div>\n <input\n type=\"password\"\n value={confirmPw}\n onChange={(e) => setConfirmPw(e.target.value)}\n autoComplete=\"new-password\"\n required\n style={inputStyle(theme)}\n />\n </div>\n <button type=\"submit\" disabled={loading} style={buttonStyle(theme, loading)}>\n {loading ? '...' : labels.registerButton}\n </button>\n {error && <div style={errorStyle()}>{error}</div>}\n <div style={{ textAlign: 'center' }}>\n <button type=\"button\" onClick={() => switchMode('login')} style={linkButtonStyle(theme)}>\n {labels.switchToLogin}\n </button>\n </div>\n </form>\n )\n}\n","/**\n * React Query hooks that use the Arbi instance from context.\n */\n\nimport { useMemo } from 'react'\nimport { useQuery, useQueries, useMutation } from '@tanstack/react-query'\nimport type {\n SSEStreamResult,\n SSEStreamStartData,\n ResponseOutputItemDoneEvent,\n ArtifactEvent,\n} from '@arbidocs/sdk/browser'\nimport { useArbi } from './useArbi'\nimport type { ParsedDocument } from './documents/parsed-types'\n\n// ── Query keys ──────────────────────────────────────────────────────────────\n\nexport const arbiQueryKeys = {\n workspaces: () => ['arbi', 'workspaces'] as const,\n documents: (workspaceId: string) => ['arbi', 'documents', workspaceId] as const,\n conversations: (workspaceId: string) => ['arbi', 'conversations', workspaceId] as const,\n tags: (workspaceId: string) => ['arbi', 'tags', workspaceId] as const,\n thumbnails: (docIds: string[]) => ['arbi', 'thumbnails', [...docIds].sort().join(',')] as const,\n parsedDoc: (docId: string, stage: string) => ['arbi', 'parsedDoc', docId, stage] as const,\n agents: () => ['arbi', 'agents'] as const,\n sessions: () => ['arbi', 'sessions'] as const,\n health: () => ['arbi', 'health'] as const,\n tasks: () => ['arbi', 'tasks'] as const,\n facts: (workspaceId: string) => ['arbi', 'facts', workspaceId] as const,\n configs: () => ['arbi', 'configs'] as const,\n activity: () => ['arbi', 'activity'] as const,\n projects: () => ['arbi', 'projects'] as const,\n projectUsage: (projectExtId: string, monthsBack: number) =>\n ['arbi', 'projectUsage', projectExtId, monthsBack] as const,\n projectInvoices: (projectExtId: string) => ['arbi', 'projectInvoices', projectExtId] as const,\n userUsageToday: () => ['arbi', 'userUsageToday'] as const,\n}\n\n// ── Hooks ───────────────────────────────────────────────────────────────────\n\n/** List the logged-in user's workspaces. */\nexport function useWorkspaces(options?: { enabled?: boolean }) {\n const arbi = useArbi()\n return useQuery({\n queryKey: arbiQueryKeys.workspaces(),\n queryFn: () => arbi.workspaces.list(),\n enabled: options?.enabled ?? arbi.isLoggedIn,\n })\n}\n\n/** List documents in a workspace. */\nexport function useDocuments(workspaceId: string | undefined, options?: { enabled?: boolean }) {\n const arbi = useArbi()\n return useQuery({\n queryKey: arbiQueryKeys.documents(workspaceId ?? ''),\n queryFn: () => arbi.documents.list(),\n enabled: (options?.enabled ?? true) && !!workspaceId && arbi.hasWorkspace,\n })\n}\n\n/** List conversations in a workspace. */\nexport function useConversations(workspaceId: string | undefined, options?: { enabled?: boolean }) {\n const arbi = useArbi()\n return useQuery({\n queryKey: arbiQueryKeys.conversations(workspaceId ?? ''),\n queryFn: () => arbi.conversations.list(),\n enabled: (options?.enabled ?? true) && !!workspaceId && arbi.hasWorkspace,\n })\n}\n\n/** List tags in a workspace. */\nexport function useTags(workspaceId: string | undefined, options?: { enabled?: boolean }) {\n const arbi = useArbi()\n return useQuery({\n queryKey: arbiQueryKeys.tags(workspaceId ?? ''),\n queryFn: () => arbi.tags.list(),\n enabled: (options?.enabled ?? true) && !!workspaceId && arbi.hasWorkspace,\n })\n}\n\n/**\n * Batch-fetch first-page thumbnails for a set of documents. Returns a map of\n * doc external id → `data:image/webp` URI (or `null` when no thumbnail exists).\n * Cached for a few minutes since thumbnails are effectively immutable per doc.\n */\nexport function useThumbnails(docIds: string[], options?: { enabled?: boolean }) {\n const arbi = useArbi()\n return useQuery({\n queryKey: arbiQueryKeys.thumbnails(docIds),\n queryFn: () => arbi.documents.getThumbnails(docIds),\n enabled: (options?.enabled ?? true) && docIds.length > 0 && arbi.hasWorkspace,\n staleTime: 5 * 60_000,\n })\n}\n\n/**\n * Fetch a document's parsed content (chunks grouped by page) for the review\n * viewer. `stage` defaults to `final` (fully processed); `marker`/`subchunk`\n * expose earlier pipeline stages.\n */\nexport function useParsedDocument(\n docId: string | undefined,\n stage: string = 'final',\n options?: { enabled?: boolean }\n) {\n const arbi = useArbi()\n return useQuery({\n queryKey: arbiQueryKeys.parsedDoc(docId ?? '', stage),\n queryFn: () =>\n arbi.documents.getParsedContent(docId as string, stage) as unknown as Promise<ParsedDocument>,\n enabled: (options?.enabled ?? true) && !!docId && arbi.hasWorkspace,\n })\n}\n\n/** Send a streaming query to the RAG assistant. Returns a mutation. */\nexport function useAssistantQuery() {\n const arbi = useArbi()\n\n return useMutation<\n SSEStreamResult,\n Error,\n {\n question: string\n docIds: string[]\n previousResponseId?: string | null\n model?: string\n onToken?: (content: string) => void\n onStreamStart?: (data: SSEStreamStartData) => void\n onOutputItemDone?: (data: ResponseOutputItemDoneEvent) => void\n onArtifact?: (data: ArtifactEvent) => void\n onError?: (message: string) => void\n onComplete?: () => void\n }\n >({\n mutationFn: ({ question, ...options }) => arbi.assistant.query(question, options),\n })\n}\n\n/** List agents owned by the current user. */\nexport function useAgents(options?: { enabled?: boolean }) {\n const arbi = useArbi()\n return useQuery({\n queryKey: arbiQueryKeys.agents(),\n queryFn: () => arbi.agents.list(),\n enabled: options?.enabled ?? arbi.isLoggedIn,\n })\n}\n\n/** Delete agents. Returns a mutation. */\nexport function useDeleteAgents() {\n const arbi = useArbi()\n return useMutation<unknown, Error, { agentExtIds: string[] }>({\n mutationFn: ({ agentExtIds }) => arbi.agents.delete(agentExtIds),\n })\n}\n\n/** List active sessions. */\nexport function useSessions(options?: { enabled?: boolean }) {\n const arbi = useArbi()\n return useQuery({\n queryKey: arbiQueryKeys.sessions(),\n queryFn: () => arbi.sessions.list(),\n enabled: options?.enabled ?? arbi.isLoggedIn,\n })\n}\n\n/** Authorize a delegated session (generates claim code). Returns a mutation. */\n\n/** Check backend health. */\nexport function useHealth(options?: { enabled?: boolean }) {\n const arbi = useArbi()\n return useQuery({\n queryKey: arbiQueryKeys.health(),\n queryFn: () => arbi.health.check(),\n enabled: options?.enabled,\n })\n}\n\n// ── Scheduled tasks ──────────────────────────────────────────────────────────\n\n/** List the caller's scheduled agent tasks. */\nexport function useTasks(options?: { enabled?: boolean }) {\n const arbi = useArbi()\n return useQuery({\n queryKey: arbiQueryKeys.tasks(),\n queryFn: () => arbi.tasks.list(),\n enabled: options?.enabled ?? arbi.isLoggedIn,\n })\n}\n\n// ── Workspace notes ──────────────────────────────────────────────────────────\n\n/** List the open workspace's facts. */\nexport function useFacts(\n workspaceId: string | undefined,\n options?: { enabled?: boolean; pinnedOnly?: boolean }\n) {\n const arbi = useArbi()\n return useQuery({\n queryKey: arbiQueryKeys.facts(workspaceId ?? ''),\n queryFn: () => arbi.facts.list({ pinnedOnly: options?.pinnedOnly }),\n enabled: (options?.enabled ?? true) && !!workspaceId && arbi.hasWorkspace,\n })\n}\n\n// ── Behaviour-template configs ───────────────────────────────────────────────\n\n/** List the caller's saved agent configurations (behaviour templates). */\nexport function useConfigs(options?: { enabled?: boolean }) {\n const arbi = useArbi()\n return useQuery({\n queryKey: arbiQueryKeys.configs(),\n queryFn: () => arbi.agentConfig.list(),\n enabled: options?.enabled ?? arbi.isLoggedIn,\n })\n}\n\n// ── Activity feed ─────────────────────────────────────────────────────────────\n\n/**\n * List the caller's durable activity feed, newest first.\n *\n * Activity entries are backend-originated, to-self log lines that are always\n * read — they are deliberately kept out of the normal notifications/DM feed and\n * never affect the unread badge, so this is a separate, opt-in query.\n */\nexport function useActivity(options?: { enabled?: boolean; limit?: number; offset?: number }) {\n const arbi = useArbi()\n return useQuery({\n queryKey: arbiQueryKeys.activity(),\n queryFn: () => arbi.dm.listActivity({ limit: options?.limit, offset: options?.offset }),\n enabled: options?.enabled ?? arbi.isLoggedIn,\n })\n}\n\n// ── Projects, usage & spend ───────────────────────────────────────────────────\n\n/** List the logged-in user's projects (billing accounts). */\nexport function useProjects(options?: { enabled?: boolean }) {\n const arbi = useArbi()\n return useQuery({\n queryKey: arbiQueryKeys.projects(),\n queryFn: () => arbi.projects.list(),\n enabled: options?.enabled ?? arbi.isLoggedIn,\n })\n}\n\n/**\n * AI usage + spend breakdown for a project's billing period. `monthsBack`\n * selects the period (0 = current, 1 = previous month, …).\n */\nexport function useProjectUsage(\n projectExtId: string | undefined,\n monthsBack: number = 0,\n options?: { enabled?: boolean }\n) {\n const arbi = useArbi()\n return useQuery({\n queryKey: arbiQueryKeys.projectUsage(projectExtId ?? '', monthsBack),\n queryFn: () => arbi.projects.usage(projectExtId as string, monthsBack),\n enabled: (options?.enabled ?? true) && !!projectExtId && arbi.isLoggedIn,\n })\n}\n\n/** One day of aggregated usage across projects (for a spend/token trend). */\nexport interface AggregatedDailyUsage {\n date: string\n spend: number\n totalTokens: number\n apiRequests: number\n}\n\n/** One model group's aggregated usage across projects (for a breakdown). */\nexport interface AggregatedModelGroupUsage {\n model: string\n spend: number\n totalTokens: number\n promptTokens: number\n completionTokens: number\n successfulRequests: number\n}\n\n/** Aggregated AI usage + spend across several projects. */\nexport interface ProjectsUsageAggregate {\n /** Summed spend across the projects, in USD (the metered currency). */\n totalSpend: number\n /** Summed token count across the projects. */\n totalTokens: number\n /** Summed API request count across the projects. */\n totalRequests: number\n /** Per-day totals merged across every project, oldest first. */\n daily: AggregatedDailyUsage[]\n /** Per-model-group totals merged across every project, biggest spend first. */\n modelGroups: AggregatedModelGroupUsage[]\n /** True while any per-project query is still loading. */\n isLoading: boolean\n /** True if any per-project query errored. */\n isError: boolean\n}\n\n/**\n * Firm-wide AI usage + spend: aggregates {@link useProjectUsage} across several\n * projects (e.g. all of a firm's matters) in parallel and merges the real totals,\n * the daily trend, and the per-model breakdown. Shares the per-project query\n * cache, so it costs nothing extra where a project's usage is already loaded.\n * Numbers are genuine — zero projects (or zero billed work) yields zero totals;\n * callers render that honestly.\n */\nexport function useProjectsUsage(\n projectExtIds: string[],\n monthsBack: number = 0,\n options?: { enabled?: boolean }\n): ProjectsUsageAggregate {\n const arbi = useArbi()\n const enabled = (options?.enabled ?? true) && arbi.isLoggedIn\n const results = useQueries({\n queries: projectExtIds.map((id) => ({\n queryKey: arbiQueryKeys.projectUsage(id, monthsBack),\n queryFn: () => arbi.projects.usage(id, monthsBack),\n enabled: enabled && !!id,\n })),\n })\n\n // Recompute only when a query's data actually changes (not on every parent\n // render — the dashboard re-renders often while a digest streams).\n const signature = results.map((r) => `${r.status}:${r.dataUpdatedAt ?? 0}`).join('|')\n\n return useMemo(() => {\n const dailyMap = new Map<string, AggregatedDailyUsage>()\n const modelMap = new Map<string, AggregatedModelGroupUsage>()\n let totalSpend = 0\n let totalTokens = 0\n let totalRequests = 0\n\n for (const r of results) {\n const d = r.data\n if (!d) continue\n totalSpend += d.total_spend ?? 0\n totalTokens += d.total_tokens ?? 0\n totalRequests += d.total_requests ?? 0\n\n for (const day of d.daily ?? []) {\n const cur = dailyMap.get(day.date) ?? {\n date: day.date,\n spend: 0,\n totalTokens: 0,\n apiRequests: 0,\n }\n cur.spend += day.spend ?? 0\n cur.totalTokens += day.total_tokens ?? 0\n cur.apiRequests += day.api_requests ?? 0\n dailyMap.set(day.date, cur)\n }\n\n for (const [model, mg] of Object.entries(d.model_groups ?? {})) {\n const cur = modelMap.get(model) ?? {\n model,\n spend: 0,\n totalTokens: 0,\n promptTokens: 0,\n completionTokens: 0,\n successfulRequests: 0,\n }\n cur.spend += mg.spend ?? 0\n cur.totalTokens += mg.total_tokens ?? 0\n cur.promptTokens += mg.prompt_tokens ?? 0\n cur.completionTokens += mg.completion_tokens ?? 0\n cur.successfulRequests += mg.successful_requests ?? 0\n modelMap.set(model, cur)\n }\n }\n\n return {\n totalSpend,\n totalTokens,\n totalRequests,\n daily: [...dailyMap.values()].sort((a, b) => a.date.localeCompare(b.date)),\n modelGroups: [...modelMap.values()].sort(\n (a, b) => b.spend - a.spend || b.totalTokens - a.totalTokens\n ),\n isLoading: results.some((r) => r.isLoading),\n isError: results.some((r) => r.isError),\n }\n }, [signature])\n}\n\n/** List the Stripe invoices for a project's subscription. */\nexport function useProjectInvoices(\n projectExtId: string | undefined,\n options?: { enabled?: boolean }\n) {\n const arbi = useArbi()\n return useQuery({\n queryKey: arbiQueryKeys.projectInvoices(projectExtId ?? ''),\n queryFn: () => arbi.projects.invoices(projectExtId as string),\n enabled: (options?.enabled ?? true) && !!projectExtId && arbi.isLoggedIn,\n })\n}\n\n/** Today's deployment-wide credit spend for the current user. */\nexport function useUserUsageToday(options?: { enabled?: boolean }) {\n const arbi = useArbi()\n return useQuery({\n queryKey: arbiQueryKeys.userUsageToday(),\n queryFn: () => arbi.user.usageToday(),\n enabled: options?.enabled ?? arbi.isLoggedIn,\n })\n}\n","import { useState } from 'react'\nimport { useArbi } from '../useArbi'\nimport { useWorkspaces } from '../hooks'\nimport type { ResolvedLabels, ResolvedTheme } from './types'\nimport {\n formContainerStyle,\n labelStyle,\n inputStyle,\n selectStyle,\n buttonStyle,\n errorStyle,\n loadingContainerStyle,\n linkButtonStyle,\n} from './styles'\n\ninterface WorkspaceScreenProps {\n theme: ResolvedTheme\n labels: ResolvedLabels\n onSelect: (workspaceId: string) => void\n}\n\ntype ScreenMode = 'select' | 'create'\n\nexport function WorkspaceScreen({ theme, labels, onSelect }: WorkspaceScreenProps) {\n const arbi = useArbi()\n const { data: workspaces, isLoading } = useWorkspaces()\n\n const [mode, setMode] = useState<ScreenMode>('select')\n const [selected, setSelected] = useState('')\n const [newName, setNewName] = useState('')\n const [loading, setLoading] = useState(false)\n const [error, setError] = useState('')\n\n if (isLoading) {\n return <div style={loadingContainerStyle()}>Loading workspaces...</div>\n }\n\n // ── Select existing workspace ─────────────────────────────────────────────\n\n const handleConfirm = async () => {\n if (!selected) return\n setLoading(true)\n setError('')\n try {\n await arbi.selectWorkspace(selected)\n onSelect(selected)\n } catch (err) {\n setError(err instanceof Error ? err.message : 'Failed to select workspace')\n } finally {\n setLoading(false)\n }\n }\n\n // ── Create new workspace ──────────────────────────────────────────────────\n\n const handleCreate = async () => {\n const name = newName.trim()\n if (!name) return\n setLoading(true)\n setError('')\n try {\n // Workspaces now belong to a project — the SDK call requires a\n // ``projectExtId``. We don't surface project selection in this\n // minimal embedded picker, so default to the user's first project\n // (typically the auto-provisioned personal one). If there are\n // none, fail loudly rather than silently picking nothing — a\n // brand-new account without a project is a setup-flow bug, not\n // something this widget should paper over.\n const projects = await arbi.projects.list()\n const projectExtId = projects[0]?.external_id\n if (!projectExtId) {\n throw new Error('No project available; create one before adding a workspace')\n }\n const ws = await arbi.workspaces.create(name, projectExtId)\n await arbi.selectWorkspace(ws.external_id)\n onSelect(ws.external_id)\n } catch (err) {\n setError(err instanceof Error ? err.message : 'Failed to create workspace')\n } finally {\n setLoading(false)\n }\n }\n\n if (mode === 'create') {\n return (\n <div style={formContainerStyle()}>\n <div>\n <div style={labelStyle(theme)}>{labels.workspaceName}</div>\n <input\n type=\"text\"\n value={newName}\n onChange={(e) => setNewName(e.target.value)}\n disabled={loading}\n style={inputStyle(theme)}\n />\n </div>\n <button\n type=\"button\"\n onClick={handleCreate}\n disabled={!newName.trim() || loading}\n style={buttonStyle(theme, !newName.trim() || loading)}\n >\n {loading ? '...' : labels.createButton}\n </button>\n {error && <div style={errorStyle()}>{error}</div>}\n <div style={{ textAlign: 'center' }}>\n <button\n type=\"button\"\n onClick={() => {\n setError('')\n setMode('select')\n }}\n style={linkButtonStyle(theme)}\n >\n or select existing\n </button>\n </div>\n </div>\n )\n }\n\n return (\n <div style={formContainerStyle()}>\n <div>\n <div style={labelStyle(theme)}>{labels.selectWorkspace}</div>\n <select\n value={selected}\n onChange={(e) => setSelected(e.target.value)}\n disabled={loading}\n style={selectStyle(theme)}\n >\n <option value=\"\" disabled>\n {labels.workspacePlaceholder}\n </option>\n {workspaces?.map((ws) => (\n <option key={ws.external_id} value={ws.external_id}>\n {ws.name}\n </option>\n ))}\n </select>\n </div>\n <button\n type=\"button\"\n onClick={handleConfirm}\n disabled={!selected || loading}\n style={buttonStyle(theme, !selected || loading)}\n >\n {loading ? 'Connecting...' : labels.continueButton}\n </button>\n {error && <div style={errorStyle()}>{error}</div>}\n <div style={{ textAlign: 'center' }}>\n <button\n type=\"button\"\n onClick={() => {\n setError('')\n setMode('create')\n }}\n style={linkButtonStyle(theme)}\n >\n {labels.createWorkspace}\n </button>\n </div>\n </div>\n )\n}\n","import { useMemo, useState, type CSSProperties } from 'react'\nimport type { Components } from 'react-markdown'\nimport { resolveCitations, summarizeCitations } from '@arbidocs/sdk/browser'\nimport { MarkdownRenderer } from '../ai/MarkdownRenderer'\nimport type { ChatMessage, ResolvedTheme } from './types'\nimport { messageBubbleStyle } from './styles'\n\ninterface MessageBubbleProps {\n message: ChatMessage\n theme: ResolvedTheme\n}\n\nconst CITE_RE = /\\[([^\\]]+)\\]\\(#cite-(\\d+)\\)/g\n\nexport function MessageBubble({ message, theme }: MessageBubbleProps) {\n const [expandedCite, setExpandedCite] = useState<string | null>(null)\n\n const hasCitations =\n message.role === 'assistant' && message.metadata && CITE_RE.test(message.text)\n\n // Reset regex lastIndex after test\n CITE_RE.lastIndex = 0\n\n const resolved = hasCitations\n ? resolveCitations(message.metadata as Parameters<typeof resolveCitations>[0])\n : []\n const summaries = hasCitations ? summarizeCitations(resolved) : []\n const summaryMap = new Map(summaries.map((s) => [s.citationNum, s]))\n\n const activeSummary = expandedCite ? summaryMap.get(expandedCite) : null\n const activeResolved = expandedCite ? resolved.find((r) => r.citationNum === expandedCite) : null\n\n // Render the message as markdown; intercept `[statement](#cite-N)` link markers\n // and turn them into the clickable citation superscript (the rest of the text\n // renders as normal markdown — bold, lists, tables, code, etc.).\n const markdownComponents = useMemo<Partial<Components>>(\n () => ({\n a: ({ href, children, ...props }) => {\n if (href?.startsWith('#cite-')) {\n const num = href.slice('#cite-'.length)\n return (\n <span>\n {children}\n <sup\n onClick={(e) => {\n e.stopPropagation()\n setExpandedCite((prev) => (prev === num ? null : num))\n }}\n style={citeSupStyle(theme)}\n title={`Citation ${num}`}\n >\n {num}\n </sup>\n </span>\n )\n }\n return (\n <a\n href={href}\n target=\"_blank\"\n rel=\"noopener noreferrer\"\n style={{ color: theme.primaryColor }}\n {...props}\n >\n {children}\n </a>\n )\n },\n }),\n [theme]\n )\n\n return (\n <div>\n <div style={messageBubbleStyle(theme, message.role)}>\n <MarkdownRenderer components={markdownComponents}>{message.text}</MarkdownRenderer>\n </div>\n {activeSummary && activeResolved && (\n <div style={citePanelStyle(theme)}>\n <div style={citePanelHeaderStyle(theme)}>\n <strong>[{activeSummary.citationNum}]</strong> {activeSummary.docTitle}\n {activeSummary.pageNumber != null && (\n <span style={{ color: theme.mutedColor }}> p.{activeSummary.pageNumber}</span>\n )}\n </div>\n {activeResolved.chunks.map((chunk, i) => (\n <div key={i} style={citeChunkStyle(theme)}>\n {chunk.content}\n </div>\n ))}\n </div>\n )}\n </div>\n )\n}\n\n// ── Inline styles ───────────────────────────────────────────────────────────\n\nfunction citeSupStyle(theme: ResolvedTheme): CSSProperties {\n return {\n display: 'inline-flex',\n alignItems: 'center',\n justifyContent: 'center',\n fontSize: '10px',\n fontWeight: 600,\n color: theme.primaryColor,\n cursor: 'pointer',\n marginLeft: '1px',\n minWidth: '14px',\n lineHeight: 1,\n }\n}\n\nfunction citePanelStyle(theme: ResolvedTheme): CSSProperties {\n return {\n marginTop: '4px',\n padding: '8px 10px',\n fontSize: '12px',\n lineHeight: '1.5',\n backgroundColor: theme.surfaceColor,\n border: `1px solid ${theme.borderColor}`,\n borderRadius: '8px',\n maxWidth: '85%',\n }\n}\n\nfunction citePanelHeaderStyle(theme: ResolvedTheme): CSSProperties {\n return {\n fontSize: '12px',\n fontWeight: 500,\n color: theme.textColor,\n marginBottom: '4px',\n }\n}\n\nfunction citeChunkStyle(theme: ResolvedTheme): CSSProperties {\n return {\n fontSize: '11px',\n color: theme.mutedColor,\n borderLeft: `2px solid ${theme.borderColor}`,\n paddingLeft: '8px',\n marginTop: '4px',\n whiteSpace: 'pre-wrap',\n wordBreak: 'break-word',\n }\n}\n","import { useState, useRef, useEffect, useCallback, type FormEvent, type ChangeEvent } from 'react'\nimport { useArbi } from '../useArbi'\nimport { useDocuments, useAssistantQuery } from '../hooks'\nimport type { ChatMessage, ResolvedLabels, ResolvedTheme } from './types'\nimport { MessageBubble } from './MessageBubble'\nimport {\n messagesContainerStyle,\n inputBarStyle,\n chatInputStyle,\n sendButtonStyle,\n docSelectorStyle,\n docToggleStyle,\n docListStyle,\n docItemStyle,\n emptyStateStyle,\n secondaryButtonStyle,\n fileInputStyle,\n agentStatusStyle,\n} from './styles'\n\ninterface ChatViewProps {\n workspaceId: string\n theme: ResolvedTheme\n labels: ResolvedLabels\n}\n\nexport function ChatView({ workspaceId, theme, labels }: ChatViewProps) {\n const arbi = useArbi()\n const { data: docs, refetch: refetchDocs } = useDocuments(workspaceId)\n const mutation = useAssistantQuery()\n\n const [messages, setMessages] = useState<ChatMessage[]>([])\n const [input, setInput] = useState('')\n const [streaming, setStreaming] = useState('')\n const [agentStatus, setAgentStatus] = useState('')\n const [selectedDocs, setSelectedDocs] = useState<string[]>([])\n const [docsExpanded, setDocsExpanded] = useState(false)\n const [previousResponseId, setPreviousResponseId] = useState<string | null>(null)\n const [uploading, setUploading] = useState(false)\n\n const messagesEndRef = useRef<HTMLDivElement>(null)\n const fileInputRef = useRef<HTMLInputElement>(null)\n\n // Auto-select all docs when they first load\n useEffect(() => {\n if (docs && docs.length > 0 && selectedDocs.length === 0) {\n setSelectedDocs(docs.map((d) => d.external_id))\n }\n }, [docs, selectedDocs.length])\n\n // Auto-scroll to bottom\n useEffect(() => {\n messagesEndRef.current?.scrollIntoView({ behavior: 'smooth' })\n }, [messages, streaming, agentStatus])\n\n const toggleDoc = (docId: string) => {\n setSelectedDocs((prev) =>\n prev.includes(docId) ? prev.filter((id) => id !== docId) : [...prev, docId]\n )\n }\n\n const handleUpload = useCallback(\n async (e: ChangeEvent<HTMLInputElement>) => {\n const files = e.target.files\n if (!files || files.length === 0) return\n setUploading(true)\n try {\n const newIds: string[] = []\n for (const file of Array.from(files)) {\n const result = await arbi.documents.uploadFile(file, file.name)\n // ``doc_ext_ids`` is optional on ``UploadResult`` — the server\n // omits it when the upload returned only skipped/duplicate\n // entries. Nothing to push in that case.\n if (result.doc_ext_ids) newIds.push(...result.doc_ext_ids)\n }\n await refetchDocs()\n setSelectedDocs((prev) => [...prev, ...newIds])\n } catch {\n // Upload errors are silently ignored — the user sees the doc list unchanged\n } finally {\n setUploading(false)\n // Reset file input so the same file can be re-selected\n if (fileInputRef.current) fileInputRef.current.value = ''\n }\n },\n [arbi, refetchDocs]\n )\n\n const handleSubmit = useCallback(\n (e: FormEvent) => {\n e.preventDefault()\n const question = input.trim()\n if (!question || selectedDocs.length === 0 || mutation.isPending) return\n\n setMessages((prev) => [...prev, { role: 'user', text: question }])\n setInput('')\n setStreaming('')\n setAgentStatus('')\n\n mutation.mutate(\n {\n question,\n docIds: selectedDocs,\n previousResponseId,\n onToken: (t) => setStreaming((prev) => prev + t),\n onOutputItemDone: (ev) => {\n const item = ev.item as { type?: string; arbi?: { label?: string; focus?: string } }\n if (item.type === 'function_call' || item.type === 'reasoning') {\n setAgentStatus(item.arbi?.focus || item.arbi?.label || '')\n }\n },\n },\n {\n onSuccess: (result) => {\n setStreaming('')\n setAgentStatus('')\n setMessages((prev) => [\n ...prev,\n { role: 'assistant', text: result.text, metadata: result.metadata },\n ])\n setPreviousResponseId(result.assistantMessageExtId)\n },\n onError: (err) => {\n setStreaming('')\n setAgentStatus('')\n setMessages((prev) => [...prev, { role: 'assistant', text: `Error: ${err.message}` }])\n },\n }\n )\n },\n [input, selectedDocs, previousResponseId, mutation]\n )\n\n const noDocs = !docs || docs.length === 0\n const noDocsSelected = selectedDocs.length === 0\n\n return (\n <>\n {/* Hidden file input (shared across upload buttons) */}\n <input\n ref={fileInputRef}\n type=\"file\"\n multiple\n accept=\".pdf,.txt,.md,.html,.doc,.docx,.rtf,.ppt,.pptx,.xls,.xlsx\"\n onChange={handleUpload}\n style={fileInputStyle()}\n />\n\n {/* Document selector — always visible so users can upload */}\n <div style={docSelectorStyle(theme)}>\n <div style={{ display: 'flex', alignItems: 'center', justifyContent: 'space-between' }}>\n <button\n type=\"button\"\n onClick={() => setDocsExpanded((prev) => !prev)}\n style={docToggleStyle(theme)}\n >\n <span style={{ fontSize: '10px' }}>{docsExpanded ? '\\u25BC' : '\\u25B6'}</span>\n {labels.documents} ({selectedDocs.length}/{docs?.length ?? 0} in chat)\n </button>\n <button\n type=\"button\"\n onClick={() => fileInputRef.current?.click()}\n disabled={uploading}\n style={secondaryButtonStyle(theme, uploading)}\n >\n {uploading ? labels.uploading : labels.uploadButton}\n </button>\n </div>\n {docsExpanded && docs && docs.length > 0 && (\n <div style={docListStyle()}>\n {docs.map((doc) => (\n <label key={doc.external_id} style={docItemStyle(theme)}>\n <input\n type=\"checkbox\"\n checked={selectedDocs.includes(doc.external_id)}\n onChange={() => toggleDoc(doc.external_id)}\n />\n {doc.file_name}\n </label>\n ))}\n </div>\n )}\n </div>\n\n {/* Messages */}\n <div style={messagesContainerStyle()}>\n {messages.length === 0 && !streaming && (\n <div style={emptyStateStyle(theme)}>\n {noDocs\n ? labels.emptyNoDocs\n : noDocsSelected\n ? labels.emptyNoSelection\n : labels.emptyReady}\n </div>\n )}\n {messages.map((msg, i) => (\n <MessageBubble key={i} message={msg} theme={theme} />\n ))}\n {agentStatus && !streaming && <div style={agentStatusStyle(theme)}>{agentStatus}...</div>}\n {streaming && (\n <MessageBubble message={{ role: 'assistant', text: streaming }} theme={theme} />\n )}\n <div ref={messagesEndRef} />\n </div>\n\n {/* Input bar */}\n <form onSubmit={handleSubmit} style={inputBarStyle(theme)}>\n <input\n type=\"text\"\n value={input}\n onChange={(e) => setInput(e.target.value)}\n placeholder={noDocs || noDocsSelected ? 'Select documents first...' : labels.placeholder}\n disabled={noDocs || noDocsSelected || mutation.isPending}\n style={chatInputStyle(theme)}\n />\n <button\n type=\"submit\"\n disabled={!input.trim() || noDocsSelected || mutation.isPending}\n style={sendButtonStyle(theme, !input.trim() || noDocsSelected || mutation.isPending)}\n >\n {mutation.isPending ? '...' : labels.sendButton}\n </button>\n </form>\n </>\n )\n}\n","import { useState, useCallback, useEffect } from 'react'\nimport { useArbi } from '../useArbi'\nimport type { ResolvedLabels, ResolvedTheme, WidgetScreen } from './types'\nimport { AuthScreen } from './AuthScreen'\nimport { WorkspaceScreen } from './WorkspaceScreen'\nimport { ChatView } from './ChatView'\nimport {\n containerStyle,\n headerStyle,\n bodyStyle,\n brandingStyle,\n brandingLinkStyle,\n linkButtonStyle,\n} from './styles'\n\ninterface ChatWidgetProps {\n theme: ResolvedTheme\n labels: ResolvedLabels\n initialWorkspaceId?: string\n width: string | number\n height: string | number\n}\n\nexport function ChatWidget({ theme, labels, initialWorkspaceId, width, height }: ChatWidgetProps) {\n const arbi = useArbi()\n const [screen, setScreen] = useState<WidgetScreen>('auth')\n const [workspaceId, setWorkspaceId] = useState<string | undefined>(initialWorkspaceId)\n\n // After authentication (or when resuming an ambient session), open the\n // provided workspace and jump to chat — or fall back to the picker.\n const resolveWorkspace = useCallback(async () => {\n if (initialWorkspaceId) {\n try {\n await arbi.selectWorkspace(initialWorkspaceId)\n setScreen('chat')\n return\n } catch {\n // Fall back to workspace selection if the provided ID fails\n setScreen('workspace')\n return\n }\n }\n setScreen('workspace')\n }, [arbi, initialWorkspaceId])\n\n const handleLogin = useCallback(() => resolveWorkspace(), [resolveWorkspace])\n\n // When embedded in a host app that already authenticated the ambient\n // ArbiProvider (e.g. <ArbiChatPanel> inside a signed-in dashboard), skip the\n // login screen and resume that session — no second login required.\n useEffect(() => {\n if (arbi.isLoggedIn) void resolveWorkspace()\n }, [arbi, resolveWorkspace])\n\n const handleWorkspaceSelect = useCallback((id: string) => {\n setWorkspaceId(id)\n setScreen('chat')\n }, [])\n\n const handleChangeWorkspace = useCallback(() => {\n setScreen('workspace')\n }, [])\n\n return (\n <div style={containerStyle(theme, width, height)}>\n <div style={{ ...headerStyle(theme), justifyContent: 'space-between' }}>\n <span>{labels.title}</span>\n {screen === 'chat' && !initialWorkspaceId && (\n <button type=\"button\" onClick={handleChangeWorkspace} style={linkButtonStyle(theme)}>\n {labels.changeWorkspace}\n </button>\n )}\n </div>\n\n <div style={bodyStyle()}>\n {screen === 'auth' && <AuthScreen theme={theme} labels={labels} onLogin={handleLogin} />}\n {screen === 'workspace' && (\n <WorkspaceScreen theme={theme} labels={labels} onSelect={handleWorkspaceSelect} />\n )}\n {screen === 'chat' && workspaceId && (\n <ChatView workspaceId={workspaceId} theme={theme} labels={labels} />\n )}\n </div>\n\n <div style={brandingStyle(theme)}>\n Powered by{' '}\n <a\n href=\"https://www.arbidocs.com\"\n target=\"_blank\"\n rel=\"noopener noreferrer\"\n style={brandingLinkStyle(theme)}\n >\n ARBI\n </a>\n </div>\n </div>\n )\n}\n","import { useMemo } from 'react'\nimport { QueryClient, QueryClientProvider } from '@tanstack/react-query'\nimport { ArbiProvider } from '../ArbiProvider'\nimport type { ArbiChatLabels, ArbiChatProps, ArbiChatTheme } from './types'\nimport { getLabels, getTheme } from './styles'\nimport { ChatWidget } from './ChatWidget'\n\nexport type { ArbiChatProps, ArbiChatTheme, ArbiChatLabels }\n\n/** Props for {@link ArbiChatPanel} — the provider-less embeddable panel. */\nexport interface ArbiChatPanelProps {\n /** Skip workspace selection — go straight to chat */\n workspaceId?: string\n /** Customize colors and appearance */\n theme?: Partial<ArbiChatTheme>\n /** Customize text labels */\n labels?: ArbiChatLabels\n /** Widget width (default: '100%') */\n width?: string | number\n /** Widget height (default: '100%') */\n height?: string | number\n}\n\n/**\n * The ARBI chat panel **without** its own providers.\n *\n * Drop it inside an app that already renders `<ArbiProvider>` and a\n * `<QueryClientProvider>` to reuse the host's authenticated session — no second\n * login. When the ambient session is already signed in, the panel skips the\n * login screen and opens straight into chat.\n *\n * ```tsx\n * // inside your authenticated app tree\n * <ArbiChatPanel workspaceId=\"wrk-…\" theme={myTheme} />\n * ```\n *\n * For a fully self-contained widget (its own providers + login), use {@link ArbiChat}.\n */\nexport function ArbiChatPanel({\n workspaceId,\n theme: themeOverrides,\n labels: labelOverrides,\n width = '100%',\n height = '100%',\n}: ArbiChatPanelProps) {\n const theme = useMemo(() => getTheme(themeOverrides), [themeOverrides])\n const labels = useMemo(() => getLabels(labelOverrides), [labelOverrides])\n\n return (\n <ChatWidget\n theme={theme}\n labels={labels}\n initialWorkspaceId={workspaceId}\n width={width}\n height={height}\n />\n )\n}\n\n/**\n * Self-contained ARBI chat widget.\n *\n * Wraps its own QueryClientProvider and ArbiProvider so it works\n * anywhere — no setup required from the host app.\n *\n * ```tsx\n * import { ArbiChat } from '@arbidocs/react'\n *\n * <ArbiChat url=\"https://www.arbidocs.com\" />\n * ```\n */\nexport function ArbiChat({\n url,\n workspaceId,\n theme: themeOverrides,\n labels: labelOverrides,\n width = '400px',\n height = '600px',\n}: ArbiChatProps) {\n const queryClient = useMemo(\n () =>\n new QueryClient({\n defaultOptions: {\n queries: { retry: 1, refetchOnWindowFocus: false },\n mutations: { retry: false },\n },\n }),\n []\n )\n\n return (\n <QueryClientProvider client={queryClient}>\n <ArbiProvider url={url}>\n <ArbiChatPanel\n workspaceId={workspaceId}\n theme={themeOverrides}\n labels={labelOverrides}\n width={width}\n height={height}\n />\n </ArbiProvider>\n </QueryClientProvider>\n )\n}\n","/**\n * Chat Bubble Component\n * iMessage / WhatsApp-style message bubble with read receipts and\n * consecutive-message grouping.\n *\n * Promoted from the ARBI app. To keep `@arbidocs/react` light (peers react /\n * react-dom only), the two host-owned concerns — rendering the message body\n * (the app's heavy markdown renderer) and formatting the timestamp — are\n * injected via the optional `renderMessage` / `formatTimestamp` props. Both\n * default to plain text so the component works standalone; the ARBI app shim\n * wires in `<MarkdownRenderer>` and `formatFriendlyDate` for identical output.\n */\n\nimport { memo, useState, type ReactNode } from 'react'\nimport { Trash2, Check, CheckCheck, Link } from 'lucide-react'\nimport { cn } from '../lib/utils'\n\n/** Animated typing indicator (three bouncing dots) */\nexport const TypingIndicator = memo(function TypingIndicator() {\n return (\n <div className=\"flex w-full justify-start mb-2\" data-testid=\"dm-typing-indicator\">\n <div className=\"bg-card border border-primary rounded-2xl rounded-bl-md px-4 py-2.5\">\n <div className=\"flex gap-1 items-center\">\n <span className=\"w-1.5 h-1.5 rounded-full bg-muted-foreground animate-bounce [animation-delay:0ms]\" />\n <span className=\"w-1.5 h-1.5 rounded-full bg-muted-foreground animate-bounce [animation-delay:150ms]\" />\n <span className=\"w-1.5 h-1.5 rounded-full bg-muted-foreground animate-bounce [animation-delay:300ms]\" />\n </div>\n </div>\n </div>\n )\n})\n\nexport interface ChatBubbleProps {\n message: string\n timestamp: string\n isSent: boolean\n deleted?: boolean\n read?: boolean\n onDelete?: () => void\n /**\n * Copy a shareable deep link to this exact message. Optional — the host\n * builds the URL (it knows the workspace/deployment domain, the light\n * package doesn't), this just renders the affordance and calls back.\n */\n onCopyLink?: () => void\n /** Stable DOM anchor for scroll-to-message (a notification deep link, a\n * \"jump to this message\" action). Typically the message's external id. */\n id?: string\n /** Brief highlight flash — set true right after scrolling into view. */\n highlighted?: boolean\n /** Last bubble in a same-sender run; shows the timestamp and read receipt. */\n isLastOfRun?: boolean\n /**\n * Who sent it. Rendered in the meta row on the last bubble of a run, so a\n * thread that needs attribution (a group, or a rail-less list where the peer\n * isn't in a header) gets it without a row per message.\n */\n senderName?: string\n /** Per-slot brand overrides, so a consumer pins its accent in one place. */\n classNames?: {\n /** The current user's own bubble. */\n ownBubble?: string\n /** The peer's bubble. */\n peerBubble?: string\n }\n /**\n * Render the message body. Injected by the host so the light package doesn't\n * depend on the app's markdown renderer. Defaults to plain text.\n */\n renderMessage?: (message: string) => ReactNode\n /**\n * Format the timestamp shown on the last bubble of a run. Defaults to the\n * raw string.\n */\n formatTimestamp?: (timestamp: string) => string\n /** Marks the message row, including the deleted tombstone. */\n 'data-testid'?: string\n}\n\nexport const ChatBubble = memo(function ChatBubble({\n message,\n timestamp,\n isSent,\n deleted,\n read,\n onDelete,\n onCopyLink,\n id,\n highlighted,\n isLastOfRun = true,\n senderName,\n classNames,\n renderMessage = (m) => m,\n formatTimestamp = (t) => t,\n 'data-testid': testId,\n}: ChatBubbleProps) {\n const [isHovered, setIsHovered] = useState(false)\n const [isFocused, setIsFocused] = useState(false)\n const showActions = isHovered || isFocused\n\n // No \"edited\" indicator: `updated_at` is also bumped by read-state\n // patches, so we can't tell a real content edit from a recipient\n // marking the message as read. The created_at timestamp is the only\n // honest signal we can show here.\n\n if (deleted) {\n return (\n <div\n id={id}\n data-testid={testId}\n className={`flex w-full ${isSent ? 'justify-end' : 'justify-start'} mb-2`}\n >\n <div className=\"text-sm text-muted-foreground italic px-3 py-1\">Message deleted</div>\n </div>\n )\n }\n\n // WhatsApp-style radius: round corners; the side facing the sender gets a\n // smaller corner on the *last* bubble of a run to read as a chat tail.\n const bubbleRadius = cn(\n 'rounded-2xl',\n isSent && isLastOfRun && 'rounded-br-sm',\n !isSent && isLastOfRun && 'rounded-bl-sm'\n )\n\n // Own messages sit on a soft brand tint rather than full `primary`: a\n // saturated block per message shouts on a long thread, and a light surface\n // means markdown needs no colour inversion.\n //\n // The tint is `ai-accent-soft`, NOT `accent`. Plenty of themes set `accent`\n // equal to `muted` and a hair off `background` — ARBI's differ by 3% — so an\n // accent bubble there is invisible against the thread. `ai-accent-soft` is\n // part of the AI-accent contract every consuming app defines explicitly, so\n // it is a tint by construction.\n const bubbleSurface = isSent\n ? cn('bg-ai-accent-soft text-foreground chat-bubble-sent', classNames?.ownBubble)\n : cn('border border-border bg-card text-card-foreground', classNames?.peerBubble)\n\n // Same treatment useScrollBehavior gives a URL-driven deep link to a\n // conversation message: a brief tinted flash, not a persistent style.\n const highlightClass = highlighted && 'ring-2 ring-blue-400 dark:ring-blue-600'\n\n const copyLinkButton = onCopyLink && (\n <button\n onClick={onCopyLink}\n onFocus={() => setIsFocused(true)}\n onBlur={() => setIsFocused(false)}\n className={cn(\n 'self-end p-1 transition-opacity focus:outline-none focus-visible:ring-1 focus-visible:ring-ring rounded',\n showActions ? 'opacity-100 text-foreground' : 'opacity-0 text-muted-foreground'\n )}\n aria-label=\"Copy link to this message\"\n >\n <Link className=\"w-3.5 h-3.5\" />\n </button>\n )\n\n return (\n <div\n id={id}\n data-testid={testId}\n className={cn(\n 'flex w-full items-end',\n isLastOfRun ? 'mb-2' : 'mb-0.5',\n isSent ? 'justify-end' : 'justify-start'\n )}\n onMouseEnter={() => setIsHovered(true)}\n onMouseLeave={() => setIsHovered(false)}\n >\n {/* Sent messages: copy-link + delete on the left */}\n {isSent && (copyLinkButton || onDelete) && (\n <div className=\"flex items-center gap-0.5 mr-1\">\n {copyLinkButton}\n {onDelete && (\n <button\n onClick={onDelete}\n onFocus={() => setIsFocused(true)}\n onBlur={() => setIsFocused(false)}\n className={cn(\n 'self-end p-1 transition-opacity focus:outline-none focus-visible:ring-1 focus-visible:ring-ring rounded',\n showActions ? 'opacity-100 text-destructive' : 'opacity-0 text-muted-foreground'\n )}\n aria-label=\"Delete message\"\n >\n <Trash2 className=\"w-3.5 h-3.5\" />\n </button>\n )}\n </div>\n )}\n\n <div className=\"flex flex-col max-w-[80%] md:max-w-[60%]\">\n <div\n className={cn(\n 'px-3.5 py-2 break-words shadow-sm transition-shadow',\n bubbleRadius,\n bubbleSurface,\n highlightClass\n )}\n >\n <div className=\"text-sm [&_.markdown-content]:space-y-1.5 [&_pre]:max-w-full [&_pre]:overflow-x-auto\">\n {renderMessage(message)}\n </div>\n\n {/* Sender + timestamp + read receipt, only on the last bubble of the\n run — a meta row per message is noise in a 1:1 thread. */}\n {isLastOfRun && (\n <div\n className={cn(\n 'flex items-center gap-1.5 mt-0.5',\n isSent ? 'justify-end' : 'justify-start'\n )}\n >\n {senderName && (\n <span className=\"text-xs font-medium leading-none opacity-90\">{senderName}</span>\n )}\n <span className=\"text-xs leading-none opacity-70\">{formatTimestamp(timestamp)}</span>\n {isSent &&\n (read ? (\n <CheckCheck className=\"w-3.5 h-3.5 flex-shrink-0 opacity-80\" />\n ) : (\n <Check className=\"w-3.5 h-3.5 flex-shrink-0 opacity-60\" />\n ))}\n </div>\n )}\n </div>\n </div>\n\n {/* Received messages: delete + copy-link on the right */}\n {!isSent && (onDelete || copyLinkButton) && (\n <div className=\"flex items-center gap-0.5 ml-1\">\n {onDelete && (\n <button\n onClick={onDelete}\n onFocus={() => setIsFocused(true)}\n onBlur={() => setIsFocused(false)}\n className={cn(\n 'self-end p-1 transition-opacity focus:outline-none focus-visible:ring-1 focus-visible:ring-ring rounded',\n showActions ? 'opacity-100 text-destructive' : 'opacity-0 text-muted-foreground'\n )}\n aria-label=\"Delete message\"\n >\n <Trash2 className=\"w-3.5 h-3.5\" />\n </button>\n )}\n {copyLinkButton}\n </div>\n )}\n </div>\n )\n})\n","/**\n * Canonical WebSocket state, shared across apps.\n *\n * This mirrors the ARBI app's `webSocketSlice` but lives in the SDK so every\n * consumer (the ARBI frontend, clarum, any firm app) gets the *same* rich\n * real-time state from one implementation. The provider feeds it; components\n * read it with the selector hooks in `./hooks`.\n */\n\nimport { create } from 'zustand'\nimport type { WsTaskUpdateMessage, WsPresenceUpdateMessage } from '@arbidocs/client'\n\nexport type ArbiWsStatus = 'disconnected' | 'connecting' | 'connected' | 'reconnecting'\n\nexport interface ArbiWsState {\n /** Live connection status of the shared socket. */\n status: ArbiWsStatus\n /** Latest processing status per document id (the `task_update` stream). */\n tasks: Record<string, WsTaskUpdateMessage>\n /** The most recent `task_update` — a convenient single-value change trigger. */\n lastTaskUpdate: WsTaskUpdateMessage | null\n /** Online status keyed by user id (the `presence_update` stream). */\n presence: Record<string, string>\n setStatus: (status: ArbiWsStatus) => void\n applyTaskUpdate: (msg: WsTaskUpdateMessage) => void\n applyPresence: (msg: WsPresenceUpdateMessage) => void\n reset: () => void\n}\n\nexport const useArbiWsStore = create<ArbiWsState>((set) => ({\n status: 'disconnected',\n tasks: {},\n lastTaskUpdate: null,\n presence: {},\n setStatus: (status) => set({ status }),\n applyTaskUpdate: (msg) =>\n set((s) => ({ tasks: { ...s.tasks, [msg.doc_ext_id]: msg }, lastTaskUpdate: msg })),\n applyPresence: (msg) => set((s) => ({ presence: { ...s.presence, [msg.user_id]: msg.status } })),\n reset: () => set({ status: 'disconnected', tasks: {}, lastTaskUpdate: null, presence: {} }),\n}))\n","/**\n * Context for the shared WebSocket — the subscribe registry the provider fills\n * and the hooks read. Kept separate from the provider component so both can be\n * imported without tripping react-refresh's component-only-export rule.\n */\n\nimport { createContext, useContext } from 'react'\nimport type { WebSocketServerMessage } from '@arbidocs/client'\n\nexport type ArbiWsSubscriber = (msg: WebSocketServerMessage) => void\n\nexport interface ArbiWsContextValue {\n subscribe: (fn: ArbiWsSubscriber) => () => void\n}\n\nexport const ArbiWsContext = createContext<ArbiWsContextValue | null>(null)\n\nexport function useArbiWsContext(): ArbiWsContextValue {\n const ctx = useContext(ArbiWsContext)\n if (!ctx) {\n throw new Error('useArbiWebSocket hooks must be used within an <ArbiWebSocketProvider>')\n }\n return ctx\n}\n","/**\n * ArbiWebSocketProvider — one shared, reconnecting WebSocket for the whole app.\n *\n * Opens a single authenticated socket (via the SDK transport's\n * `connectWithReconnect`, which handles auth, backoff, and live-token refresh),\n * feeds the canonical WS store, and fans every typed message out to subscribers\n * registered by the `useArbiWebSocket` / `useArbiWsMessage` hooks.\n *\n * Mount it inside an `<ArbiProvider>` (it reads the Arbi instance for the base\n * URL + live access token). Gate it with `enabled` so it connects only once the\n * app is authenticated against a live backend.\n */\n\nimport { useEffect, useMemo, useRef, type ReactNode } from 'react'\nimport { connectWithReconnect, type ReconnectableWsConnection } from '@arbidocs/sdk/browser'\nimport {\n isMessageType,\n type WebSocketServerMessage,\n type WsTaskUpdateMessage,\n type WsPresenceUpdateMessage,\n} from '@arbidocs/client'\nimport { useArbi } from '../useArbi'\nimport { useArbiWsStore } from './store'\nimport { ArbiWsContext, type ArbiWsContextValue, type ArbiWsSubscriber } from './context'\n\nexport interface ArbiWebSocketProviderProps {\n /**\n * Open the socket only when the app is authenticated against a live backend.\n * Defaults to `true`; pass the connection status so demo/logged-out sessions\n * don't try to connect.\n */\n enabled?: boolean\n children: ReactNode\n}\n\nexport function ArbiWebSocketProvider({ enabled = true, children }: ArbiWebSocketProviderProps) {\n const arbi = useArbi()\n const subscribersRef = useRef<Set<ArbiWsSubscriber>>(new Set())\n const setStatus = useArbiWsStore((s) => s.setStatus)\n const applyTaskUpdate = useArbiWsStore((s) => s.applyTaskUpdate)\n const applyPresence = useArbiWsStore((s) => s.applyPresence)\n const reset = useArbiWsStore((s) => s.reset)\n\n // Stable subscribe API — the subscriber set lives in a ref, so registering a\n // handler never re-opens the socket.\n const context = useMemo<ArbiWsContextValue>(\n () => ({\n subscribe: (fn) => {\n subscribersRef.current.add(fn)\n return () => {\n subscribersRef.current.delete(fn)\n }\n },\n }),\n []\n )\n\n useEffect(() => {\n if (!enabled) {\n reset()\n return\n }\n\n let conn: ReconnectableWsConnection | null = null\n let cancelled = false\n\n const onMessage = (msg: WebSocketServerMessage) => {\n // Canonical store updates (the same shape the ARBI app maintains).\n if (isMessageType<WsTaskUpdateMessage>(msg, 'task_update')) applyTaskUpdate(msg)\n else if (isMessageType<WsPresenceUpdateMessage>(msg, 'presence_update')) applyPresence(msg)\n\n // Fan out to app subscribers. A throwing subscriber must not kill the stream.\n for (const fn of subscribersRef.current) {\n try {\n fn(msg)\n } catch {\n /* swallow — one bad handler can't break the socket */\n }\n }\n }\n\n const start = async () => {\n const info = arbi.getConnectionInfo()\n if (!info) return // not authenticated yet; the effect re-runs when `enabled` flips\n setStatus('connecting')\n try {\n const c = await connectWithReconnect({\n baseUrl: info.baseUrl,\n accessToken: info.accessToken,\n // Resolve the freshest token on every (re)connect so rotation is picked up.\n getAccessToken: () => arbi.getConnectionInfo()?.accessToken ?? null,\n onMessage,\n onReconnecting: () => setStatus('reconnecting'),\n onReconnected: () => setStatus('connected'),\n onClose: () => {\n if (!cancelled) setStatus('reconnecting')\n },\n })\n if (cancelled) {\n c.close()\n return\n }\n conn = c\n setStatus('connected')\n } catch {\n setStatus('disconnected')\n }\n }\n void start()\n\n return () => {\n cancelled = true\n conn?.close()\n reset()\n }\n }, [enabled, arbi, setStatus, applyTaskUpdate, applyPresence, reset])\n\n return <ArbiWsContext.Provider value={context}>{children}</ArbiWsContext.Provider>\n}\n","/**\n * Typed subscription + selector hooks for the shared WebSocket.\n *\n * All message typing flows from the OpenAPI-derived `WebSocketServerMessage`\n * union — handlers are narrowed by the discriminant `type`, exactly like the\n * rest of the SDK.\n */\n\nimport { useEffect, useRef } from 'react'\nimport { isMessageType, type WebSocketServerMessage } from '@arbidocs/client'\nimport { useArbiWsContext } from './context'\nimport { useArbiWsStore, type ArbiWsStatus } from './store'\n\n/**\n * Subscribe to every server message. The handler is kept in a ref, so passing a\n * new inline function each render does not resubscribe.\n */\nexport function useArbiWebSocket(onMessage: (msg: WebSocketServerMessage) => void): void {\n const { subscribe } = useArbiWsContext()\n const handlerRef = useRef(onMessage)\n handlerRef.current = onMessage\n useEffect(() => subscribe((msg) => handlerRef.current(msg)), [subscribe])\n}\n\n/**\n * Subscribe to a single message type, fully narrowed to that variant.\n *\n * @example\n * useArbiWsMessage<WsBatchCompleteMessage>('batch_complete', (msg) => {\n * // msg.batch_type, msg.doc_ext_ids are typed\n * })\n */\nexport function useArbiWsMessage<T extends WebSocketServerMessage>(\n type: T['type'],\n handler: (msg: T) => void\n): void {\n const { subscribe } = useArbiWsContext()\n const handlerRef = useRef(handler)\n handlerRef.current = handler\n useEffect(\n () =>\n subscribe((msg) => {\n if (isMessageType<T>(msg, type)) handlerRef.current(msg)\n }),\n [subscribe, type]\n )\n}\n\n/** Live connection status of the shared socket. */\nexport function useArbiWsStatus(): ArbiWsStatus {\n return useArbiWsStore((s) => s.status)\n}\n\n/** `true` once the shared socket is authenticated and connected. */\nexport function useArbiConnected(): boolean {\n return useArbiWsStore((s) => s.status === 'connected')\n}\n\n/** The latest processing status per document id (the `task_update` stream). */\nexport function useArbiWsTasks() {\n return useArbiWsStore((s) => s.tasks)\n}\n\n/** The latest processing status for a single document, if any. */\nexport function useArbiWsTask(docId: string) {\n return useArbiWsStore((s) => s.tasks[docId])\n}\n","/**\n * Keep a workspace's documents (and tags) query live from WebSocket events —\n * the shared, no-polling replacement for refetch loops.\n *\n * Mount `useArbiDocumentSync(workspaceId)` once wherever the document list\n * matters. It refetches the documents query on:\n * - `batch_complete` (upload OR doctag_generate) for this workspace, and\n * - a terminal `task_update` for a document (processing finished),\n * so freshly-uploaded, freshly-coded, or freshly-processed docs appear without\n * anyone polling.\n */\n\nimport { useQueryClient } from '@tanstack/react-query'\nimport {\n isMessageType,\n type WsBatchCompleteMessage,\n type WsTaskUpdateMessage,\n} from '@arbidocs/client'\nimport { arbiQueryKeys } from '../hooks'\nimport { useArbiWebSocket } from './hooks'\n\n// Processing statuses that mean a document is done (success or otherwise) — the\n// point at which its row is worth refetching. Mirrors the SDK transport set.\nconst TERMINAL_STATUSES: ReadonlySet<string> = new Set([\n 'completed',\n 'failed',\n 'skipped',\n 'empty',\n 'low-content',\n])\n\nexport function useArbiDocumentSync(workspaceId: string | undefined): void {\n const queryClient = useQueryClient()\n\n useArbiWebSocket((msg) => {\n if (!workspaceId) return\n\n if (isMessageType<WsBatchCompleteMessage>(msg, 'batch_complete')) {\n if (msg.workspace_ext_id !== workspaceId) return\n void queryClient.invalidateQueries({ queryKey: arbiQueryKeys.documents(workspaceId) })\n void queryClient.invalidateQueries({ queryKey: arbiQueryKeys.tags(workspaceId) })\n return\n }\n\n if (isMessageType<WsTaskUpdateMessage>(msg, 'task_update')) {\n if (msg.workspace_ext_id !== workspaceId) return\n if (TERMINAL_STATUSES.has(msg.status)) {\n void queryClient.invalidateQueries({ queryKey: arbiQueryKeys.documents(workspaceId) })\n }\n }\n })\n}\n","/**\n * The AI engine — domain-agnostic hooks for building an AI-native app on ARBI.\n *\n * `useAiTask` runs a streaming, cited agentic query (tokens, agent steps and\n * artifacts accumulate live, with follow-up threading). `useWorkspaceDocs`\n * resolves a workspace's document ids to ground on, and `useSemanticSearch`\n * returns retrieval-only cited passages. These wrap the low-level SDK hooks so a\n * vertical app never re-implements the streaming/accumulation plumbing.\n */\n\nimport { useCallback, useMemo, useRef, useState } from 'react'\nimport { useMutation } from '@tanstack/react-query'\nimport type { SSEStreamResult, ArtifactEvent } from '@arbidocs/sdk/browser'\nimport { useDocuments, useAssistantQuery } from '../hooks'\nimport { useArbi } from '../useArbi'\n\nexport type { ArtifactEvent }\n\n/**\n * Resolve a workspace's document set and their external ids. Pass the active\n * `workspaceId`; the kit stays agnostic about how selection is managed.\n */\nexport function useWorkspaceDocs(workspaceId?: string) {\n const { data: docs = [], isLoading, isError } = useDocuments(workspaceId)\n\n const docIds = useMemo(\n () =>\n docs.map((d: { external_id?: string }) => d.external_id).filter((id): id is string => !!id),\n [docs]\n )\n\n return { wsId: workspaceId, docs, docIds, isLoading, isError, ready: docIds.length > 0 }\n}\n\nexport type AiTaskStatus = 'idle' | 'running' | 'done' | 'error'\n\nexport interface AiRunOptions {\n /** Continue a prior turn (follow-up questions in the same thread). */\n previousResponseId?: string | null\n model?: string\n}\n\n/**\n * Run a single streaming agentic task grounded in a set of documents.\n *\n * Returns live state (`text` accumulates tokens as they stream) plus a `run`\n * that resolves to the full {@link SSEStreamResult} — including the response id\n * needed to chain follow-ups.\n */\nexport function useAiTask() {\n const mutation = useAssistantQuery()\n const [status, setStatus] = useState<AiTaskStatus>('idle')\n const [text, setText] = useState('')\n const [stepCount, setStepCount] = useState(0)\n const [error, setError] = useState<string | null>(null)\n const [responseId, setResponseId] = useState<string | null>(null)\n const [artifacts, setArtifacts] = useState<ArtifactEvent[]>([])\n const bufferRef = useRef('')\n const artifactsRef = useRef<Map<string, ArtifactEvent>>(new Map())\n\n const reset = useCallback(() => {\n setStatus('idle')\n setText('')\n setStepCount(0)\n setError(null)\n setResponseId(null)\n setArtifacts([])\n artifactsRef.current = new Map()\n bufferRef.current = ''\n }, [])\n\n const run = useCallback(\n async (\n question: string,\n docIds: string[],\n opts?: AiRunOptions\n ): Promise<SSEStreamResult | null> => {\n setStatus('running')\n setText('')\n setStepCount(0)\n setError(null)\n setArtifacts([])\n artifactsRef.current = new Map()\n bufferRef.current = ''\n let streamError: string | null = null\n try {\n const result = await mutation.mutateAsync({\n question,\n docIds,\n previousResponseId: opts?.previousResponseId ?? undefined,\n model: opts?.model,\n onToken: (c: string) => {\n bufferRef.current += c\n setText(bufferRef.current)\n },\n onOutputItemDone: (ev) => {\n const t = (ev.item as { type?: string }).type\n if (t === 'function_call' || t === 'reasoning') setStepCount((n) => n + 1)\n },\n onArtifact: (a: ArtifactEvent) => {\n // Artifacts are documents; keep the latest version per doc.\n artifactsRef.current.set(a.doc_ext_id, a)\n setArtifacts([...artifactsRef.current.values()])\n },\n onError: (m: string) => {\n streamError = m\n },\n })\n const finalText = result.text || bufferRef.current\n setText(finalText)\n setResponseId(result.assistantMessageExtId)\n setStepCount(result.agentSteps.length || 0)\n if (result.artifacts?.length) {\n for (const a of result.artifacts) artifactsRef.current.set(a.doc_ext_id, a)\n setArtifacts([...artifactsRef.current.values()])\n }\n const err = streamError || result.errors[0] || null\n if (err && !finalText) {\n setError(err)\n setStatus('error')\n } else {\n setStatus('done')\n }\n return result\n } catch (e) {\n setError(e instanceof Error ? e.message : 'The assistant request failed.')\n setStatus('error')\n return null\n }\n },\n [mutation]\n )\n\n return {\n status,\n text,\n stepCount,\n error,\n responseId,\n artifacts,\n run,\n reset,\n isRunning: status === 'running',\n isDone: status === 'done',\n }\n}\n\n// ── Semantic search (retrieval-only, cited chunks — no LLM generation) ────────\n\nexport interface SearchChunk {\n /**\n * Stable chunk id — the join key that ties a search hit to its rendered\n * location in the document viewer (`<div data-chunk-id={chunkExtId}>`). This\n * is what lets a result open the split-screen viewer scrolled to, and\n * highlighting, the exact matched passage. May be absent for legacy chunks.\n */\n chunkExtId?: string | null\n docId?: string | null\n docTitle?: string | null\n page?: number | null\n score?: number | null\n content: string\n}\n\n/**\n * Search a set of documents and return the top matching passages.\n *\n * Retrieval is a triggered action, so it's modelled as a React Query\n * `useMutation` (like {@link useAiTask}) rather than an auto-running query. The\n * SDK's `assistant.retrieve` (POST `/v1/assistant/retrieve` with a\n * `retrieval_chunk` tool) is the only network call — the hook maps its response\n * into ranked {@link SearchChunk}s carrying the `chunkExtId` join key.\n */\nexport function useSemanticSearch(docIds: string[]) {\n const arbi = useArbi()\n const [query, setQuery] = useState('')\n\n const mutation = useMutation<\n SearchChunk[],\n Error,\n { query: string; mode: 'semantic' | 'keyword' | 'hybrid' }\n >({\n mutationFn: async ({ query: q, mode }) => {\n const res = await arbi.assistant.retrieve(q, docIds, { searchMode: mode })\n const byTool = res.retrieval_chunk?.tool_responses ?? {}\n return Object.values(byTool)\n .flat()\n .map(\n (c: {\n metadata: {\n chunk_ext_id?: string | null\n doc_ext_id?: string | null\n doc_title?: string | null\n page_number?: number | null\n rerank_score?: number | null\n score?: number | null\n }\n content: string\n }) => ({\n chunkExtId: c.metadata.chunk_ext_id,\n docId: c.metadata.doc_ext_id,\n docTitle: c.metadata.doc_title,\n page: c.metadata.page_number,\n score: c.metadata.rerank_score ?? c.metadata.score,\n content: c.content,\n })\n )\n .sort((a, b) => (b.score ?? 0) - (a.score ?? 0))\n },\n })\n\n const { mutateAsync, reset } = mutation\n const search = useCallback(\n async (q: string, mode: 'semantic' | 'keyword' | 'hybrid' = 'hybrid') => {\n const trimmed = q.trim()\n setQuery(trimmed)\n // Nothing to search — clear back to the idle state.\n if (!trimmed || docIds.length === 0) {\n reset()\n return\n }\n try {\n await mutateAsync({ query: trimmed, mode })\n } catch {\n // Error state is exposed via `error`; swallow the rejection so callers\n // can `void search(...)` from an event handler without an unhandled\n // promise rejection.\n }\n },\n [mutateAsync, reset, docIds]\n )\n\n const status: AiTaskStatus = mutation.isPending\n ? 'running'\n : mutation.isError\n ? 'error'\n : mutation.isSuccess\n ? 'done'\n : 'idle'\n\n return {\n query,\n results: mutation.data ?? [],\n status,\n error: mutation.error ? (mutation.error.message ?? 'Search failed.') : null,\n search,\n isRunning: mutation.isPending,\n }\n}\n","/**\n * Client-side redlining — turn an original + revised text into track-changes\n * markdown (`<del>` strikethrough deletions, `<ins>` insertions). Rendered by\n * {@link AiMarkdown} (via rehype-raw) and the {@link ArtifactCanvas}.\n */\nimport { diffWords } from 'diff'\nimport type { ArtifactEvent } from '@arbidocs/sdk/browser'\n\n/** Produce inline `<del>/<ins>` redline markdown from two document versions. */\nexport function toRedlineMarkdown(original: string, revised: string): string {\n const parts = diffWords(original ?? '', revised ?? '')\n return parts\n .map((p) => {\n if (p.added) return `<ins>${p.value}</ins>`\n if (p.removed) return `<del>${p.value}</del>`\n return p.value\n })\n .join('')\n}\n\n/** Count added/removed words between two versions (for a redline summary). */\nexport function redlineStats(original: string, revised: string) {\n let added = 0\n let removed = 0\n for (const p of diffWords(original ?? '', revised ?? '')) {\n const words = p.value.trim() ? p.value.trim().split(/\\s+/).length : 0\n if (p.added) added += words\n else if (p.removed) removed += words\n }\n return { added, removed }\n}\n\n/** Wrap arbitrary text/markdown as a synthetic artifact for the canvas. */\nexport function textToArtifact(\n title: string,\n content: string,\n opts?: { mode?: ArtifactEvent['mode']; isComplete?: boolean; version?: number; id?: string }\n): ArtifactEvent {\n return {\n type: 'arbi.artifact',\n doc_ext_id: opts?.id ?? `local-${title.replace(/\\W+/g, '-').toLowerCase()}`,\n title,\n mode: opts?.mode ?? 'markdown',\n content,\n // Content-backed (markdown/text/html) artifacts carry no blob; file_type is\n // required on ArtifactEvent and defaults to \"\" for non-image artifacts.\n file_type: '',\n is_complete: opts?.isComplete ?? true,\n version: opts?.version ?? 1,\n message_ext_id: null,\n t: null,\n }\n}\n","import { useState } from 'react'\nimport { Sparkles, Loader2, AlertTriangle, Copy, Check, ShieldCheck } from 'lucide-react'\nimport { cn } from '../lib/utils'\nimport type { AiTaskStatus } from './engine'\nimport { AiMarkdown } from './AiMarkdown'\n\n/**\n * Renders the live state of a single agentic task: streaming tokens, a \"thinking\"\n * indicator with the running step count, errors, and a grounded/cited footer with\n * copy-to-clipboard. Shared by every AI feature so streaming looks identical\n * everywhere. Copy is customisable via `groundedNote` / `runningHint`.\n */\nexport function AiAnswer({\n status,\n text,\n stepCount,\n error,\n className,\n emptyHint,\n groundedNote = 'Grounded in the live workspace · verify citations before relying on it',\n runningHint = 'Reading the documents…',\n testId = 'ai-answer',\n}: {\n status: AiTaskStatus\n text: string\n stepCount?: number\n error?: string | null\n className?: string\n emptyHint?: string\n groundedNote?: string\n runningHint?: string\n testId?: string\n}) {\n const [copied, setCopied] = useState(false)\n const running = status === 'running'\n const hasText = text.trim().length > 0\n\n const copy = async () => {\n await navigator.clipboard.writeText(text)\n setCopied(true)\n setTimeout(() => setCopied(false), 1600)\n }\n\n if (status === 'idle' && !hasText) {\n return emptyHint ? (\n <p className={cn('text-sm text-muted-foreground', className)} data-testid={`${testId}-empty`}>\n {emptyHint}\n </p>\n ) : null\n }\n\n return (\n <div className={cn('space-y-3', className)} data-testid={testId} data-status={status}>\n {running && (\n <div\n className=\"flex items-center gap-2 text-xs font-medium text-ai-accent\"\n data-testid={`${testId}-thinking`}\n >\n <Loader2 className=\"size-3.5 animate-spin\" />\n {stepCount && stepCount > 0\n ? `Working — ${stepCount} step${stepCount === 1 ? '' : 's'}…`\n : 'Thinking…'}\n </div>\n )}\n\n {status === 'error' && !hasText && (\n <div\n className=\"flex items-start gap-2 rounded-lg border border-destructive/30 bg-destructive/5 p-3 text-sm text-destructive\"\n data-testid={`${testId}-error`}\n >\n <AlertTriangle className=\"mt-0.5 size-4 shrink-0\" />\n <span>{error ?? 'The assistant request failed.'}</span>\n </div>\n )}\n\n {hasText && (\n <>\n <AiMarkdown isStreaming={running}>{text}</AiMarkdown>\n {!running && (\n <div className=\"flex items-center justify-between border-t border-border pt-2.5\">\n <span className=\"inline-flex items-center gap-1.5 text-xs text-muted-foreground\">\n <ShieldCheck className=\"size-3.5 text-ai-accent\" />\n {groundedNote}\n </span>\n <button\n type=\"button\"\n onClick={copy}\n className=\"inline-flex items-center gap-1 text-xs font-medium text-muted-foreground hover:text-foreground\"\n data-testid={`${testId}-copy`}\n >\n {copied ? (\n <Check className=\"size-3.5 text-ai-accent\" />\n ) : (\n <Copy className=\"size-3.5\" />\n )}\n {copied ? 'Copied' : 'Copy'}\n </button>\n </div>\n )}\n </>\n )}\n\n {running && !hasText && (\n <div className=\"flex items-center gap-1.5 text-sm text-muted-foreground\">\n <Sparkles className=\"size-4 animate-pulse text-ai-accent\" /> {runningHint}\n </div>\n )}\n </div>\n )\n}\n","import type { LucideIcon } from 'lucide-react'\nimport { Sparkles } from 'lucide-react'\nimport { Card } from '../ui/card'\nimport { Button } from '../ui/button'\nimport { useAiTask } from './engine'\nimport { AiAnswer } from './AiAnswer'\n\n/**\n * A self-contained one-click agentic workflow: title + description + a Run button\n * that streams a grounded, cited result inline. Drop it on any page — it owns its\n * own task state via `useAiTask`.\n */\nexport function AiActionCard({\n icon: Icon = Sparkles,\n title,\n description,\n prompt,\n docIds,\n runLabel = 'Run',\n noDocsHint = 'Connect to the workspace to run this.',\n disabled,\n testId,\n}: {\n icon?: LucideIcon\n title: string\n description: string\n /** The fully-built prompt to run, or a factory (deferred until click). */\n prompt: string | (() => string)\n docIds: string[]\n runLabel?: string\n noDocsHint?: string\n disabled?: boolean\n testId?: string\n}) {\n const task = useAiTask()\n const noDocs = docIds.length === 0\n\n const onRun = () => {\n const p = typeof prompt === 'function' ? prompt() : prompt\n void task.run(p, docIds)\n }\n\n return (\n <Card variant=\"elevated\" className=\"rounded-xl p-5\" data-testid={testId}>\n <div className=\"flex items-start justify-between gap-4\">\n <div className=\"flex items-start gap-3\">\n <div className=\"flex size-9 shrink-0 items-center justify-center rounded-lg bg-ai-accent-soft text-ai-accent\">\n <Icon className=\"size-4\" />\n </div>\n <div>\n <p className=\"text-sm font-semibold text-foreground\">{title}</p>\n <p className=\"mt-0.5 text-xs leading-relaxed text-muted-foreground\">{description}</p>\n </div>\n </div>\n <Button\n variant={task.isDone ? 'outline' : 'accent'}\n size=\"sm\"\n onClick={onRun}\n disabled={disabled || noDocs || task.isRunning}\n data-testid={testId && `${testId}-run`}\n >\n <Sparkles className=\"size-3.5\" />\n {task.isRunning ? 'Running…' : task.isDone ? 'Re-run' : runLabel}\n </Button>\n </div>\n\n {(task.status !== 'idle' || noDocs) && (\n <div className=\"mt-4\">\n {noDocs ? (\n <p className=\"text-xs text-muted-foreground\">{noDocsHint}</p>\n ) : (\n <AiAnswer\n status={task.status}\n text={task.text}\n stepCount={task.stepCount}\n error={task.error}\n testId={testId && `${testId}-answer`}\n />\n )}\n </div>\n )}\n </Card>\n )\n}\n","import { useEffect, useState } from 'react'\nimport {\n FileText,\n Download,\n Copy,\n Check,\n Loader2,\n GitCompareArrows,\n AlertTriangle,\n} from 'lucide-react'\nimport { motion, AnimatePresence } from 'framer-motion'\nimport { Badge } from '../ui/badge'\nimport { cn } from '../lib/utils'\nimport type { ArtifactEvent } from './engine'\nimport { AiMarkdown } from './AiMarkdown'\n\n/**\n * The artifacts canvas — renders agent-produced documents (drafts, redlines,\n * memos) as first-class artifacts in a paper-styled panel. Markdown mode supports\n * redlines (`<del>` deletions / `<ins>` additions). Streams live: content grows\n * and `is_complete` flips when finished. Token-neutral: the \"paper\" surface is\n * the kit's `ai-surface` colour.\n */\nexport function ArtifactCanvas({\n artifacts,\n className,\n emptyHint = 'Draft artifacts produced by the agent will open here.',\n busy = false,\n busyHint = 'The agent is working through the documents…',\n stepCount,\n error = null,\n}: {\n artifacts: ArtifactEvent[]\n className?: string\n emptyHint?: string\n /** A run failed before producing content — show it instead of the empty hint. */\n error?: string | null\n /**\n * The agent is running but hasn't produced streamable content yet. Agentic\n * drafts spend a while planning/retrieving before the first token, so show a\n * live working state instead of the empty hint — otherwise the canvas reads\n * as broken during a perfectly normal multi-step run.\n */\n busy?: boolean\n busyHint?: string\n /** Agent steps completed so far, surfaced in the working state when > 0. */\n stepCount?: number\n}) {\n const [activeId, setActiveId] = useState<string | null>(null)\n const [copied, setCopied] = useState(false)\n\n // Follow the most recent artifact as they stream in.\n useEffect(() => {\n if (artifacts.length && (!activeId || !artifacts.some((a) => a.doc_ext_id === activeId))) {\n setActiveId(artifacts[artifacts.length - 1].doc_ext_id)\n }\n }, [artifacts, activeId])\n\n if (artifacts.length === 0) {\n // A failed run with no partial content — surface the error, not a dead hint.\n if (error && !busy) {\n return (\n <div\n className={cn(\n 'flex h-full min-h-[280px] flex-col items-center justify-center rounded-xl border border-destructive/30 bg-destructive/5 p-8 text-center',\n className\n )}\n data-testid=\"artifact-canvas-error\"\n >\n <AlertTriangle className=\"size-8 text-destructive/70\" />\n <p className=\"mt-3 max-w-md text-sm text-foreground\">{error}</p>\n </div>\n )\n }\n // Running-but-empty: the agent is planning/retrieving before it streams.\n if (busy) {\n return (\n <div\n className={cn(\n 'flex h-full min-h-[280px] flex-col items-center justify-center rounded-xl border border-border bg-ai-surface/40 p-8 text-center',\n className\n )}\n data-testid=\"artifact-canvas-busy\"\n >\n <Loader2 className=\"size-8 animate-spin text-ai-accent\" />\n <p className=\"mt-4 max-w-xs text-sm font-medium text-foreground\">{busyHint}</p>\n {typeof stepCount === 'number' && stepCount > 0 && (\n <p className=\"mt-1 text-xs text-muted-foreground\" data-testid=\"artifact-canvas-steps\">\n {stepCount} {stepCount === 1 ? 'step' : 'steps'} so far\n </p>\n )}\n </div>\n )\n }\n return (\n <div\n className={cn(\n 'flex h-full min-h-[280px] flex-col items-center justify-center rounded-xl border border-dashed border-border bg-secondary/30 p-8 text-center',\n className\n )}\n data-testid=\"artifact-canvas-empty\"\n >\n <FileText className=\"size-8 text-muted-foreground/50\" />\n <p className=\"mt-3 max-w-xs text-sm text-muted-foreground\">{emptyHint}</p>\n </div>\n )\n }\n\n const active = artifacts.find((a) => a.doc_ext_id === activeId) ?? artifacts[artifacts.length - 1]\n const isRedline = /~~|<ins|<del|<mark/i.test(active.content)\n\n const copy = async () => {\n await navigator.clipboard.writeText(active.content)\n setCopied(true)\n setTimeout(() => setCopied(false), 1600)\n }\n\n const download = () => {\n const ext = active.mode === 'html' ? 'html' : active.mode === 'text' ? 'txt' : 'md'\n const blob = new Blob([active.content], { type: 'text/plain' })\n const url = URL.createObjectURL(blob)\n const a = document.createElement('a')\n a.href = url\n a.download = `${active.title.replace(/[^\\w.-]+/g, '_') || 'artifact'}.${ext}`\n a.click()\n URL.revokeObjectURL(url)\n }\n\n return (\n <div\n className={cn(\n 'flex h-full flex-col overflow-hidden rounded-xl border border-border bg-card',\n className\n )}\n data-testid=\"artifact-canvas\"\n >\n {/* Header */}\n <div className=\"flex items-center gap-2 border-b border-border bg-secondary/40 px-4 py-2.5\">\n <FileText className=\"size-4 shrink-0 text-ai-accent\" />\n <span\n className=\"min-w-0 flex-1 truncate text-sm font-medium text-foreground\"\n data-testid=\"artifact-title\"\n >\n {active.title}\n </span>\n {isRedline && (\n <Badge variant=\"accent\" className=\"gap-1\">\n <GitCompareArrows className=\"size-3\" /> Redline\n </Badge>\n )}\n <Badge variant=\"secondary\">v{active.version}</Badge>\n {!active.is_complete ? (\n <span\n className=\"inline-flex items-center gap-1 text-xs text-ai-accent\"\n data-testid=\"artifact-streaming\"\n >\n <Loader2 className=\"size-3 animate-spin\" /> drafting\n </span>\n ) : (\n <div className=\"flex items-center gap-1\">\n <button\n onClick={copy}\n className=\"rounded p-1 text-muted-foreground hover:bg-accent hover:text-foreground\"\n title=\"Copy\"\n data-testid=\"artifact-copy\"\n >\n {copied ? (\n <Check className=\"size-3.5 text-ai-accent\" />\n ) : (\n <Copy className=\"size-3.5\" />\n )}\n </button>\n <button\n onClick={download}\n className=\"rounded p-1 text-muted-foreground hover:bg-accent hover:text-foreground\"\n title=\"Download\"\n data-testid=\"artifact-download\"\n >\n <Download className=\"size-3.5\" />\n </button>\n </div>\n )}\n </div>\n\n {/* Tabs when multiple artifacts */}\n {artifacts.length > 1 && (\n <div className=\"flex gap-1 overflow-x-auto border-b border-border bg-card px-2 py-1.5\">\n {artifacts.map((a) => (\n <button\n key={a.doc_ext_id}\n onClick={() => setActiveId(a.doc_ext_id)}\n className={cn(\n 'shrink-0 rounded-md px-2.5 py-1 text-xs font-medium',\n a.doc_ext_id === active.doc_ext_id\n ? 'bg-ai-accent-soft text-ai-accent'\n : 'text-muted-foreground hover:bg-accent'\n )}\n >\n {a.title.slice(0, 28)}\n </button>\n ))}\n </div>\n )}\n\n {/* Paper body */}\n <div className=\"flex-1 overflow-y-auto bg-ai-surface/40 p-6\">\n <AnimatePresence mode=\"wait\">\n <motion.div\n key={active.doc_ext_id}\n initial={{ opacity: 0, y: 6 }}\n animate={{ opacity: 1, y: 0 }}\n transition={{ duration: 0.2 }}\n className=\"mx-auto max-w-2xl rounded-lg bg-card p-8 shadow-sm ring-1 ring-border\"\n >\n {active.mode === 'html' ? (\n <div className=\"text-sm\" dangerouslySetInnerHTML={{ __html: active.content }} />\n ) : active.mode === 'text' ? (\n <pre className=\"whitespace-pre-wrap font-mono text-xs text-foreground\">\n {active.content}\n </pre>\n ) : (\n <AiMarkdown>{active.content}</AiMarkdown>\n )}\n </motion.div>\n </AnimatePresence>\n </div>\n </div>\n )\n}\n","import React from 'react'\nimport { FileText, Image as ImageIcon } from 'lucide-react'\nimport { Card } from '../ui/card'\n\n/**\n * The minimal artifact shape this card renders. A structural subset of the\n * ARBI app's `StreamingDocument`, defined here so the light package doesn't\n * depend on the app store — any object carrying these fields is accepted.\n */\nexport interface MessageArtifact {\n /** External id of the drafted document; opened in the docked viewer. */\n docExtId: string\n /** Display title; falls back when empty. */\n title: string\n /** Whether generation has finished. */\n isComplete: boolean\n /** Content mode; `image` swaps in image-specific labels and icon. */\n mode: 'markdown' | 'html' | 'text' | 'image'\n}\n\ninterface MessageArtifactCardProps {\n /** The streaming/drafted document linked to this assistant message. */\n artifact: MessageArtifact\n /** Opens the drafted document (docExtId) in the docked viewer. */\n onOpen: (docExtId: string) => void\n}\n\n/**\n * Inline \"View draft\" affordance shown inside the assistant message that\n * produced a drafted document — so the artifact lives in the conversation\n * narrative (dyad-style) instead of only a hidden docked panel.\n *\n * Clean-ARBI contract: flat outline card, one chat type size, brand\n * accent on the action, tap-friendly (a real button — no hover-only).\n */\nexport function MessageArtifactCard({\n artifact,\n onOpen,\n}: MessageArtifactCardProps): React.JSX.Element {\n const { docExtId, title, isComplete, mode } = artifact\n const isImage = mode === 'image'\n const Icon = isImage ? ImageIcon : FileText\n const statusText = isImage\n ? isComplete\n ? 'Image ready'\n : 'Generating…'\n : isComplete\n ? 'Draft ready'\n : 'Drafting…'\n\n return (\n <Card\n variant=\"outline\"\n className=\"mt-3 flex items-center gap-3 px-3 py-2.5\"\n data-testid={`message-artifact-card-${docExtId}`}\n >\n <Icon className=\"h-4 w-4 shrink-0 text-muted-foreground\" aria-hidden />\n <div className=\"min-w-0 flex-1\">\n <div\n className=\"truncate text-chat font-semibold text-foreground\"\n data-testid=\"artifact-title\"\n >\n {title || (isImage ? 'Generated image' : 'Untitled draft')}\n </div>\n <div className=\"text-sm text-muted-foreground\" data-testid=\"artifact-status\">\n {statusText}\n </div>\n </div>\n <button\n type=\"button\"\n onClick={() => onOpen(docExtId)}\n className=\"shrink-0 rounded-md bg-secondary/15 px-3 py-1.5 text-sm font-semibold text-secondary transition-colors hover:bg-secondary/25\"\n data-testid={`view-artifact-button-${docExtId}`}\n >\n {isImage ? 'View image' : 'View draft'}\n </button>\n </Card>\n )\n}\n","import { useState } from 'react'\nimport { Search, Loader2, FileText, CornerDownLeft } from 'lucide-react'\nimport { Card } from '../ui/card'\nimport { Badge } from '../ui/badge'\nimport { useSemanticSearch } from './engine'\nimport { cn } from '../lib/utils'\n\n/**\n * Semantic search across a document set — retrieval-only (no LLM), returning the\n * top matching passages with their source document and page. Uses the SDK's\n * `assistant.retrieve`, so every hit is a real, cited chunk of a real document.\n */\nexport function DocSearch({\n docIds,\n onOpenDoc,\n placeholder = 'Semantic search across your documents…',\n className,\n}: {\n docIds: string[]\n onOpenDoc?: (docId: string) => void\n placeholder?: string\n className?: string\n}) {\n const { results, status, error, search, isRunning, query } = useSemanticSearch(docIds)\n const [value, setValue] = useState('')\n\n const submit = () => {\n if (value.trim()) void search(value, 'hybrid')\n }\n\n return (\n <div className={cn('space-y-3', className)} data-testid=\"doc-search\">\n <div className=\"relative\">\n <Search className=\"pointer-events-none absolute left-3 top-1/2 size-4 -translate-y-1/2 text-muted-foreground\" />\n {isRunning && (\n <Loader2 className=\"absolute right-3 top-1/2 size-4 -translate-y-1/2 animate-spin text-ai-accent\" />\n )}\n <input\n value={value}\n onChange={(e) => setValue(e.target.value)}\n onKeyDown={(e) => e.key === 'Enter' && (e.preventDefault(), submit())}\n placeholder={placeholder}\n className=\"h-11 w-full rounded-lg border border-input bg-background pl-9 pr-24 text-sm outline-none focus:border-ai-accent/50 focus:ring-2 focus:ring-ai-accent/15\"\n data-testid=\"doc-search-input\"\n />\n <button\n type=\"button\"\n onClick={submit}\n className=\"absolute right-2 top-1/2 flex -translate-y-1/2 items-center gap-1 rounded-md bg-ai-accent px-2.5 py-1 text-xs font-medium text-ai-accent-foreground\"\n data-testid=\"doc-search-submit\"\n >\n Search <CornerDownLeft className=\"size-3\" />\n </button>\n </div>\n\n {status === 'error' && (\n <p className=\"text-sm text-destructive\" data-testid=\"doc-search-error\">\n {error}\n </p>\n )}\n\n {status === 'done' && (\n <div className=\"space-y-2\" data-testid=\"doc-search-results\">\n <p className=\"text-xs text-muted-foreground\">\n {results.length === 0\n ? `No passages matched “${query}”.`\n : `${results.length} passage${results.length === 1 ? '' : 's'} for “${query}”`}\n </p>\n {results.slice(0, 8).map((r, i) => (\n <Card\n key={`${r.docId}-${r.page}-${i}`}\n variant=\"elevated\"\n className={cn(\n 'rounded-xl p-3',\n onOpenDoc && r.docId && 'cursor-pointer transition-colors hover:border-ai-accent/40'\n )}\n onClick={() => r.docId && onOpenDoc?.(r.docId)}\n data-testid={`doc-search-hit-${i}`}\n >\n <div className=\"mb-1 flex items-center gap-2\">\n <FileText className=\"size-3.5 text-ai-accent\" />\n <span className=\"truncate text-xs font-medium text-foreground\">\n {r.docTitle ?? 'Document'}\n </span>\n {r.page != null && <Badge variant=\"secondary\">p.{r.page}</Badge>}\n {r.score != null && (\n <span className=\"ml-auto text-xs text-muted-foreground\">\n score {r.score.toFixed(2)}\n </span>\n )}\n </div>\n <p className=\"line-clamp-3 text-xs leading-relaxed text-muted-foreground\">\n {r.content}\n </p>\n </Card>\n ))}\n </div>\n )}\n </div>\n )\n}\n","/**\n * DocumentReview — a reusable, decoupled \"review mode\" viewer for a single\n * document. It renders the parsed content (chunks grouped by page, as markdown)\n * and overlays the document's AI findings: each tag citation highlights the\n * chunks it references and is listed in a findings rail that jumps to the\n * passage on click.\n *\n * REUSE-FIRST: reads purely from SDK data — `useParsedDocument` for the body,\n * the passed-in `doc.doctags[].citations` for findings, `useTags` for label\n * names, and `MarkdownRenderer` for rendering. No app store / react-pdf / Zustand\n * coupling; citation-jump is plain `scrollIntoView` on `data-chunk-id`.\n */\n\nimport React from 'react'\nimport { X } from 'lucide-react'\nimport type { components } from '@arbidocs/client'\n\nimport { useParsedDocument, useTags } from '../hooks'\nimport { MarkdownRenderer } from '../ai/MarkdownRenderer'\nimport { TagEntity } from '../entities/TagEntity'\nimport { Badge } from '../ui/badge'\nimport { cn } from '../lib/utils'\nimport type { ParsedChunk } from './parsed-types'\n\ntype DocResponse = components['schemas']['DocResponse']\n\nexport interface DocumentReviewProps {\n /** Document to review. */\n docId: string\n /** The document object (from `useDocuments`) — supplies title + AI findings\n * (`doctags[].citations`). Optional: without it the viewer is a plain reader. */\n doc?: DocResponse\n /** Workspace id — used to resolve tag ids → human names for findings. */\n workspaceId?: string\n /** Parse stage to render. Default `final`. */\n stage?: string\n /**\n * A chunk to scroll to and persistently highlight — the join key is the\n * parsed chunk's `chunk_ext_id`. This is how a semantic-search hit drives the\n * viewer: passing the matched passage's `chunkExtId` scrolls the body to it\n * and marks it, mirroring the monolith's `viewingPassageId` behaviour.\n * Independent of AI findings (which highlight via `doctags[].citations`).\n */\n activeChunkId?: string | null\n /** When provided, a close button is shown in the header. */\n onClose?: () => void\n className?: string\n}\n\ninterface Finding {\n key: string\n tagExtId: string\n statement: string\n chunkIds: string[]\n}\n\nexport function DocumentReview({\n docId,\n doc,\n workspaceId,\n stage = 'final',\n activeChunkId,\n onClose,\n className,\n}: DocumentReviewProps) {\n const parsedQuery = useParsedDocument(docId, stage)\n const tagsQuery = useTags(workspaceId)\n\n const tagNameById = React.useMemo(() => {\n const map = new Map<string, string>()\n for (const t of tagsQuery.data ?? []) {\n if (t.external_id) map.set(t.external_id, t.name ?? t.external_id.slice(0, 8))\n }\n return map\n }, [tagsQuery.data])\n\n const title = doc?.doc_metadata?.title || doc?.file_name || 'Document'\n\n // Findings: one per grounded doctag, plus an index of which chunks it\n // highlights. A doctag used to carry a per-statement citation map, so this\n // produced several findings per tag; each statement was a verbatim copy of\n // the doctag's own note, so the tag's note IS the finding text now.\n const { findings, chunkToTag } = React.useMemo(() => {\n const list: Finding[] = []\n const chunkTag = new Map<string, string>() // chunk_ext_id → tag_ext_id\n for (const dt of doc?.doctags ?? []) {\n const chunkIds = (dt.citations ?? []).flatMap((d) => (d.chunks ?? []).map((c) => c.chunk_id))\n if (chunkIds.length === 0) continue\n list.push({\n key: dt.tag_ext_id,\n tagExtId: dt.tag_ext_id,\n statement: dt.note ?? '',\n chunkIds,\n })\n for (const cid of chunkIds) if (!chunkTag.has(cid)) chunkTag.set(cid, dt.tag_ext_id)\n }\n return { findings: list, chunkToTag: chunkTag }\n }, [doc?.doctags])\n\n // Group parsed chunks by page.\n const pages = React.useMemo(() => {\n const chunks = (parsedQuery.data?.chunks ?? []) as ParsedChunk[]\n const byPage = new Map<number, ParsedChunk[]>()\n for (const c of chunks) {\n const p = c.metadata?.page_number ?? 0\n if (!byPage.has(p)) byPage.set(p, [])\n byPage.get(p)!.push(c)\n }\n return [...byPage.entries()].sort((a, b) => a[0] - b[0])\n }, [parsedQuery.data])\n\n const scrollRef = React.useRef<HTMLDivElement | null>(null)\n const [flash, setFlash] = React.useState<string | null>(null)\n\n const jumpToChunk = React.useCallback((chunkId: string) => {\n const el = scrollRef.current?.querySelector<HTMLElement>(`[data-chunk-id=\"${chunkId}\"]`)\n if (!el) return\n el.scrollIntoView({ behavior: 'smooth', block: 'center' })\n setFlash(chunkId)\n window.setTimeout(() => setFlash((c) => (c === chunkId ? null : c)), 1600)\n }, [])\n\n // Drive the viewer from an external passage selection (semantic-search hit).\n // Scroll to + flash the target chunk once its element is in the DOM — which,\n // since this viewer renders every chunk eagerly, is as soon as the parsed\n // body has loaded. Re-runs whenever the selected passage changes so clicking\n // successive results re-navigates, matching `viewingPassageId` in the monolith.\n const parsedReady = !parsedQuery.isLoading && !!parsedQuery.data\n React.useEffect(() => {\n if (!activeChunkId || !parsedReady) return\n // Defer to the next frame so the chunk nodes are committed before we query.\n const raf = window.requestAnimationFrame(() => jumpToChunk(activeChunkId))\n return () => window.cancelAnimationFrame(raf)\n }, [activeChunkId, parsedReady, jumpToChunk])\n\n return (\n <div\n data-testid=\"document-review\"\n className={cn(\n 'flex h-full min-h-0 flex-col overflow-hidden rounded-lg border bg-card',\n className\n )}\n >\n {/* Header */}\n <div className=\"flex items-center gap-3 border-b px-4 py-3\">\n <div className=\"min-w-0 flex-1\">\n <div className=\"truncate text-sm font-semibold\" title={title}>\n {title}\n </div>\n <div className=\"text-xs text-muted-foreground\">\n {parsedQuery.data?.metadata?.total_number_of_pages\n ? `${parsedQuery.data.metadata.total_number_of_pages} pages`\n : `${pages.length} pages`}\n {findings.length ? ` · ${findings.length} findings` : ''}\n </div>\n </div>\n {doc?.status ? <Badge variant=\"secondary\">{doc.status}</Badge> : null}\n {onClose ? (\n <button\n type=\"button\"\n aria-label=\"Close review\"\n data-testid=\"document-review-close\"\n onClick={onClose}\n className=\"rounded p-1 text-muted-foreground hover:bg-muted hover:text-foreground\"\n >\n <X className=\"size-4\" />\n </button>\n ) : null}\n </div>\n\n <div className=\"flex min-h-0 flex-1\">\n {/* Findings rail */}\n {findings.length > 0 ? (\n <aside\n className=\"hidden w-64 shrink-0 overflow-y-auto border-r p-3 md:block\"\n data-testid=\"document-review-findings\"\n >\n <div className=\"mb-2 text-xs font-medium uppercase tracking-wide text-muted-foreground\">\n AI findings\n </div>\n <ul className=\"space-y-2\">\n {findings.map((f) => (\n <li key={f.key}>\n {/* role=button (not <button>) so the TagEntity pill — itself a\n button — isn't nested inside a button (invalid HTML). */}\n <div\n role=\"button\"\n tabIndex={0}\n data-testid=\"review-finding\"\n onClick={() => jumpToChunk(f.chunkIds[0])}\n onKeyDown={(e) => {\n if (e.key === 'Enter' || e.key === ' ') {\n e.preventDefault()\n jumpToChunk(f.chunkIds[0])\n }\n }}\n className=\"w-full cursor-pointer rounded-md border p-2 text-left text-xs transition hover:border-ring hover:bg-muted/50 focus:outline-none focus-visible:ring-2 focus-visible:ring-ring\"\n >\n <TagEntity\n size=\"sm\"\n tag={{\n external_id: f.tagExtId,\n name: tagNameById.get(f.tagExtId) ?? f.tagExtId.slice(0, 8),\n }}\n />\n <p className=\"mt-1 line-clamp-3 text-muted-foreground\">{f.statement}</p>\n </div>\n </li>\n ))}\n </ul>\n </aside>\n ) : null}\n\n {/* Document body */}\n <div ref={scrollRef} className=\"min-w-0 flex-1 overflow-y-auto px-6 py-4\">\n {parsedQuery.isLoading ? (\n <div className=\"flex h-full items-center justify-center text-sm text-muted-foreground\">\n Loading document…\n </div>\n ) : parsedQuery.isError ? (\n <div className=\"flex h-full items-center justify-center text-sm text-muted-foreground\">\n Could not load this document’s content.\n </div>\n ) : pages.length === 0 ? (\n <div className=\"flex h-full items-center justify-center text-sm text-muted-foreground\">\n No readable content.\n </div>\n ) : (\n <div className=\"mx-auto max-w-3xl space-y-8\">\n {pages.map(([pageNum, chunks]) => (\n <section key={pageNum}>\n <div className=\"mb-3 flex items-center gap-3\">\n <span className=\"text-xs font-medium uppercase tracking-wide text-muted-foreground\">\n Page {pageNum}\n </span>\n <div className=\"h-px flex-1 bg-border\" />\n </div>\n <div className=\"space-y-3\">\n {chunks.map((c, i) => {\n const cid = c.metadata?.chunk_ext_id\n const tagExtId = cid ? chunkToTag.get(cid) : undefined\n const highlighted = !!tagExtId\n const isActive = !!cid && cid === activeChunkId\n return (\n <div\n key={cid ?? i}\n data-chunk-id={cid}\n data-testid={\n isActive\n ? 'review-chunk-active'\n : highlighted\n ? 'review-chunk-cited'\n : 'review-chunk'\n }\n className={cn(\n 'scroll-mt-4 rounded-md px-2 py-1 transition-colors',\n highlighted &&\n 'bg-[var(--color-ai-accent-soft,theme(colors.amber.100))] ring-1 ring-inset ring-border',\n // The externally-selected search passage wins the\n // styling: a stronger accent ring so the matched\n // hit stands out from any AI-finding highlights.\n isActive &&\n 'bg-[var(--color-ai-accent-soft,theme(colors.amber.100))] ring-2 ring-inset ring-ai-accent',\n flash === cid && 'ring-2 ring-ring'\n )}\n >\n {highlighted ? (\n <div className=\"mb-1\">\n <TagEntity\n size=\"sm\"\n tag={{\n external_id: tagExtId!,\n name: tagNameById.get(tagExtId!) ?? tagExtId!.slice(0, 8),\n }}\n />\n </div>\n ) : null}\n <MarkdownRenderer className=\"prose prose-sm max-w-none dark:prose-invert\">\n {c.content}\n </MarkdownRenderer>\n </div>\n )\n })}\n </div>\n </section>\n ))}\n </div>\n )}\n </div>\n </div>\n </div>\n )\n}\n","/**\n * SemanticSearch — a drop-in, Google-style semantic search over a document set\n * with a split-screen document viewer.\n *\n * Left: a query box + ranked result rows (document title, matched snippet with\n * the query context, a relevance affordance and page meta). Right: the selected\n * document rendered inline, scrolled to and highlighting the matched passage.\n *\n * Architecture mirrors the ARBI-frontend monolith's retrieve → navigate →\n * highlight flow:\n * - `useSemanticSearch` calls `POST /v1/assistant/retrieve` (via the SDK's\n * `assistant.retrieve`) and returns ranked chunks, each carrying a stable\n * `chunkExtId`.\n * - Selecting a result passes that `chunkExtId` to <DocumentReview>, whose\n * body renders every parsed chunk as an addressable `data-chunk-id` node;\n * it scrolls to and marks the matching node — the shared key that ties a\n * search hit to its location in the rendered document.\n *\n * Data + hooks stay in @arbidocs/react. Theming is semantic tokens only\n * (shadcn tokens + the AI-accent contract) — no firm look is hardcoded.\n */\n\nimport { useCallback, useMemo, useState } from 'react'\nimport { ArrowLeft, FileText, Loader2, Search, CornerDownLeft } from 'lucide-react'\nimport type { components } from '@arbidocs/client'\nimport { Badge } from '../ui/badge'\nimport { Button } from '../ui/button'\nimport { cn } from '../lib/utils'\nimport { useDocuments } from '../hooks'\nimport { DocumentReview } from '../documents/DocumentReview'\nimport { PassageCard } from './PassageCard'\nimport { useSemanticSearch, type SearchChunk } from './engine'\n\ntype DocResponse = components['schemas']['DocResponse']\n\nexport interface SemanticSearchProps {\n /**\n * The document corpus to search. The caller resolves this from the active\n * workspace (e.g. via `useWorkspaceDocs`), keeping the block agnostic about\n * how workspace selection is managed — retrieval runs against the SDK's open\n * workspace.\n */\n docIds: string[]\n /**\n * Active workspace id — forwarded to the viewer so AI-finding tag ids resolve\n * to human names, and used to enrich each hit's document title/findings.\n */\n workspaceId?: string\n /** Which search mode to run. Default `hybrid` (keyword + semantic). */\n searchMode?: 'hybrid' | 'semantic' | 'keyword'\n /** Placeholder for the query box. */\n placeholder?: string\n className?: string\n 'data-testid'?: string\n}\n\n/** Significant words to emphasise in a snippet (quoted phrases + long words). */\nfunction queryTerms(query: string): string[] {\n const terms = new Set<string>()\n for (const phrase of query.match(/\"([^\"]+)\"/g) ?? []) {\n const inner = phrase.slice(1, -1).trim()\n if (inner) terms.add(inner)\n }\n for (const word of query.replace(/\"/g, ' ').split(/\\s+/)) {\n if (word.length > 2) terms.add(word)\n }\n return [...terms]\n}\n\n/** Render a snippet with the query terms marked, as React nodes (no raw HTML). */\nfunction HighlightedSnippet({ text, terms }: { text: string; terms: string[] }) {\n const nodes = useMemo(() => {\n if (terms.length === 0) return [text]\n const escaped = terms.map((t) => t.replace(/[.*+?^${}()|[\\]\\\\]/g, '\\\\$&'))\n const re = new RegExp(`(${escaped.join('|')})`, 'gi')\n // Unstyled on purpose — <PassageCard> styles the marks it contains.\n return text.split(re).map((part, i) => (i % 2 === 1 ? <mark key={i}>{part}</mark> : part))\n }, [text, terms])\n return <>{nodes}</>\n}\n\nfunction ResultRow({\n result,\n index,\n terms,\n isActive,\n onSelect,\n}: {\n result: SearchChunk\n index: number\n terms: string[]\n isActive: boolean\n onSelect: () => void\n}) {\n return (\n <PassageCard\n onClick={onSelect}\n active={isActive}\n score={result.score}\n data-testid={`arbi-semantic-search-result-${index}`}\n header={\n <>\n <FileText className=\"size-3.5 shrink-0 text-ai-accent\" />\n <span className=\"truncate text-xs font-medium text-foreground\">\n {result.docTitle ?? 'Document'}\n </span>\n {result.page != null && <Badge variant=\"secondary\">p.{result.page}</Badge>}\n </>\n }\n >\n <p className=\"line-clamp-3 text-xs leading-relaxed text-muted-foreground\">\n <span className=\"text-muted-foreground/60\">… </span>\n <HighlightedSnippet text={result.content} terms={terms} />\n <span className=\"text-muted-foreground/60\"> …</span>\n </p>\n </PassageCard>\n )\n}\n\nexport function SemanticSearch({\n docIds,\n workspaceId,\n searchMode = 'hybrid',\n placeholder = 'Search your documents by meaning…',\n className,\n 'data-testid': testId = 'arbi-semantic-search',\n}: SemanticSearchProps) {\n const { results, status, error, search, isRunning, query } = useSemanticSearch(docIds)\n const [value, setValue] = useState('')\n const [selected, setSelected] = useState<SearchChunk | null>(null)\n\n // Enrich hits with the full document (title + AI findings) when a workspace is\n // known. Without it the viewer still reads title/pages from parsed metadata.\n const { data: docs = [] } = useDocuments(workspaceId, { enabled: !!workspaceId })\n const docMap = useMemo(() => {\n const map = new Map<string, DocResponse>()\n for (const d of docs as DocResponse[]) if (d.external_id) map.set(d.external_id, d)\n return map\n }, [docs])\n\n const terms = useMemo(() => queryTerms(query), [query])\n\n const submit = useCallback(() => {\n const q = value.trim()\n if (!q) return\n setSelected(null)\n void search(q, searchMode)\n }, [value, search, searchMode])\n\n const selectedDoc = selected?.docId ? docMap.get(selected.docId) : undefined\n const hasResults = status === 'done' && results.length > 0\n\n return (\n <div data-testid={testId} className={cn('flex min-h-0 flex-col gap-4 md:flex-row', className)}>\n {/* Results panel — hidden on mobile once a document is open. */}\n <div\n className={cn(\n 'flex min-h-0 flex-col gap-3 md:w-[22rem] md:shrink-0',\n selected && 'hidden md:flex'\n )}\n >\n <div className=\"relative\">\n <Search className=\"pointer-events-none absolute left-3 top-1/2 size-4 -translate-y-1/2 text-muted-foreground\" />\n {isRunning && (\n <Loader2 className=\"absolute right-3 top-1/2 size-4 -translate-y-1/2 animate-spin text-ai-accent\" />\n )}\n <input\n value={value}\n onChange={(e) => setValue(e.target.value)}\n onKeyDown={(e) => e.key === 'Enter' && (e.preventDefault(), submit())}\n placeholder={placeholder}\n aria-label=\"Semantic search query\"\n className=\"h-11 w-full rounded-lg border border-input bg-background pl-9 pr-24 text-sm outline-none focus:border-ai-accent/50 focus:ring-2 focus:ring-ai-accent/15\"\n data-testid=\"arbi-semantic-search-input\"\n />\n <button\n type=\"button\"\n onClick={submit}\n disabled={!value.trim() || isRunning}\n className=\"absolute right-2 top-1/2 flex -translate-y-1/2 items-center gap-1 rounded-md bg-ai-accent px-2.5 py-1 text-xs font-medium text-ai-accent-foreground disabled:opacity-50\"\n data-testid=\"arbi-semantic-search-submit\"\n >\n Search <CornerDownLeft className=\"size-3\" />\n </button>\n </div>\n\n {status === 'error' && (\n <p className=\"text-sm text-destructive\" data-testid=\"arbi-semantic-search-error\">\n {error}\n </p>\n )}\n\n {status === 'done' && (\n <div\n className=\"flex min-h-0 flex-col gap-2 overflow-y-auto\"\n data-testid=\"arbi-semantic-search-results\"\n >\n <p className=\"text-xs text-muted-foreground\">\n {results.length === 0\n ? `No passages matched “${query}”.`\n : `${results.length} passage${results.length === 1 ? '' : 's'} for “${query}”`}\n </p>\n {results.map((r, i) => (\n <ResultRow\n key={r.chunkExtId ?? `${r.docId}-${r.page}-${i}`}\n result={r}\n index={i}\n terms={terms}\n isActive={selected?.chunkExtId != null && selected.chunkExtId === r.chunkExtId}\n onSelect={() => setSelected(r)}\n />\n ))}\n </div>\n )}\n </div>\n\n {/* Viewer panel — the split screen. On mobile it replaces the list. */}\n <div\n className={cn('min-h-0 min-w-0 flex-1', !selected && 'hidden md:block')}\n data-testid=\"arbi-semantic-search-viewer\"\n >\n {selected && selected.docId ? (\n <div className=\"flex h-full min-h-0 flex-col gap-2\">\n <Button\n variant=\"ghost\"\n size=\"sm\"\n className=\"self-start md:hidden\"\n onClick={() => setSelected(null)}\n data-testid=\"arbi-semantic-search-back\"\n >\n <ArrowLeft className=\"size-4\" /> Back to results\n </Button>\n <DocumentReview\n key={selected.docId}\n docId={selected.docId}\n doc={selectedDoc}\n workspaceId={workspaceId}\n activeChunkId={selected.chunkExtId ?? undefined}\n className=\"min-h-0 flex-1\"\n />\n </div>\n ) : (\n <div\n className=\"flex h-full min-h-[16rem] items-center justify-center rounded-lg border border-dashed border-border bg-muted/20 p-8 text-center\"\n data-testid=\"arbi-semantic-search-empty\"\n >\n <div className=\"max-w-xs\">\n <Search className=\"mx-auto mb-3 size-6 text-muted-foreground/50\" />\n <p className=\"text-sm text-muted-foreground\">\n {hasResults\n ? 'Select a passage to open the document alongside, scrolled to the match.'\n : 'Search across the record — every hit is a real, cited passage you can open in place.'}\n </p>\n </div>\n </div>\n )}\n </div>\n </div>\n )\n}\n","import { useState } from 'react'\nimport { Send, Tags } from 'lucide-react'\nimport { Button } from '../ui/button'\nimport { Input } from '../ui/input'\nimport { useAiTask } from './engine'\nimport { AiAnswer } from './AiAnswer'\n\n/**\n * Ask questions grounded in a SINGLE document (docId scoped to one file), plus a\n * one-click \"suggest tags\" action. Drop it in a document viewer.\n */\nexport function DocQaPanel({ docId, docName }: { docId: string; docName?: string }) {\n const task = useAiTask()\n const [q, setQ] = useState('')\n\n const ask = () => {\n const question = q.trim()\n if (!question || task.isRunning) return\n void task.run(\n `You are answering strictly from the single document \"${docName ?? docId}\". Cite the page/section for each point and say if the document does not address the question.\\n\\nQuestion: ${question}`,\n [docId]\n )\n }\n\n const suggestTags = () =>\n void task.run(\n `Suggest 3-6 concise, reusable labels for the document \"${docName ?? docId}\" — covering document type, the key issues it touches, and any key parties. Return them as a short comma-separated list with a one-line rationale for each.`,\n [docId]\n )\n\n return (\n <div className=\"min-w-0 space-y-3\" data-testid=\"doc-qa\">\n {/* min-w-0 on the field and shrink-0 on the buttons: without them a flex\n row refuses to shrink past the input's intrinsic width, so the actions\n overflow the container in any narrow host (a docked review rail, a\n split pane). */}\n <div className=\"flex min-w-0 items-center gap-2\">\n <Input\n value={q}\n onChange={(e) => setQ(e.target.value)}\n onKeyDown={(e) => e.key === 'Enter' && (e.preventDefault(), ask())}\n placeholder=\"Ask about this document…\"\n className=\"min-w-0 flex-1 bg-card text-sm placeholder:text-muted-foreground/70 focus-visible:border-ring/60 focus-visible:ring-2 focus-visible:ring-ring/50\"\n data-testid=\"doc-qa-input\"\n />\n <Button\n variant=\"accent\"\n size=\"icon\"\n onClick={ask}\n disabled={task.isRunning || !q.trim()}\n className=\"shrink-0\"\n data-testid=\"doc-qa-send\"\n >\n <Send className=\"size-4\" />\n </Button>\n <Button\n variant=\"outline\"\n size=\"sm\"\n onClick={suggestTags}\n disabled={task.isRunning}\n className=\"shrink-0\"\n data-testid=\"doc-qa-tags\"\n >\n <Tags className=\"size-4\" /> Tags\n </Button>\n </div>\n <AiAnswer\n status={task.status}\n text={task.text}\n stepCount={task.stepCount}\n error={task.error}\n emptyHint=\"Ask a question, or suggest tags — answered from this document only.\"\n testId=\"doc-qa-answer\"\n />\n </div>\n )\n}\n","import React, { useMemo, useCallback, useEffect, useLayoutEffect, useRef, useState } from 'react'\nimport { createPortal } from 'react-dom'\nimport ReactMarkdown, { Components } from 'react-markdown'\nimport type { components } from '@arbidocs/client'\nimport { MarkMenu, type MarkMenuItem } from '../ui/mark-menu'\nimport { cn } from '../lib/utils'\n\n/**\n * Presentational core of the ARBI citation renderer — promoted from the monolith\n * as the callback-injection reference for the AI family. It owns all the hard-won\n * citation behaviour (numbering, per-doc grouping, hover/active highlighting,\n * click/open flows, emphasis-safe markdown parsing) but knows NOTHING about the\n * app's store, router or React Query. Every app coupling is injected:\n *\n * - `renderMarkdown` — the app's `MarkdownRenderer` (KaTeX / Mermaid / doc-entity\n * pills all stay app-side; the core just hands it the citation `a` override).\n * - `ExternalLink` — the app's confirm-before-open external-link component.\n * - `onOpenCitation` / `onActivateChunk` — replace the two store writes that used\n * to fire when a citation opens / a chunk card is clicked.\n * - `useCitationState` — an injected hook the popover calls to read the reactive\n * active-citation / viewing-passage / active-page state (kept as a hook so the\n * subscription stays local to each popover, exactly as before — the top-level\n * renderer never re-renders on citation state changes, so the markdown is never\n * re-parsed mid-interaction).\n * - `onCloseCitation` / `onDismissCitation` — the two distinct close flows.\n */\n\n// Renders markdown inline (no block wrappers) for single-line truncated display\nconst INLINE_MD_COMPONENTS = {\n p: ({ children }: { children?: React.ReactNode }) => <>{children}</>,\n strong: ({ children }: { children?: React.ReactNode }) => (\n <strong className=\"font-semibold\">{children}</strong>\n ),\n em: ({ children }: { children?: React.ReactNode }) => <em>{children}</em>,\n code: ({ children }: { children?: React.ReactNode }) => (\n <code className=\"font-mono\">{children}</code>\n ),\n a: ({ children }: { children?: React.ReactNode }) => <>{children}</>,\n ul: ({ children }: { children?: React.ReactNode }) => <>{children}</>,\n ol: ({ children }: { children?: React.ReactNode }) => <>{children}</>,\n li: ({ children }: { children?: React.ReactNode }) => <span>{children} </span>,\n h1: ({ children }: { children?: React.ReactNode }) => <>{children}</>,\n h2: ({ children }: { children?: React.ReactNode }) => <>{children}</>,\n h3: ({ children }: { children?: React.ReactNode }) => <>{children}</>,\n h4: ({ children }: { children?: React.ReactNode }) => <>{children}</>,\n h5: ({ children }: { children?: React.ReactNode }) => <>{children}</>,\n h6: ({ children }: { children?: React.ReactNode }) => <>{children}</>,\n blockquote: ({ children }: { children?: React.ReactNode }) => <>{children}</>,\n pre: ({ children }: { children?: React.ReactNode }) => <>{children}</>,\n}\n\n// Structural citation types, sourced from the canonical OpenAPI schema so the\n// core stays in lockstep with the app's `Chunk` / `ToolResponses` shapes.\nexport type Chunk = components['schemas']['Chunk']\nexport interface ToolResponses {\n [docId: string]: Chunk[]\n}\n\n/** Reactive citation state the popover reads (injected as a hook by the app). */\nexport interface CitationState {\n activeCitationKey: string | null\n viewingPassageId: string | null\n isOnConversationPage: boolean\n}\n\n/** Payload handed to the app when a chunk card is clicked / a citation opens. */\nexport interface ChunkActivation {\n messageId: string\n citationNum: string\n chunkIds: string[]\n chunk: Chunk\n citationData?: ToolResponses\n}\n\n/** Renders the citation content as markdown — the app supplies its MarkdownRenderer. */\nexport type RenderMarkdown = (args: {\n components: Partial<Components>\n isStreaming: boolean\n children: string\n}) => React.ReactNode\n\nexport interface CitationRendererProps {\n content: string\n citations?: Record<string, string[]>\n citationData?: ToolResponses\n className?: string\n messageId: string\n isStreaming?: boolean\n // ── injected app bindings ──────────────────────────────────────────────────\n renderMarkdown: RenderMarkdown\n ExternalLink: React.ComponentType<React.ComponentPropsWithoutRef<'a'>>\n onOpenCitation: (citationKey: string) => void\n onActivateChunk: (activation: ChunkActivation) => void\n useCitationState: () => CitationState\n onCloseCitation: () => void\n onDismissCitation: () => void\n /** Tells the user a citation was copied (or could not be). Optional: copying is silent without it. */\n notify?: (message: string, kind?: 'success' | 'error' | 'info') => void\n}\n\nconst CitationRendererComponent: React.FC<CitationRendererProps> = ({\n content,\n citations,\n citationData,\n className,\n messageId,\n isStreaming = false,\n renderMarkdown,\n ExternalLink,\n onOpenCitation,\n onActivateChunk,\n useCitationState,\n onCloseCitation,\n onDismissCitation,\n notify,\n}) => {\n const chunkMap = useMemo(() => {\n const map = new Map<string, Chunk>()\n if (citationData) {\n Object.entries(citationData as ToolResponses).forEach(([, docChunks]) => {\n if (docChunks && Array.isArray(docChunks)) {\n docChunks.forEach((chunk: Chunk) => {\n if (chunk.metadata && chunk.metadata.chunk_ext_id) {\n map.set(chunk.metadata.chunk_ext_id, chunk)\n }\n })\n }\n })\n }\n return map\n }, [citationData])\n\n const getChunkDetails = useCallback(\n (chunkIds: string[]): Chunk[] =>\n [...new Set(chunkIds)]\n .map((id) => chunkMap.get(id))\n .filter((c): c is Chunk => c !== undefined),\n [chunkMap]\n )\n\n const handleChunkClick = useCallback(\n (citationNum: string, chunkIds: string[], chunk: Chunk) => {\n onActivateChunk({ messageId, citationNum, chunkIds, chunk, citationData })\n },\n [messageId, citationData, onActivateChunk]\n )\n\n const markdownComponents = useMemo(() => {\n const components: Partial<Components> = {\n a: ({ href, children, ...props }) => {\n if (!href?.startsWith('#cite-')) {\n if (!href || href.startsWith('#')) {\n return (\n <a className=\"text-primary underline underline-offset-2\" href={href} {...props}>\n {children}\n </a>\n )\n }\n return (\n <ExternalLink href={href} {...props}>\n {children}\n </ExternalLink>\n )\n }\n\n const citationNum = href.slice(6)\n const citationKey = `${messageId}-${citationNum}`\n const chunkIds = citations?.[citationNum] || []\n const chunks = getChunkDetails(chunkIds)\n\n return (\n <CitationPopover\n key={citationKey}\n citationNum={citationNum}\n messageId={messageId}\n chunks={chunks}\n isStreaming={isStreaming}\n onOpen={() => onOpenCitation(citationKey)}\n onChunkClick={(chunk) => handleChunkClick(citationNum, chunkIds, chunk)}\n useCitationState={useCitationState}\n onCloseCitation={onCloseCitation}\n onDismissCitation={onDismissCitation}\n notify={notify}\n >\n {children}\n </CitationPopover>\n )\n },\n }\n return components\n }, [\n citations,\n messageId,\n isStreaming,\n getChunkDetails,\n handleChunkClick,\n onOpenCitation,\n ExternalLink,\n useCitationState,\n onCloseCitation,\n onDismissCitation,\n notify,\n ])\n\n // Citation markers `[text](#cite-N)` are already valid markdown link syntax.\n // We let react-markdown parse them natively (the `a` override above keys on the\n // `#cite-` href) instead of pre-converting to raw HTML — so emphasis inside the\n // cited text (**bold**, *italic*, `code`) and literal `*`/`_` characters survive\n // intact, and link boundaries can never split an emphasis span.\n return (\n <div className={cn('citation-container', className)} data-testid=\"citation-renderer\">\n {renderMarkdown({ components: markdownComponents, isStreaming, children: content })}\n </div>\n )\n}\n\n// ── CitationPopover ──────────────────────────────────────────────────────────\n\ninterface CitationPopoverProps {\n citationNum: string\n messageId: string\n chunks: Chunk[]\n isStreaming: boolean\n onOpen: () => void\n onChunkClick: (chunk: Chunk) => void\n useCitationState: () => CitationState\n onCloseCitation: () => void\n onDismissCitation: () => void\n notify?: CitationRendererProps['notify']\n children: React.ReactNode\n}\n\nconst CitationPopover: React.FC<CitationPopoverProps> = ({\n citationNum,\n messageId,\n chunks,\n isStreaming,\n onOpen,\n onChunkClick,\n useCitationState,\n onCloseCitation,\n onDismissCitation,\n notify,\n children,\n}) => {\n const { activeCitationKey, viewingPassageId, isOnConversationPage } = useCitationState()\n const isActive = activeCitationKey === `${messageId}-${citationNum}`\n // Gate on the app's navigation state, not useLocation(): in-app navigation\n // rewrites the hash via history.replaceState, which react-router never\n // observes, so its location stays frozen at the page-load value.\n const open = isActive && isOnConversationPage\n\n // The popover belongs to the conversation view. If the user leaves it (another page, or a\n // full-screen panel over it) while it is open, drop the active key so it neither floats over\n // the new view nor reappears when they come back.\n useEffect(() => {\n if (isActive && !isOnConversationPage) onDismissCitation()\n }, [isActive, isOnConversationPage, onDismissCitation])\n\n const triggerRef = useRef<HTMLElement>(null)\n const dialogRef = useRef<HTMLDivElement>(null)\n // Set when the user closes it (Escape / the X): focus then goes back to the citation they came\n // from. A close caused by something else (another citation, leaving the page) leaves focus alone.\n const restoreFocusRef = useRef(false)\n\n const dismiss = useCallback(() => {\n restoreFocusRef.current = true\n onDismissCitation()\n }, [onDismissCitation])\n\n // The popover is portalled to the end of <body>, so a keyboard or screen-reader user who\n // opened it would otherwise have to Tab through the whole page to reach it. Move focus into the\n // dialog on open (taps do not focus a span on iOS, so this is not gated on the trigger) and\n // return it to the citation when the user dismisses.\n useEffect(() => {\n if (!open) return\n dialogRef.current?.focus({ preventScroll: true })\n return () => {\n if (!restoreFocusRef.current) return\n restoreFocusRef.current = false\n triggerRef.current?.focus({ preventScroll: true })\n }\n }, [open])\n\n // Escape closes like the X: the popover goes, the passage stays in the viewer.\n useEffect(() => {\n if (!open) return\n const onKeyDown = (e: KeyboardEvent) => {\n if (e.key === 'Escape') dismiss()\n }\n document.addEventListener('keydown', onKeyDown)\n return () => document.removeEventListener('keydown', onKeyDown)\n }, [open, dismiss])\n\n // The popover docks to the top edge of the composer (full chat width) instead of the cited\n // word, so it never covers the answer paragraph being cited. The edge is measured each time\n // the popover opens.\n const [dock, setDock] = useState({ left: 0, top: 0, width: 0 })\n\n // Measured whenever it opens, however it was opened (click, keyboard, a source chip).\n useLayoutEffect(() => {\n if (!open) return\n // The composer is exactly the chat column (the main element also spans a docked viewer).\n const edge = (\n document.querySelector('[data-testid=\"message-input-container\"]') ??\n document.querySelector('main[data-testid^=\"conversation-\"]') ??\n document.body\n ).getBoundingClientRect()\n setDock({ left: edge.left, top: edge.top, width: edge.width })\n }, [open])\n\n const handleOpen = useCallback(() => {\n onOpen()\n if (chunks.length > 0) {\n onChunkClick(chunks[0])\n }\n }, [onOpen, onChunkClick, chunks])\n\n const byDoc = useMemo(() => {\n const map = new Map<string, { title: string; chunks: Chunk[] }>()\n chunks.forEach((chunk) => {\n const docId = chunk.metadata.doc_ext_id ?? 'unknown'\n const title = chunk.metadata.doc_title ?? docId\n if (!map.has(docId)) map.set(docId, { title, chunks: [] })\n map.get(docId)!.chunks.push(chunk)\n })\n return Array.from(map.entries()).map(([docId, val]) => ({ docId, ...val }))\n }, [chunks])\n\n const first = chunks[0]\n const firstText = first ? first.content.replace(/\\n+/g, ' ').trim() : ''\n const firstTitle = first ? (first.metadata.doc_title ?? first.metadata.doc_ext_id ?? '') : ''\n const firstPage = first?.metadata.page_number\n\n const copyCitation = useCallback(async () => {\n const source = [firstTitle, firstPage != null ? `p.${firstPage}` : null]\n .filter(Boolean)\n .join(', ')\n try {\n await navigator.clipboard.writeText(source ? `“${firstText}” (${source})` : firstText)\n notify?.('Citation copied', 'success')\n } catch {\n notify?.('Could not copy the citation', 'error')\n }\n }, [firstText, firstTitle, firstPage, notify])\n\n const items: MarkMenuItem[] =\n isStreaming || chunks.length === 0\n ? []\n : [\n {\n id: 'open',\n label: 'Open in viewer',\n primary: true,\n onSelect: handleOpen,\n testId: `citation-open-${citationNum}`,\n },\n {\n id: 'copy',\n label: 'Copy citation',\n onSelect: () => void copyCitation(),\n testId: `citation-copy-${citationNum}`,\n },\n ]\n\n // The cited passage itself: quoted text, its source and page, before anything is opened.\n const preview = first ? (\n <div className=\"max-w-xs\" data-testid={`citation-preview-${citationNum}`}>\n <span className=\"block text-xs font-medium text-foreground\">{firstTitle}</span>\n {firstPage != null && (\n <span className=\"block text-xs text-muted-foreground\">Page {firstPage}</span>\n )}\n <span className=\"mt-1 line-clamp-4 block text-xs italic text-muted-foreground\">\n <ReactMarkdown components={INLINE_MD_COMPONENTS}>{firstText}</ReactMarkdown>\n </span>\n {chunks.length > 1 && (\n <span className=\"mt-1 block text-xs text-muted-foreground\">\n +{chunks.length - 1} more passage{chunks.length > 2 ? 's' : ''}\n </span>\n )}\n </div>\n ) : undefined\n\n return (\n <>\n <CitationLink\n triggerRef={triggerRef}\n citationNum={citationNum}\n isActive={isActive}\n isStreaming={isStreaming}\n items={items}\n preview={preview}\n >\n {children}\n </CitationLink>\n {open &&\n createPortal(\n <div\n className=\"pointer-events-none fixed z-[42] flex justify-center px-2\"\n style={{\n left: dock.left,\n width: dock.width,\n bottom: window.innerHeight - dock.top + 8,\n }}\n >\n <div\n ref={dialogRef}\n role=\"dialog\"\n tabIndex={-1}\n aria-label={`Citation ${citationNum}`}\n className=\"pointer-events-auto z-[42] max-h-[45vh] outline-none w-[min(100%,48rem)] min-w-0 overflow-y-auto rounded-md border border-border bg-popover p-0 text-popover-foreground shadow-xl\"\n data-testid={`citation-popover-${citationNum}`}\n >\n <div className=\"px-3 py-2 pointer-coarse:py-0 border-b border-border sticky top-0 bg-popover z-10 flex items-center justify-between gap-2\">\n <span className=\"text-xs font-semibold text-muted-foreground tracking-wide\">\n Citation {citationNum} ({chunks.length} passage{chunks.length !== 1 ? 's' : ''})\n </span>\n <button\n onClick={dismiss}\n // A bare 12px glyph is a tiny target — easy to miss, so closing takes\n // several tries. Pad it out to a comfortable ~28px tap area (negative\n // margin keeps the icon where it sat, so the header layout is\n // unchanged) and give it a hover background so it reads as a button.\n className=\"-m-1.5 flex shrink-0 items-center justify-center rounded p-1.5 text-muted-foreground transition-colors hover:bg-muted hover:text-foreground pointer-coarse:m-0 pointer-coarse:size-11 pointer-coarse:p-0\"\n aria-label=\"Close\"\n data-testid={`citation-popover-close-${citationNum}`}\n >\n <svg\n width=\"14\"\n height=\"14\"\n viewBox=\"0 0 12 12\"\n fill=\"none\"\n xmlns=\"http://www.w3.org/2000/svg\"\n >\n <path\n d=\"M1 1L11 11M11 1L1 11\"\n stroke=\"currentColor\"\n strokeWidth=\"1.5\"\n strokeLinecap=\"round\"\n />\n </svg>\n </button>\n </div>\n {byDoc.map(({ docId, title, chunks: docChunks }) => (\n <div key={docId} className=\"px-3 py-2 border-b border-border last:border-0\">\n <p className=\"text-sm font-semibold text-foreground mb-1 truncate\" title={title}>\n {title}\n </p>\n {docChunks.map((chunk) => {\n const isSelected = viewingPassageId === chunk.metadata.chunk_ext_id\n return (\n <button\n key={chunk.metadata.chunk_ext_id}\n data-testid={`citation-chunk-${chunk.metadata.chunk_ext_id}`}\n onClick={() => onChunkClick(chunk)}\n className={cn(\n 'w-full text-left text-sm rounded-md px-2 py-1.5 pointer-coarse:min-h-11 pointer-coarse:py-3 transition-colors flex items-start gap-2 mb-1 last:mb-0',\n isSelected\n ? 'bg-ai-soft text-foreground ring-1 ring-ai-accent/40'\n : 'text-muted-foreground hover:text-primary hover:bg-muted'\n )}\n >\n <span className=\"min-w-0 flex-1\">\n {chunk.metadata.page_number != null && (\n <span className=\"block text-xs text-muted-foreground\">\n Page {chunk.metadata.page_number}\n </span>\n )}\n <span className=\"line-clamp-3 italic\">\n <ReactMarkdown components={INLINE_MD_COMPONENTS}>\n {chunk.content.replace(/\\n+/g, ' ').trim()}\n </ReactMarkdown>\n </span>\n </span>\n </button>\n )\n })}\n </div>\n ))}\n </div>\n </div>,\n document.body\n )}\n </>\n )\n}\n\n// ── CitationLink ─────────────────────────────────────────────────────────────\n\ninterface CitationLinkProps {\n citationNum: string\n isActive: boolean\n isStreaming: boolean\n items: MarkMenuItem[]\n preview: React.ReactNode\n triggerRef: React.Ref<HTMLElement>\n children: React.ReactNode\n}\n\n/**\n * The cited words with a faint wash and a small superscript number: quiet text, not a badge.\n * Its one menu (preview of the passage, Open in viewer, Copy citation) is the shared `MarkMenu`.\n */\nconst CitationLink: React.FC<CitationLinkProps> = ({\n citationNum,\n isActive,\n isStreaming,\n items,\n preview,\n triggerRef,\n children,\n}) => (\n <MarkMenu\n triggerRef={triggerRef}\n items={items}\n preview={isStreaming ? undefined : preview}\n menuLabel={`Citation ${citationNum}`}\n testId={`citation-link-${citationNum}`}\n tabIndex={isStreaming ? -1 : 0}\n data-mark-kind=\"citation\"\n className={cn(\n 'cited-text relative rounded-sm px-0.5 transition-colors',\n // 44px touch hit area without changing the text layout.\n \"pointer-coarse:after:absolute pointer-coarse:after:content-[''] pointer-coarse:after:-inset-x-3 pointer-coarse:after:-inset-y-4\",\n isStreaming ? 'cursor-default' : 'cursor-pointer',\n isActive ? 'bg-ai-soft text-foreground' : 'bg-ai-soft/30 hover:bg-ai-soft/70'\n )}\n >\n {children}\n <sup className=\"ml-px align-super text-[0.7em] font-semibold leading-none tabular-nums text-ai-ink\">\n {citationNum}\n </sup>\n </MarkMenu>\n)\n\nexport const CitationRenderer = React.memo(CitationRendererComponent)\n","/**\n * DOC Icon Component. Promoted from the ARBI app for SDK reuse.\n * For Word documents (.doc, .docx files) with blue styling.\n */\n\nimport React from 'react'\nimport { FILE_TYPE_COLORS } from './colors'\n\ninterface DocIconProps {\n size?: number\n className?: string\n}\n\nexport const DocIcon: React.FC<DocIconProps> = ({ size = 16, className = '' }) => {\n return (\n <svg\n width={size}\n height={size}\n viewBox=\"0 0 24 24\"\n fill=\"none\"\n xmlns=\"http://www.w3.org/2000/svg\"\n className={className}\n >\n <path\n d=\"M14 2H6a2 2 0 0 0-2 2v16a2 2 0 0 0 2 2h12a2 2 0 0 0 2-2V8l-6-6z\"\n fill={FILE_TYPE_COLORS.doc}\n stroke={FILE_TYPE_COLORS.doc}\n strokeWidth=\"1\"\n strokeLinecap=\"round\"\n strokeLinejoin=\"round\"\n />\n <path\n d=\"M14 2v6h6\"\n fill=\"none\"\n stroke={FILE_TYPE_COLORS.white}\n strokeWidth=\"1\"\n strokeLinecap=\"round\"\n strokeLinejoin=\"round\"\n />\n <text\n x=\"12\"\n y=\"16\"\n fontSize=\"6\"\n fill=\"white\"\n textAnchor=\"middle\"\n fontWeight=\"bold\"\n fontFamily=\"Arial, sans-serif\"\n >\n DOC\n </text>\n </svg>\n )\n}\n","/**\n * HTML Icon Component. Promoted from the ARBI app for SDK reuse.\n * A proper HTML file icon with sky blue styling for web files.\n */\n\nimport React from 'react'\nimport { FILE_TYPE_COLORS } from './colors'\n\ninterface HtmlIconProps {\n size?: number\n className?: string\n}\n\nexport const HtmlIcon: React.FC<HtmlIconProps> = ({ size = 16, className = '' }) => {\n return (\n <svg\n width={size}\n height={size}\n viewBox=\"0 0 24 24\"\n fill=\"none\"\n xmlns=\"http://www.w3.org/2000/svg\"\n className={className}\n >\n <path\n d=\"M14 2H6a2 2 0 0 0-2 2v16a2 2 0 0 0 2 2h12a2 2 0 0 0 2-2V8l-6-6z\"\n fill={FILE_TYPE_COLORS.html}\n stroke={FILE_TYPE_COLORS.html}\n strokeWidth=\"1\"\n strokeLinecap=\"round\"\n strokeLinejoin=\"round\"\n />\n <path\n d=\"M14 2v6h6\"\n fill=\"none\"\n stroke={FILE_TYPE_COLORS.white}\n strokeWidth=\"1\"\n strokeLinecap=\"round\"\n strokeLinejoin=\"round\"\n />\n <text\n x=\"12\"\n y=\"16\"\n fontSize=\"5\"\n fill=\"white\"\n textAnchor=\"middle\"\n fontWeight=\"bold\"\n fontFamily=\"Arial, sans-serif\"\n >\n HTML\n </text>\n </svg>\n )\n}\n","/**\n * TXT Icon Component. Promoted from the ARBI app for SDK reuse.\n * For text files (.txt) with gray styling.\n */\n\nimport React from 'react'\nimport { FILE_TYPE_COLORS } from './colors'\n\ninterface TxtIconProps {\n size?: number\n className?: string\n}\n\nexport const TxtIcon: React.FC<TxtIconProps> = ({ size = 16, className = '' }) => {\n return (\n <svg\n width={size}\n height={size}\n viewBox=\"0 0 24 24\"\n fill=\"none\"\n xmlns=\"http://www.w3.org/2000/svg\"\n className={className}\n >\n <path\n d=\"M14 2H6a2 2 0 0 0-2 2v16a2 2 0 0 0 2 2h12a2 2 0 0 0 2-2V8l-6-6z\"\n fill={FILE_TYPE_COLORS.txt}\n stroke={FILE_TYPE_COLORS.txt}\n strokeWidth=\"1\"\n strokeLinecap=\"round\"\n strokeLinejoin=\"round\"\n />\n <path\n d=\"M14 2v6h6\"\n fill=\"none\"\n stroke={FILE_TYPE_COLORS.white}\n strokeWidth=\"1\"\n strokeLinecap=\"round\"\n strokeLinejoin=\"round\"\n />\n <text\n x=\"12\"\n y=\"16\"\n fontSize=\"6\"\n fill=\"white\"\n textAnchor=\"middle\"\n fontWeight=\"bold\"\n fontFamily=\"Arial, sans-serif\"\n >\n TXT\n </text>\n </svg>\n )\n}\n","/**\n * XLS Icon Component. Promoted from the ARBI app for SDK reuse.\n * For Excel spreadsheets (.xls, .xlsx files) with green styling.\n */\n\nimport React from 'react'\nimport { FILE_TYPE_COLORS } from './colors'\n\ninterface XlsIconProps {\n size?: number\n className?: string\n}\n\nexport const XlsIcon: React.FC<XlsIconProps> = ({ size = 16, className = '' }) => {\n return (\n <svg\n width={size}\n height={size}\n viewBox=\"0 0 24 24\"\n fill=\"none\"\n xmlns=\"http://www.w3.org/2000/svg\"\n className={className}\n >\n <path\n d=\"M14 2H6a2 2 0 0 0-2 2v16a2 2 0 0 0 2 2h12a2 2 0 0 0 2-2V8l-6-6z\"\n fill={FILE_TYPE_COLORS.xls}\n stroke={FILE_TYPE_COLORS.xls}\n strokeWidth=\"1\"\n strokeLinecap=\"round\"\n strokeLinejoin=\"round\"\n />\n <path\n d=\"M14 2v6h6\"\n fill=\"none\"\n stroke={FILE_TYPE_COLORS.white}\n strokeWidth=\"1\"\n strokeLinecap=\"round\"\n strokeLinejoin=\"round\"\n />\n <text\n x=\"12\"\n y=\"16\"\n fontSize=\"6\"\n fill=\"white\"\n textAnchor=\"middle\"\n fontWeight=\"bold\"\n fontFamily=\"Arial, sans-serif\"\n >\n XLS\n </text>\n </svg>\n )\n}\n","/** Generic file icon (gray, question mark). Promoted from the ARBI app. */\n\nimport React from 'react'\nimport { FILE_TYPE_COLORS } from './colors'\n\ninterface IconProps {\n size?: number\n className?: string\n}\n\nexport const FileIcon: React.FC<IconProps> = ({ size = 16, className = '' }) => {\n return (\n <svg\n width={size}\n height={size}\n viewBox=\"0 0 24 24\"\n fill=\"none\"\n xmlns=\"http://www.w3.org/2000/svg\"\n className={className}\n >\n <path\n d=\"M14 2H6a2 2 0 0 0-2 2v16a2 2 0 0 0 2 2h12a2 2 0 0 0 2-2V8l-6-6z\"\n fill={FILE_TYPE_COLORS.generic}\n stroke={FILE_TYPE_COLORS.generic}\n strokeWidth=\"1\"\n strokeLinecap=\"round\"\n strokeLinejoin=\"round\"\n />\n <path\n d=\"M14 2v6h6\"\n fill=\"none\"\n stroke={FILE_TYPE_COLORS.white}\n strokeWidth=\"1\"\n strokeLinecap=\"round\"\n strokeLinejoin=\"round\"\n />\n <text\n x=\"12\"\n y=\"17\"\n fontSize=\"10\"\n fill=\"white\"\n textAnchor=\"middle\"\n fontWeight=\"bold\"\n fontFamily=\"Arial, sans-serif\"\n >\n ?\n </text>\n </svg>\n )\n}\n","/**\n * Apple Icon Component. Promoted from the ARBI app for SDK reuse.\n */\n\nimport React from 'react'\n\ninterface AppleIconProps {\n size?: number\n className?: string\n 'aria-label'?: string\n 'aria-hidden'?: boolean\n}\n\nexport const AppleIcon: React.FC<AppleIconProps> = ({\n size = 20,\n className = '',\n 'aria-label': ariaLabel,\n 'aria-hidden': ariaHidden = true,\n}) => {\n return (\n <svg\n className={className}\n width={size}\n height={size}\n viewBox=\"0 0 24 24\"\n fill=\"currentColor\"\n aria-label={ariaLabel}\n aria-hidden={ariaHidden}\n >\n <path d=\"M17.05 20.28c-.98.95-2.05.8-3.08.35-1.09-.46-2.09-.48-3.24 0-1.44.62-2.2.44-3.06-.35C2.79 15.25 3.51 7.59 9.05 7.31c1.35.07 2.29.74 3.08.8 1.18-.24 2.31-.93 3.57-.84 1.51.12 2.65.72 3.4 1.8-3.12 1.87-2.38 5.98.48 7.13-.57 1.5-1.31 2.99-2.54 4.09l.01-.01zM12.03 7.25c-.15-2.23 1.66-4.07 3.74-4.25.29 2.58-2.34 4.5-3.74 4.25z\" />\n </svg>\n )\n}\n","/**\n * Google Icon Component. Promoted from the ARBI app for SDK reuse.\n */\n\nimport React from 'react'\n\ninterface GoogleIconProps {\n size?: number\n className?: string\n 'aria-label'?: string\n 'aria-hidden'?: boolean\n}\n\nexport const GoogleIcon: React.FC<GoogleIconProps> = ({\n size = 20,\n className = '',\n 'aria-label': ariaLabel,\n 'aria-hidden': ariaHidden = true,\n}) => {\n return (\n <svg\n className={className}\n width={size}\n height={size}\n viewBox=\"0 0 24 24\"\n aria-label={ariaLabel}\n aria-hidden={ariaHidden}\n >\n <path\n fill=\"#4285F4\"\n 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\"\n />\n <path\n fill=\"#34A853\"\n 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\"\n />\n <path\n fill=\"#FBBC05\"\n 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\"\n />\n <path\n fill=\"#EA4335\"\n 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\"\n />\n </svg>\n )\n}\n","/**\n * GitHub Icon Component. Promoted from the ARBI app for SDK reuse.\n */\n\nimport React from 'react'\n\ninterface GitHubIconProps {\n size?: number\n className?: string\n 'aria-label'?: string\n 'aria-hidden'?: boolean\n}\n\nexport const GitHubIcon: React.FC<GitHubIconProps> = ({\n size = 20,\n className = '',\n 'aria-label': ariaLabel,\n 'aria-hidden': ariaHidden = true,\n}) => {\n return (\n <svg\n className={className}\n width={size}\n height={size}\n viewBox=\"0 0 24 24\"\n fill=\"currentColor\"\n aria-label={ariaLabel}\n aria-hidden={ariaHidden}\n >\n <path\n fillRule=\"evenodd\"\n clipRule=\"evenodd\"\n d=\"M12 2C6.477 2 2 6.484 2 12.017c0 4.425 2.865 8.18 6.839 9.504.5.092.682-.217.682-.483 0-.237-.008-.868-.013-1.703-2.782.605-3.369-1.343-3.369-1.343-.454-1.158-1.11-1.466-1.11-1.466-.908-.62.069-.608.069-.608 1.003.07 1.531 1.032 1.531 1.032.892 1.53 2.341 1.088 2.91.832.092-.647.35-1.088.636-1.338-2.22-.253-4.555-1.113-4.555-4.951 0-1.093.39-1.988 1.029-2.688-.103-.253-.446-1.272.098-2.65 0 0 .84-.27 2.75 1.026A9.564 9.564 0 0112 6.844c.85.004 1.705.115 2.504.337 1.909-1.296 2.747-1.027 2.747-1.027.546 1.379.202 2.398.1 2.651.64.7 1.028 1.595 1.028 2.688 0 3.848-2.339 4.695-4.566 4.943.359.309.678.92.678 1.855 0 1.338-.012 2.419-.012 2.747 0 .268.18.58.688.482A10.019 10.019 0 0022 12.017C22 6.484 17.522 2 12 2z\"\n />\n </svg>\n )\n}\n","/**\n * LinkedIn Icon Component. Promoted from the ARBI app for SDK reuse.\n */\n\nimport React from 'react'\n\ninterface LinkedInIconProps {\n size?: number\n className?: string\n 'aria-label'?: string\n 'aria-hidden'?: boolean\n}\n\nexport const LinkedInIcon: React.FC<LinkedInIconProps> = ({\n size = 20,\n className = '',\n 'aria-label': ariaLabel,\n 'aria-hidden': ariaHidden = true,\n}) => {\n return (\n <svg\n className={className}\n width={size}\n height={size}\n viewBox=\"0 0 24 24\"\n fill=\"#0A66C2\"\n aria-label={ariaLabel}\n aria-hidden={ariaHidden}\n >\n <path d=\"M20.447 20.452h-3.554v-5.569c0-1.328-.027-3.037-1.852-3.037-1.853 0-2.136 1.445-2.136 2.939v5.667H9.351V9h3.414v1.561h.046c.477-.9 1.637-1.85 3.37-1.85 3.601 0 4.267 2.37 4.267 5.455v6.286zM5.337 7.433c-1.144 0-2.063-.926-2.063-2.065 0-1.138.92-2.063 2.063-2.063 1.14 0 2.064.925 2.064 2.063 0 1.139-.925 2.065-2.064 2.065zm1.782 13.019H3.555V9h3.564v11.452zM22.225 0H1.771C.792 0 0 .774 0 1.729v20.542C0 23.227.792 24 1.771 24h20.451C23.2 24 24 23.227 24 22.271V1.729C24 .774 23.2 0 22.222 0h.003z\" />\n </svg>\n )\n}\n","import React from 'react'\n\ninterface IconProps {\n size?: number\n className?: string\n 'aria-label'?: string\n 'aria-hidden'?: boolean\n}\n\nexport const OpenAIIcon: React.FC<IconProps> = ({\n size = 16,\n className = '',\n 'aria-label': ariaLabel = 'OpenAI',\n 'aria-hidden': ariaHidden = true,\n}) => (\n <svg\n className={className}\n width={size}\n height={size}\n viewBox=\"0 0 24 24\"\n aria-label={ariaLabel}\n aria-hidden={ariaHidden}\n >\n <path\n fill=\"#10A37F\"\n 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\"\n />\n </svg>\n)\n","import React from 'react'\n\ninterface IconProps {\n size?: number\n className?: string\n 'aria-label'?: string\n 'aria-hidden'?: boolean\n}\n\nexport const ClaudeIcon: React.FC<IconProps> = ({\n size = 16,\n className = '',\n 'aria-label': ariaLabel = 'Claude',\n 'aria-hidden': ariaHidden = true,\n}) => (\n <svg\n className={className}\n width={size}\n height={size}\n viewBox=\"0 0 24 24\"\n aria-label={ariaLabel}\n aria-hidden={ariaHidden}\n >\n <path\n fill=\"#D97757\"\n 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\"\n />\n </svg>\n)\n","import React from 'react'\n\ninterface IconProps {\n size?: number\n className?: string\n 'aria-label'?: string\n 'aria-hidden'?: boolean\n}\n\nexport const GeminiIcon: React.FC<IconProps> = ({\n size = 16,\n className = '',\n 'aria-label': ariaLabel = 'Gemini',\n 'aria-hidden': ariaHidden = true,\n}) => (\n <svg\n className={className}\n width={size}\n height={size}\n viewBox=\"0 0 24 24\"\n aria-label={ariaLabel}\n aria-hidden={ariaHidden}\n >\n <defs>\n <linearGradient id=\"geminiGradient\" x1=\"0%\" y1=\"0%\" x2=\"100%\" y2=\"100%\">\n <stop offset=\"0%\" stopColor=\"#1BA1E3\" />\n <stop offset=\"25%\" stopColor=\"#5489D6\" />\n <stop offset=\"50%\" stopColor=\"#9B72CB\" />\n <stop offset=\"75%\" stopColor=\"#D96570\" />\n <stop offset=\"100%\" stopColor=\"#F49C46\" />\n </linearGradient>\n </defs>\n <path\n fill=\"url(#geminiGradient)\"\n 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\"\n />\n </svg>\n)\n","import React from 'react'\n\ninterface IconProps {\n size?: number\n className?: string\n 'aria-label'?: string\n 'aria-hidden'?: boolean\n}\n\n/** Fireworks AI brand mark — three-stroke burst in their signature purple\n * (#6720FF). Pulled from fireworks.ai/icon0.svg. */\nexport const FireworksIcon: React.FC<IconProps> = ({\n size = 16,\n className = '',\n 'aria-label': ariaLabel = 'Fireworks AI',\n 'aria-hidden': ariaHidden = true,\n}) => (\n <svg\n className={className}\n width={size}\n height={size}\n viewBox=\"-2 6 36 20\"\n preserveAspectRatio=\"xMidYMid meet\"\n fill=\"none\"\n style={{ minWidth: size, minHeight: size }}\n aria-label={ariaLabel}\n aria-hidden={ariaHidden}\n >\n <path\n fill=\"#6720FF\"\n 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\"\n />\n <path\n fill=\"#6720FF\"\n 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\"\n />\n <path\n fill=\"#6720FF\"\n 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\"\n />\n </svg>\n)\n","import { Crown } from 'lucide-react'\nimport { OpenAIIcon } from './OpenAIIcon'\nimport { ClaudeIcon } from './ClaudeIcon'\nimport { GeminiIcon } from './GeminiIcon'\nimport { GoogleIcon } from './GoogleIcon'\nimport { FireworksIcon } from './FireworksIcon'\n\n/** Pick the best brand mark for a model. We prefer the *product* logo\n * (ChatGPT swirl, Gemini sparkle, Claude burst) when the model_name\n * signals a known product line, falling back to the LiteLLM provider\n * string for everything else. Returns Crown as the universal fallback so\n * Premium-tier rows always render an icon. */\nexport function ProviderIcon({\n modelName,\n provider,\n size = 16,\n className = '',\n}: {\n modelName?: string\n provider?: string | null\n size?: number\n className?: string\n}) {\n const m = (modelName ?? '').toLowerCase()\n const p = (provider ?? '').toLowerCase()\n\n if (m.includes('gpt') || p === 'openai') {\n return <OpenAIIcon size={size} className={className} />\n }\n if (m.includes('claude') || p === 'anthropic') {\n return <ClaudeIcon size={size} className={className} />\n }\n if (m.includes('gemini') || p.startsWith('vertex_ai')) {\n return <GeminiIcon size={size} className={className} />\n }\n if (p === 'google') {\n return <GoogleIcon size={size} className={className} />\n }\n if (p === 'fireworks_ai') {\n return <FireworksIcon size={size} className={className} />\n }\n return (\n <Crown\n className={className}\n style={{ width: size, height: size, color: '#EAB308', fill: '#EAB308' }}\n />\n )\n}\n","/**\n * ARBI Icon Component. Promoted from the ARBI app for SDK reuse.\n * Renders the host app's `/favicon.svg` (the consumer serves the asset).\n */\n\nimport React from 'react'\n\ninterface ArbiIconProps {\n size?: number\n className?: string\n 'aria-label'?: string\n 'aria-hidden'?: boolean\n}\n\nexport const ArbiIcon: React.FC<ArbiIconProps> = ({\n size = 20,\n className = '',\n 'aria-label': ariaLabel = 'ARBI Docs',\n 'aria-hidden': ariaHidden = false,\n}) => {\n return (\n <img\n src=\"/favicon.svg\"\n alt={ariaLabel}\n className={`rounded object-contain ${className}`}\n style={{ width: size, height: size }}\n aria-label={ariaLabel}\n aria-hidden={ariaHidden}\n />\n )\n}\n","import React, { useId } from 'react'\n\ninterface ArbiBotIconProps {\n size?: number\n className?: string\n}\n\nexport const ArbiBotIcon: React.FC<ArbiBotIconProps> = ({ size = 24, className = '' }) => {\n const maskId = useId()\n\n return (\n <svg\n xmlns=\"http://www.w3.org/2000/svg\"\n width={size}\n height={size}\n viewBox=\"0 0 250 250\"\n preserveAspectRatio=\"xMidYMid meet\"\n className={className}\n >\n <defs>\n <mask id={maskId}>\n <g transform=\"translate(0,250) scale(0.1,-0.1)\">\n <rect x=\"0\" y=\"0\" width=\"2500\" height=\"2500\" fill=\"white\" />\n {/* Cut out thick rings around the eyes — annulus shape */}\n <circle cx=\"855\" cy=\"1715\" r=\"190\" fill=\"black\" />\n <circle cx=\"855\" cy=\"1715\" r=\"50\" fill=\"white\" />\n <circle cx=\"1665\" cy=\"1700\" r=\"190\" fill=\"black\" />\n <circle cx=\"1665\" cy=\"1700\" r=\"50\" fill=\"white\" />\n </g>\n </mask>\n </defs>\n <g mask={`url(#${maskId})`}>\n <g\n transform=\"translate(0,250) scale(0.1,-0.1)\"\n fill=\"currentColor\"\n stroke=\"currentColor\"\n strokeWidth=\"100\"\n >\n <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\" />\n </g>\n <g transform=\"translate(0,250) scale(0.1,-0.1)\" fill=\"currentColor\" stroke=\"none\">\n <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\" />\n <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\" />\n <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\" />\n <g transform=\"translate(564,0)\">\n <path\n d=\"M515 353 c-49 -136 -91 -253 -93 -261 -3 -10 11 -12 60 -10 l63 3 19 53 19 52 91 0 92 0 18 -55 17 -56 62 3 c76 4 79 -24 -30 275 l-88 243 -70 0 -70 0 -90 -247z m215 -55 c0 -4 -27 -8 -59 -8 l-60 0 31 92 31 93 29 -85 c15 -46 28 -88 28 -92z\"\n stroke=\"currentColor\"\n strokeWidth=\"30\"\n />\n </g>\n </g>\n </g>\n </svg>\n )\n}\n","/**\n * Notification-type presentation primitives — the brand-neutral icon, colour and\n * label maps for every `NotificationType`, plus the workspace-membership phrasing\n * helpers. Kept in their own module (not a component file) so both the monolith's\n * AG-Grid notification centre and lightweight consumers (e.g. clarum's activity\n * feed) share one source of truth for \"what does this notification type mean\",\n * and so component files stay fast-refresh friendly.\n *\n * Deliberately decoupled: no store, no app `@/` imports — just lucide icon\n * components + semantic Tailwind token class names. Callers render the icon\n * themselves (`<Icon className={iconClassName} />`).\n */\n\nimport {\n Activity,\n Gauge,\n Gift,\n Info,\n MessageCircleMore,\n PartyPopper,\n UserCheck,\n} from 'lucide-react'\nimport { getEntityIcon, type EntityIconComponent } from '../entities/registry'\n\n/** Icon component, its colour class, and a short human label for a notification type. */\nexport interface NotificationTypeMeta {\n Icon: EntityIconComponent\n /** Semantic Tailwind colour class for the glyph. */\n iconClassName: string\n /** Short category label (e.g. \"Added\", \"Usage 90%\"). */\n label: string\n}\n\n/**\n * Resolve the icon + colour + short label for a notification type.\n *\n * Workspace-membership events all share the workspace glyph — the specific role\n * lives in the Event sentence (see {@link getWorkspaceSentPhrase}), so the label\n * stays short (\"Added\", not \"Added as collaborator\"). Unknown types fall back to\n * an info glyph and the raw type string.\n */\nexport function getNotificationTypeMeta(type: string | null | undefined): NotificationTypeMeta {\n // Resolve the workspace glyph live (not at module load) so a deployment's\n // configureEntityRegistry() injection is always reflected, regardless of import order.\n const WorkspaceIcon = getEntityIcon('WORKSPACE') as EntityIconComponent\n switch (type) {\n case 'user_message':\n return { Icon: MessageCircleMore, iconClassName: 'text-primary', label: 'Message' }\n case 'workspaceuser_added_owner':\n case 'workspaceuser_added_collaborator':\n case 'workspaceuser_added_guest':\n return { Icon: WorkspaceIcon, iconClassName: 'text-primary', label: 'Added' }\n case 'workspaceuser_removed':\n return { Icon: WorkspaceIcon, iconClassName: 'text-primary', label: 'Removed' }\n case 'workspaceuser_updated_owner':\n case 'workspaceuser_updated_collaborator':\n case 'workspaceuser_updated_guest':\n return { Icon: WorkspaceIcon, iconClassName: 'text-primary', label: 'Role changed' }\n case 'contact_accepted':\n return { Icon: UserCheck, iconClassName: 'text-green-500', label: 'Invitation' }\n case 'signup_reward':\n return { Icon: PartyPopper, iconClassName: 'text-green-600', label: 'Signup bonus' }\n case 'referral_reward':\n return { Icon: Gift, iconClassName: 'text-green-600', label: 'Reward earned' }\n case 'quota_threshold_50':\n return { Icon: Gauge, iconClassName: 'text-blue-500', label: 'Usage 50%' }\n case 'quota_threshold_90':\n return { Icon: Gauge, iconClassName: 'text-orange-500', label: 'Usage 90%' }\n case 'quota_threshold_100':\n return { Icon: Gauge, iconClassName: 'text-red-500', label: 'Usage limit' }\n case 'activity':\n // Durable to-self activity line — the specific event lives in `content`.\n // Callers that have the content should prefer describeActivity() for a\n // precise glyph/label; this is the type-only fallback.\n return { Icon: Activity, iconClassName: 'text-muted-foreground', label: 'Activity' }\n default:\n return { Icon: Info, iconClassName: 'text-blue-500', label: type || 'Notification' }\n }\n}\n\n/** Whether a notification type is a workspace-membership event. */\nexport function isWorkspaceNotificationType(type: string): boolean {\n return type.startsWith('workspaceuser_')\n}\n\n/**\n * Recipient-perspective action text (\"you received\"). Renders after the sender\n * pill: \"[sender] added you as collaborator\". The workspace renders in its own\n * column, so there's no trailing preposition.\n */\nexport function getWorkspaceActionText(type: string): string {\n switch (type) {\n case 'workspaceuser_added_owner':\n return 'added you as owner'\n case 'workspaceuser_added_collaborator':\n return 'added you as collaborator'\n case 'workspaceuser_added_guest':\n return 'added you as guest'\n case 'workspaceuser_removed':\n return 'removed you'\n case 'workspaceuser_updated_owner':\n return 'changed your role to owner'\n case 'workspaceuser_updated_collaborator':\n return 'changed your role to collaborator'\n case 'workspaceuser_updated_guest':\n return 'changed your role to guest'\n default:\n return 'updated your access'\n }\n}\n\n/**\n * Sender-perspective phrasing (\"you did this\"). Renders around the affected\n * member pill — `{before} [member] {after}` — so it reads as an active sentence:\n * \"You added [Jane] as collaborator\" rather than the ambiguous \"Added as\n * collaborator: Jane\".\n */\nexport function getWorkspaceSentPhrase(type: string): { before: string; after: string } {\n switch (type) {\n case 'workspaceuser_added_owner':\n return { before: 'You added', after: 'as owner' }\n case 'workspaceuser_added_collaborator':\n return { before: 'You added', after: 'as collaborator' }\n case 'workspaceuser_added_guest':\n return { before: 'You added', after: 'as guest' }\n case 'workspaceuser_removed':\n return { before: 'You removed', after: '' }\n case 'workspaceuser_updated_owner':\n return { before: 'You set', after: 'as owner' }\n case 'workspaceuser_updated_collaborator':\n return { before: 'You set', after: 'as collaborator' }\n case 'workspaceuser_updated_guest':\n return { before: 'You set', after: 'as guest' }\n default:\n return { before: 'You updated access for', after: '' }\n }\n}\n","/**\n * Activity-event presentation — decodes the compact `{\"event\": ..., ...fields}`\n * JSON payload carried by durable `activity` notifications (recorded backend-side\n * by `log_activity`) into a glyph + human sentence.\n *\n * Distinct from `notification-types.ts`: that maps the notification *type* (a DM,\n * a workspace-membership change, a reward); this maps the *event* recorded on a\n * to-self activity line (\"opened a workspace\", \"processed a document\"). Entity\n * glyphs are sourced from the shared entity registry — one source of truth.\n */\n\nimport {\n Activity,\n FileCheck2,\n FileX2,\n FolderPlus,\n Pencil,\n SquareArrowOutUpRight,\n Trash2,\n} from 'lucide-react'\nimport { getEntityIcon, type EntityIconComponent } from '../entities/registry'\n\n/** Parsed activity payload — always has `event`, plus event-specific fields. */\nexport interface ActivityContent {\n event: string\n [field: string]: unknown\n}\n\n/** Rendered description of an activity line. */\nexport interface ActivityDescription {\n Icon: EntityIconComponent\n /** Semantic Tailwind colour class for the glyph. */\n iconClassName: string\n /** Human-readable one-line summary of what happened. */\n title: string\n}\n\n/** Parse an activity notification's `content` JSON into `{event, ...fields}`, or null. */\nexport function parseActivityContent(content: string | null | undefined): ActivityContent | null {\n if (!content) return null\n try {\n const parsed = JSON.parse(content)\n if (parsed && typeof parsed === 'object' && typeof parsed.event === 'string') {\n return parsed as ActivityContent\n }\n } catch {\n // Not JSON (e.g. a legacy plain-string activity line) — no structured event.\n }\n return null\n}\n\nfunction str(v: unknown): string | undefined {\n return typeof v === 'string' && v ? v : undefined\n}\n\n/**\n * Describe an activity line for display. Accepts either the raw `content` string\n * or an already-parsed {@link ActivityContent}. Unknown/unparseable events fall\n * back to a generic activity glyph and a humanised event name.\n */\nexport function describeActivity(\n content: string | ActivityContent | null | undefined\n): ActivityDescription {\n const parsed =\n typeof content === 'string' || content == null ? parseActivityContent(content) : content\n\n if (!parsed) {\n return { Icon: Activity, iconClassName: 'text-muted-foreground', title: 'Activity' }\n }\n\n const fileName = str(parsed.file_name)\n\n switch (parsed.event) {\n case 'workspace_opened':\n return {\n Icon: SquareArrowOutUpRight,\n iconClassName: 'text-primary',\n title: 'Opened a workspace',\n }\n case 'workspace_created':\n return { Icon: FolderPlus, iconClassName: 'text-green-600', title: 'Created a workspace' }\n case 'workspace_updated':\n return { Icon: Pencil, iconClassName: 'text-primary', title: 'Updated workspace settings' }\n case 'workspace_deleted':\n return { Icon: Trash2, iconClassName: 'text-red-500', title: 'Deleted a workspace' }\n case 'document_processing': {\n const failed = str(parsed.status) === 'failed'\n const noun = fileName ? `“${fileName}”` : 'a document'\n return failed\n ? { Icon: FileX2, iconClassName: 'text-red-500', title: `Failed to process ${noun}` }\n : { Icon: FileCheck2, iconClassName: 'text-green-600', title: `Processed ${noun}` }\n }\n default:\n // Humanise an unrecognised event slug: \"some_new_event\" → \"Some new event\".\n return {\n Icon: parsed.workspace_ext_id\n ? (getEntityIcon('WORKSPACE') as EntityIconComponent)\n : Activity,\n iconClassName: 'text-muted-foreground',\n title: humaniseEvent(parsed.event),\n }\n }\n}\n\n/** \"workspace_opened\" → \"Workspace opened\" — a readable fallback for new events. */\nfunction humaniseEvent(event: string): string {\n const words = event.replace(/[_-]+/g, ' ').trim()\n return words ? words.charAt(0).toUpperCase() + words.slice(1) : 'Activity'\n}\n","/**\n * ActivityFeed — a presentational, self-fetching list of the current user's\n * durable activity (the to-self \"you opened a workspace / processed a document\"\n * log). Renders each line via the shared {@link describeActivity} descriptor, so\n * the glyph/label knowledge stays in one place and any app (clarum's dashboard,\n * a monolith panel) can drop this in.\n *\n * Pure semantic Tailwind tokens; no store, no app `@/` imports. Data comes from\n * the shared {@link useActivity} query.\n */\n\nimport { Activity } from 'lucide-react'\nimport { useActivity } from '../hooks'\nimport { cn } from '../lib/utils'\nimport { describeActivity } from './activity-types'\n\n/** Relative time like \"just now\", \"3m\", \"2h\", \"5d\"; falls back to a date. */\nfunction formatRelative(iso: string): string {\n const then = new Date(iso).getTime()\n if (Number.isNaN(then)) return ''\n const secs = Math.round((Date.now() - then) / 1000)\n if (secs < 45) return 'just now'\n const mins = Math.round(secs / 60)\n if (mins < 60) return `${mins}m`\n const hours = Math.round(mins / 60)\n if (hours < 24) return `${hours}h`\n const days = Math.round(hours / 24)\n if (days < 7) return `${days}d`\n return new Date(iso).toLocaleDateString()\n}\n\nexport interface ActivityFeedProps {\n /** Max entries to fetch/show. Default 20. */\n limit?: number\n /** Extra classes for the outer container. */\n className?: string\n /** Message shown when there's no activity yet. */\n emptyLabel?: string\n /** Whether to fetch — defaults to enabled when logged in. */\n enabled?: boolean\n 'data-testid'?: string\n}\n\n/**\n * Renders the activity feed. Handles its own loading/empty/error states so a\n * consumer can place it directly (e.g. inside a dashboard card).\n */\nexport function ActivityFeed({\n limit = 20,\n className,\n emptyLabel = 'No recent activity',\n enabled,\n 'data-testid': testId = 'activity-feed',\n}: ActivityFeedProps) {\n const { data, isLoading, isError } = useActivity({ limit, enabled })\n\n if (isLoading) {\n return (\n <div className={cn('space-y-2', className)} data-testid={testId} aria-busy=\"true\">\n {Array.from({ length: 3 }).map((_, i) => (\n <div key={i} className=\"flex items-center gap-3 py-1.5\">\n <div className=\"h-4 w-4 shrink-0 animate-pulse rounded-full bg-muted\" />\n <div className=\"h-3 flex-1 animate-pulse rounded bg-muted\" />\n </div>\n ))}\n </div>\n )\n }\n\n if (isError) {\n return (\n <div className={cn('text-sm text-muted-foreground', className)} data-testid={testId}>\n Couldn’t load activity.\n </div>\n )\n }\n\n const items = data ?? []\n if (items.length === 0) {\n return (\n <div\n className={cn('flex items-center gap-2 text-sm text-muted-foreground', className)}\n data-testid={testId}\n >\n <Activity className=\"h-4 w-4 shrink-0\" />\n <span>{emptyLabel}</span>\n </div>\n )\n }\n\n return (\n <ul className={cn('divide-y divide-border', className)} data-testid={testId}>\n {items.map((item) => {\n const desc = describeActivity(item.content)\n return (\n <li\n key={item.external_id}\n className=\"flex items-center gap-3 py-2\"\n data-testid=\"activity-feed-item\"\n >\n <desc.Icon className={cn('h-4 w-4 shrink-0', desc.iconClassName)} />\n <span className=\"min-w-0 flex-1 truncate text-sm text-foreground\">{desc.title}</span>\n <time className=\"shrink-0 text-xs tabular-nums text-muted-foreground\">\n {formatRelative(item.created_at)}\n </time>\n </li>\n )\n })}\n </ul>\n )\n}\n","/** Small presentation helpers for the DM kit. */\n\nimport type { DmUser } from './types'\n\n/** Initials from a user's name (falls back to the email local-part). */\nexport function userInitials(user: Pick<DmUser, 'given_name' | 'family_name' | 'email'>): string {\n const parts = [user.given_name, user.family_name].filter(Boolean) as string[]\n if (parts.length) {\n return parts\n .map((p) => p[0]?.toUpperCase() ?? '')\n .join('')\n .slice(0, 2)\n }\n const local = user.email?.split('@')[0] ?? ''\n return local.slice(0, 2).toUpperCase() || '?'\n}\n\n/** Full display name (falls back to the email local-part). */\nexport function userDisplayName(\n user: Pick<DmUser, 'given_name' | 'family_name' | 'email'>\n): string {\n const name = [user.given_name, user.family_name].filter(Boolean).join(' ').trim()\n return name || user.email?.split('@')[0] || 'Unknown'\n}\n\n/**\n * Whether a peer is an agent rather than a person.\n *\n * Derived from the `agt-` external-id prefix, which is the platform's own\n * convention and already assumed elsewhere in the kit (entity colours are keyed\n * off the same ids). Deriving it once here is what lets every DM surface mark\n * agents without each consumer having to resolve and pass a flag.\n */\nexport function isAgentUser(user: Pick<DmUser, 'external_id'>): boolean {\n return user.external_id.startsWith('agt-')\n}\n\nexport { formatRelativeTime } from '../lib/format-relative-time'\n","/**\n * useDirectMessages — the data layer for the DM block kit.\n *\n * Sits entirely on top of the SDK's encrypted-by-default `arbi.dm` surface:\n * it never touches `/v1/notifications` or crypto directly. It lists decrypted\n * DMs, groups them into per-peer conversations, refreshes live over the shared\n * WebSocket, and exposes send / mark-read mutations.\n *\n * Requires an <ArbiWebSocketProvider> above it for live updates (standard in\n * the ARBI provider stack).\n */\n\nimport { useEffect, useMemo, useState } from 'react'\nimport { useQuery, useMutation, useQueryClient } from '@tanstack/react-query'\nimport type { WsNotificationResponse } from '@arbidocs/client'\nimport { useArbi } from '../useArbi'\nimport { useArbiWsMessage } from '../websocket'\nimport { userDisplayName } from './utils'\nimport type { DmConversation, DmMessage, DmNotification, DmUser } from './types'\n\nconst DM_QUERY_KEY = ['arbi', 'directMessages'] as const\nconst CONTACTS_QUERY_KEY = ['arbi', 'contacts'] as const\n\n/**\n * Merge the user's contacts into the thread list so every colleague appears in\n * the rail — those with history keep their thread, those without show as an\n * empty conversation ready to start. Contacts still pending sign-up (no linked\n * user) are skipped. Threads with a peer who isn't a contact (e.g. an agent you\n * were added to) are preserved.\n */\nfunction mergeContacts(\n threads: DmConversation[],\n contacts: { user?: DmUser | null }[]\n): DmConversation[] {\n const byPeer = new Map<string, DmConversation>()\n for (const t of threads) byPeer.set(t.peer.external_id, t)\n\n for (const c of contacts) {\n const peer = c.user\n if (!peer?.external_id || byPeer.has(peer.external_id)) continue\n byPeer.set(peer.external_id, { peer, messages: [], unreadCount: 0, isContactOnly: true })\n }\n\n // Threads with activity first (most recent), then message-less contacts A→Z.\n return [...byPeer.values()].sort((a, b) => {\n const at = a.lastMessage?.createdAt\n const bt = b.lastMessage?.createdAt\n if (at && bt) return bt.localeCompare(at)\n if (at) return -1\n if (bt) return 1\n return userDisplayName(a.peer).localeCompare(userDisplayName(b.peer))\n })\n}\n\n/** Group a flat, decrypted DM list into per-peer conversations. */\nfunction groupConversations(\n notifications: DmNotification[],\n myExtId: string | null\n): DmConversation[] {\n const messagesByPeer = new Map<string, DmMessage[]>()\n const peers = new Map<string, DmUser>()\n\n for (const n of notifications) {\n if (n.type !== 'user_message') continue\n // Skip self-notifications (sender == recipient == me): not a real thread.\n if (n.sender.external_id === n.recipient.external_id) continue\n\n const isMine = n.sender.external_id === myExtId\n const peer = isMine ? n.recipient : n.sender\n if (!peer?.external_id) continue\n\n const message: DmMessage = {\n externalId: n.external_id,\n body: n.content ?? '',\n createdAt: n.created_at,\n isMine,\n read: n.read,\n sender: n.sender,\n recipient: n.recipient,\n }\n\n if (!messagesByPeer.has(peer.external_id)) {\n messagesByPeer.set(peer.external_id, [])\n peers.set(peer.external_id, peer)\n }\n messagesByPeer.get(peer.external_id)!.push(message)\n }\n\n const conversations: DmConversation[] = []\n for (const [peerId, messages] of messagesByPeer) {\n messages.sort((a, b) => a.createdAt.localeCompare(b.createdAt))\n const unreadCount = messages.filter((m) => !m.isMine && !m.read).length\n conversations.push({\n peer: peers.get(peerId)!,\n messages,\n lastMessage: messages[messages.length - 1],\n unreadCount,\n })\n }\n // Most recently active conversations first.\n // Every conversation built here has messages, so lastMessage is always set.\n conversations.sort((a, b) => b.lastMessage!.createdAt.localeCompare(a.lastMessage!.createdAt))\n return conversations\n}\n\nexport interface UseDirectMessagesResult {\n /** Per-peer conversations, most recently active first. */\n conversations: DmConversation[]\n /** The current user's external_id (for ownership checks), or null if unknown. */\n myExtId: string | null\n isLoading: boolean\n isError: boolean\n error: unknown\n refetch: () => void\n /** Send a message to a known peer (extId + public key from a conversation). */\n sendMessage: (\n recipientExtId: string,\n recipientPublicKey: string,\n text: string\n ) => Promise<unknown>\n /** Send by email / external_id, resolving the recipient's key internally. */\n sendMessageTo: (recipient: string, text: string) => Promise<unknown>\n isSending: boolean\n /** The last send failure, or null. A failed send must never pass silently. */\n sendError: Error | null\n /** Mark the given message ids as read. */\n markRead: (messageIds: string[]) => Promise<unknown>\n}\n\nexport function useDirectMessages(options?: { enabled?: boolean }): UseDirectMessagesResult {\n const arbi = useArbi()\n const queryClient = useQueryClient()\n const enabled = options?.enabled ?? arbi.isLoggedIn\n\n const query = useQuery({\n queryKey: DM_QUERY_KEY,\n queryFn: () => arbi.dm.list(),\n enabled,\n })\n\n // Contacts drive the rail: every colleague shows, with or without history.\n const contactsQuery = useQuery({\n queryKey: CONTACTS_QUERY_KEY,\n queryFn: () => arbi.contacts.list(),\n enabled,\n })\n\n // Live: a new DM arrives as a `user_message` notification over the socket.\n useArbiWsMessage<WsNotificationResponse>('user_message', () => {\n queryClient.invalidateQueries({ queryKey: DM_QUERY_KEY })\n })\n\n // Read straight from the session on every render rather than memoising: it is a\n // cheap synchronous lookup, and a stale `null` here would misfile every message\n // we sent (`isMine` false → the message lands in a thread keyed by ourselves).\n let myExtId: string | null = null\n try {\n myExtId = arbi.user.identity()?.externalId ?? null\n } catch {\n myExtId = null\n }\n\n // Messages this session has sent, held until the server's own list reports\n // them back. Writing them into the query cache instead would not survive the\n // refetch that follows the send: `GET /v1/notifications/` is eventually\n // consistent, so a refetch that lands before the write propagates would\n // overwrite the cache and the message would vanish out of the open thread.\n const [pendingSent, setPendingSent] = useState<DmNotification[]>([])\n\n const serverIds = useMemo(\n () => new Set((query.data ?? []).map((n) => n.external_id)),\n [query.data]\n )\n\n // Drop each pending send the moment the server acknowledges it, so the two\n // copies can never both be rendered.\n useEffect(() => {\n setPendingSent((pending) =>\n pending.some((n) => serverIds.has(n.external_id))\n ? pending.filter((n) => !serverIds.has(n.external_id))\n : pending\n )\n }, [serverIds])\n\n const conversations = useMemo(() => {\n // Newest first, matching the server's ordering.\n const all = [...pendingSent.filter((n) => !serverIds.has(n.external_id)), ...(query.data ?? [])]\n return mergeContacts(groupConversations(all, myExtId), contactsQuery.data ?? [])\n }, [query.data, serverIds, pendingSent, contactsQuery.data, myExtId])\n\n const invalidate = () => queryClient.invalidateQueries({ queryKey: DM_QUERY_KEY })\n\n /**\n * Hold on to the notifications the send just created, then reconcile with the\n * server. The SDK hands them back already decrypted, so a sent message renders\n * immediately and never depends on a second network round-trip (or on\n * re-decrypting our own ciphertext) to become visible.\n */\n const absorbSent = (created: DmNotification[]) => {\n setPendingSent((pending) => [...created, ...pending])\n invalidate()\n }\n\n const sendMutation = useMutation({\n mutationFn: (vars: { recipientExtId: string; recipientPublicKey: string; text: string }) =>\n arbi.dm.sendTo(vars.recipientExtId, vars.recipientPublicKey, vars.text),\n onSuccess: absorbSent,\n })\n\n const sendToMutation = useMutation({\n mutationFn: (vars: { recipient: string; text: string }) =>\n arbi.dm.send(vars.recipient, vars.text),\n onSuccess: absorbSent,\n })\n\n const markReadMutation = useMutation({\n mutationFn: (messageIds: string[]) => arbi.dm.markRead(messageIds),\n onSuccess: invalidate,\n })\n\n return {\n conversations,\n myExtId,\n isLoading: (query.isLoading || contactsQuery.isLoading) && enabled,\n isError: query.isError,\n error: query.error,\n refetch: () => query.refetch(),\n sendMessage: (recipientExtId, recipientPublicKey, text) =>\n sendMutation.mutateAsync({ recipientExtId, recipientPublicKey, text }),\n sendMessageTo: (recipient, text) => sendToMutation.mutateAsync({ recipient, text }),\n isSending: sendMutation.isPending || sendToMutation.isPending,\n sendError: sendMutation.error ?? sendToMutation.error,\n markRead: (messageIds) => markReadMutation.mutateAsync(messageIds),\n }\n}\n","/**\n * A peer avatar in a DM surface.\n *\n * This used to be its own small avatar that knew nothing about agents or\n * presence, which is why the ARBI app replaced it on every row with a\n * hand-rolled variant of its own. It is now a thin adapter over\n * {@link UserEntity} — the one presentational person component — so a DM row, a\n * members table and a document owner all draw a person the same way.\n *\n * The name and props are unchanged: it is exported from the package, and\n * consumers should not have to care that the implementation collapsed.\n */\n\nimport { UserEntity, type PresenceDisplayStatus } from '../entities/UserEntity'\nimport { getEntityColorStyles } from '../entities/colors'\nimport { useArbiWsStore } from '../websocket/store'\nimport type { DmUser } from './types'\nimport { userDisplayName, userInitials, isAgentUser } from './utils'\n\nexport interface DmAvatarProps {\n user: DmUser\n className?: string\n /** Defaults to the 40px row avatar this component has always drawn. */\n size?: 'xs' | 'sm' | 'md' | 'lg'\n}\n\nexport function DmAvatar({ user, className, size = 'lg' }: DmAvatarProps) {\n // Presence comes from the shared WS store, which stays empty until an app\n // mounts ArbiWebSocketProvider. That is deliberate: with no socket we know\n // nothing about who is online, and `undefined` hides the dot rather than\n // asserting that everyone is offline.\n const presence = useArbiWsStore((s) => s.presence[user.external_id])\n const displayStatus: PresenceDisplayStatus | undefined =\n presence === undefined ? undefined : presence === 'online' ? 'connected' : 'disconnected'\n\n return (\n <UserEntity\n variant=\"icon\"\n size={size}\n className={className}\n interactive={false}\n showTooltip={false}\n initials={userInitials(user)}\n displayName={userDisplayName(user)}\n picture={user.picture}\n // Deterministic tint from the user's id so the fallback is stable + distinct.\n avatarStyle={getEntityColorStyles(user.external_id)}\n isAgent={isAgentUser(user)}\n displayStatus={displayStatus}\n />\n )\n}\n","/**\n * The left rail: a scrollable list of 1:1 conversations, each showing the peer\n * avatar, name, last-message preview, relative time, and an unread pill.\n */\n\nimport { Check, CheckCheck } from 'lucide-react'\nimport { Badge } from '../ui/badge'\nimport { cn } from '../lib/utils'\nimport type { DmClassNames, DmConversation } from './types'\nimport { formatRelativeTime, userDisplayName, isAgentUser } from './utils'\nimport { DmAvatar } from './DmAvatar'\nimport { AgentBadge } from '../entities/AgentMarkers'\n\nexport interface ConversationListProps {\n conversations: DmConversation[]\n selectedPeerId: string | null\n onSelect: (peerId: string) => void\n classNames?: Pick<DmClassNames, 'unreadBadge'>\n /** Rendered when there are no conversations. */\n emptyState?: React.ReactNode\n /**\n * Replaces the default \"Conversations / N colleagues\" heading — e.g. with a\n * call to action. Pass `null` for no heading at all.\n */\n header?: React.ReactNode\n /**\n * Overrides the rail's own sizing. The default is a fixed-width column beside\n * a thread; a consumer showing the list on its own needs it to fill instead,\n * and cannot get there by wrapping (a narrower wrapper clips rather than\n * shrinks).\n */\n className?: string\n}\n\nexport function ConversationList({\n conversations,\n selectedPeerId,\n onSelect,\n classNames,\n emptyState,\n header,\n className,\n}: ConversationListProps) {\n return (\n <aside\n className={cn(\n 'flex min-h-0 flex-col border-b border-border md:w-80 md:shrink-0 md:border-b-0 md:border-r',\n className\n )}\n data-testid=\"arbi-dm-list\"\n >\n {header === undefined ? (\n <div className=\"border-b border-border px-4 py-3\">\n <p className=\"text-sm font-semibold text-foreground\">Conversations</p>\n <p className=\"text-xs text-muted-foreground\">\n {conversations.length} {conversations.length === 1 ? 'colleague' : 'colleagues'}\n </p>\n </div>\n ) : (\n header\n )}\n <div className=\"min-h-0 flex-1 overflow-y-auto\">\n {conversations.length === 0 ? (\n <div className=\"px-4 py-6 text-xs text-muted-foreground\">\n {emptyState ?? 'No conversations yet.'}\n </div>\n ) : (\n <ul className=\"w-full\">\n {conversations.map((c, i) => {\n const { peer, lastMessage, unreadCount } = c\n // The heading renders once, above the first row of its group.\n const newSection =\n c.sectionLabel && c.sectionLabel !== conversations[i - 1]?.sectionLabel\n const active = peer.external_id === selectedPeerId\n const preview = lastMessage?.body ?? 'No messages yet — say hello'\n // Unread rows carry weight, which is the signal you catch scanning\n // a list — the count alone is a detail you have to go looking for.\n const unread = unreadCount > 0\n const body = (\n <>\n {c.leading ?? <DmAvatar user={peer} />}\n <div className=\"min-w-0 flex-1\">\n {/* Count sits with the name; the time sits with the message\n it belongs to. They were the other way round, which put\n \"just now\" beside a name it said nothing about. */}\n <div className=\"flex items-center justify-between gap-2\">\n <span className=\"flex min-w-0 items-center gap-1.5\">\n <span\n className={cn(\n 'truncate text-sm text-foreground',\n unread ? 'font-bold' : 'font-semibold'\n )}\n >\n {userDisplayName(peer)}\n </span>\n {/* An agent is marked by default — a consumer only\n supplies `badge` to say something else. */}\n {c.badge ?? (isAgentUser(peer) ? <AgentBadge /> : null)}\n </span>\n {c.statusLabel ? (\n <Badge\n variant=\"outline\"\n className=\"shrink-0 rounded-full px-2 py-0 text-xs font-medium text-muted-foreground\"\n >\n {c.statusLabel}\n </Badge>\n ) : unreadCount > 0 ? (\n // Quiet by default: a filled brand pill with a shadow\n // shouted louder than the message it was counting.\n // Enough to catch the eye scanning the list, no more.\n <Badge\n variant=\"accent\"\n className={cn(\n 'min-w-[1.125rem] justify-center rounded-full px-1 py-0 text-xs font-medium leading-[1.125rem] shadow-none',\n classNames?.unreadBadge\n )}\n >\n {unreadCount}\n </Badge>\n ) : null}\n </div>\n <div className=\"mt-1 flex items-center gap-1.5\">\n {/* Your own last message is marked with the same tick the\n bubble carries — one delivered, two read. It says who\n spoke last AND whether it landed, which a \"You:\" prefix\n cannot, and costs no preview width. */}\n {lastMessage?.isMine ? (\n lastMessage.read ? (\n <CheckCheck\n className=\"size-3.5 shrink-0 text-ai-accent\"\n aria-label=\"Read\"\n />\n ) : (\n <Check\n className=\"size-3.5 shrink-0 text-muted-foreground\"\n aria-label=\"Sent\"\n />\n )\n ) : null}\n <p\n className={cn(\n 'min-w-0 flex-1 truncate text-xs',\n unread ? 'font-medium text-foreground' : 'text-muted-foreground'\n )}\n >\n {c.subtitle ?? preview}\n </p>\n <span className=\"shrink-0 text-xs text-muted-foreground\">\n {lastMessage ? formatRelativeTime(lastMessage.createdAt) : ''}\n </span>\n </div>\n </div>\n </>\n )\n\n // An invitation that nobody has accepted has no thread to open, so\n // it is listed but not offered as something to click.\n const rowClass = cn(\n // Each row is its own opaque surface. Left transparent it takes\n // the panel's colour, and the chips stop reading as cards at all\n // — which is the whole point of them.\n 'flex w-full items-start gap-3 border-b border-border/60 bg-card px-4 py-3 text-left transition-colors',\n c.disabled ? 'cursor-default' : active ? 'bg-ai-accent-soft' : 'hover:bg-accent/40'\n )\n\n return (\n <li key={peer.external_id}>\n {newSection && (\n <p\n className=\"bg-muted/40 px-4 py-1.5 text-xs font-medium uppercase tracking-wide text-muted-foreground\"\n data-testid=\"arbi-dm-section\"\n >\n {c.sectionLabel}\n </p>\n )}\n {c.disabled ? (\n <div\n data-testid={`arbi-dm-conversation-${peer.external_id}`}\n className={rowClass}\n >\n {body}\n {c.trailing}\n </div>\n ) : (\n <button\n type=\"button\"\n onClick={() => onSelect(peer.external_id)}\n data-testid={`arbi-dm-conversation-${peer.external_id}`}\n className={rowClass}\n >\n {body}\n </button>\n )}\n </li>\n )\n })}\n </ul>\n )}\n </div>\n </aside>\n )\n}\n","/**\n * Thread grouping: the two annotations a readable message list needs.\n *\n * A run is a burst from one sender close together in time; only its last\n * message carries the meta row (sender, time, receipt), so ten rapid messages\n * read as one block instead of ten stamped rows. A day boundary gets a\n * separator so a thread spanning weeks stays navigable.\n *\n * Generic over the message shape because the two consumers hold different ones —\n * the block's `DmMessage` and the ARBI app's decrypted notification rows — and\n * duplicating this logic is exactly how they drifted apart before.\n */\n\n/** Two messages belong to the same run when same sender and within this gap. */\nexport const RUN_WINDOW_MS = 2 * 60 * 1000\n\nexport interface ThreadItem<T> {\n message: T\n /** Last of a same-sender run: render the meta row here. */\n isLastOfRun: boolean\n /** First message on its calendar day: render a date separator above it. */\n isFirstOfDay: boolean\n}\n\nexport interface ThreadAccessors<T> {\n senderId: (message: T) => string\n createdAt: (message: T) => string\n}\n\n/**\n * Local calendar day for a timestamp.\n *\n * Deliberately local rather than UTC: a message sent at 23:30 in the reader's\n * zone belongs under that day's separator, not tomorrow's. Falls back to the\n * raw string for an unparseable timestamp so such a message still buckets\n * consistently with itself rather than joining an arbitrary day.\n */\nexport function dayKey(iso: string): string {\n const d = new Date(iso)\n if (Number.isNaN(d.getTime())) return iso\n return `${d.getFullYear()}-${d.getMonth() + 1}-${d.getDate()}`\n}\n\n/** Annotate messages (ascending time order) with run and day boundaries. */\nexport function annotateThread<T>(\n messages: T[],\n accessors: ThreadAccessors<T>,\n runWindowMs: number = RUN_WINDOW_MS\n): ThreadItem<T>[] {\n const { senderId, createdAt } = accessors\n return messages.map((message, i) => {\n const next = messages[i + 1]\n const prev = messages[i - 1]\n const day = dayKey(createdAt(message))\n\n const continuesIntoNext =\n !!next &&\n senderId(next) === senderId(message) &&\n dayKey(createdAt(next)) === day &&\n Date.parse(createdAt(next)) - Date.parse(createdAt(message)) < runWindowMs\n\n return {\n message,\n isLastOfRun: !continuesIntoNext,\n isFirstOfDay: !prev || dayKey(createdAt(prev)) !== day,\n }\n })\n}\n","/**\n * The day divider between message runs in a thread.\n *\n * The label is supplied by the caller rather than formatted here: the ARBI app\n * has a friendly formatter that already says \"Today\" / \"Yesterday\" in the user's\n * locale, and a second date-formatting opinion in the kit would drift from it.\n */\n\nimport type { ReactNode } from 'react'\n\nexport interface DateSeparatorProps {\n children: ReactNode\n}\n\nexport function DateSeparator({ children }: DateSeparatorProps) {\n return (\n <div className=\"my-3 flex justify-center\" data-testid=\"dm-date-separator\">\n <span className=\"rounded-full bg-background/80 px-2 py-0.5 text-xs text-muted-foreground\">\n {children}\n </span>\n </div>\n )\n}\n","/**\n * A single message row in a DM thread.\n *\n * This is an adapter, not a second bubble: it maps a `DmMessage` onto the shared\n * <ChatBubble>, which is the one implementation behind both this block and the\n * ARBI app's thread. The two used to be separate components for the same object\n * and had drifted apart — this one had the softer look and the brand slots, the\n * other had delete, read receipts and same-sender run grouping. Every consumer\n * now gets all of it.\n */\n\nimport { ChatBubble } from '../chat/ChatBubble'\nimport type { DmClassNames, DmMessage } from './types'\nimport { formatRelativeTime, userDisplayName } from './utils'\n\nexport interface MessageBubbleProps {\n message: DmMessage\n classNames?: Pick<DmClassNames, 'ownBubble' | 'peerBubble'>\n /**\n * False when the next message is from the same sender in the same run, which\n * suppresses the meta row so a burst reads as one block. Defaults to true —\n * every message carries its own sender, time and receipt.\n */\n isLastOfRun?: boolean\n /** Deletes this message. Omit to hide the affordance. */\n onDelete?: () => void\n /** Renders the tombstone in place of the body. */\n deleted?: boolean\n}\n\nexport function MessageBubble({\n message,\n classNames,\n isLastOfRun = true,\n onDelete,\n deleted,\n}: MessageBubbleProps) {\n return (\n <ChatBubble\n data-testid=\"arbi-dm-message\"\n message={message.body}\n timestamp={message.createdAt}\n isSent={message.isMine}\n read={message.read}\n deleted={deleted}\n onDelete={onDelete}\n isLastOfRun={isLastOfRun}\n senderName={message.isMine ? 'You' : userDisplayName(message.sender)}\n classNames={classNames}\n formatTimestamp={formatRelativeTime}\n />\n )\n}\n","/**\n * The open conversation: a peer header, a scrolling message list (auto-scrolled\n * to the newest), and — when no peer is selected — an empty state.\n */\n\nimport { Fragment, useEffect, useMemo, useRef } from 'react'\nimport { MessagesSquare } from 'lucide-react'\nimport { ScrollArea } from '../ui/scroll-area'\nimport type { DmClassNames, DmConversation, DmMessage } from './types'\nimport { userDisplayName } from './utils'\nimport { annotateThread } from './grouping'\nimport { DateSeparator } from './DateSeparator'\nimport { DmAvatar } from './DmAvatar'\nimport { MessageBubble } from './MessageBubble'\n\nexport interface MessageThreadProps {\n conversation: DmConversation | null\n classNames?: Pick<DmClassNames, 'ownBubble' | 'peerBubble'>\n emptyState?: React.ReactNode\n /**\n * Label for a day divider. Omit to leave the thread undivided — the kit does\n * not format dates itself (see DateSeparator).\n */\n formatDay?: (iso: string) => string\n /** Deletes a message. Omit to hide the affordance. */\n onDeleteMessage?: (message: DmMessage) => void\n /** External ids of messages already deleted, rendered as tombstones. */\n deletedIds?: ReadonlySet<string>\n}\n\nconst THREAD_ACCESSORS = {\n senderId: (m: DmMessage) => m.sender.external_id,\n createdAt: (m: DmMessage) => m.createdAt,\n}\n\nexport function MessageThread({\n conversation,\n classNames,\n emptyState,\n formatDay,\n onDeleteMessage,\n deletedIds,\n}: MessageThreadProps) {\n const bottomRef = useRef<HTMLDivElement>(null)\n\n const items = useMemo(\n () => annotateThread(conversation?.messages ?? [], THREAD_ACCESSORS),\n [conversation?.messages]\n )\n\n useEffect(() => {\n bottomRef.current?.scrollIntoView({ block: 'end' })\n }, [conversation?.peer.external_id, conversation?.messages.length])\n\n if (!conversation) {\n return (\n <section className=\"flex min-h-0 flex-1 flex-col items-center justify-center gap-3 p-8 text-center\">\n {emptyState ?? (\n <>\n <div className=\"flex size-14 items-center justify-center rounded-full bg-accent\">\n <MessagesSquare className=\"size-6 text-muted-foreground\" />\n </div>\n <div>\n <p className=\"text-sm font-semibold text-foreground\">No conversation selected</p>\n <p className=\"mx-auto mt-1 max-w-xs text-xs text-muted-foreground\">\n Choose a colleague from the list to read the thread and send a direct message.\n </p>\n </div>\n </>\n )}\n </section>\n )\n }\n\n const { peer } = conversation\n\n return (\n <>\n <header className=\"flex items-center gap-3 border-b border-border px-4 py-3\">\n <DmAvatar user={peer} className=\"size-9\" />\n <div className=\"min-w-0\">\n <p className=\"truncate text-sm font-semibold text-foreground\">{userDisplayName(peer)}</p>\n <p className=\"truncate text-xs text-muted-foreground\">{peer.email}</p>\n </div>\n </header>\n\n <ScrollArea className=\"min-h-0 flex-1 bg-background\">\n {/* No `gap` here: spacing is the bubble's job now, so a mid-run message\n can sit tight against the one before it and a run reads as a block. */}\n <div className=\"flex flex-col px-4 py-4\" data-testid=\"arbi-dm-thread\">\n {items.map(({ message: m, isLastOfRun, isFirstOfDay }) => (\n <Fragment key={m.externalId}>\n {isFirstOfDay && formatDay && <DateSeparator>{formatDay(m.createdAt)}</DateSeparator>}\n <MessageBubble\n message={m}\n classNames={classNames}\n isLastOfRun={isLastOfRun}\n deleted={deletedIds?.has(m.externalId)}\n onDelete={onDeleteMessage ? () => onDeleteMessage(m) : undefined}\n />\n </Fragment>\n ))}\n <div ref={bottomRef} />\n </div>\n </ScrollArea>\n </>\n )\n}\n","/**\n * The message composer: an auto-sizing textarea + send button. Enter sends,\n * Shift+Enter inserts a newline.\n */\n\nimport { useRef, useState } from 'react'\nimport { Loader2, Send } from 'lucide-react'\nimport { Button } from '../ui/button'\nimport { Textarea } from '../ui/textarea'\nimport { cn } from '../lib/utils'\nimport type { DmClassNames } from './types'\n\nexport interface DmComposerProps {\n /** Placeholder, e.g. \"Message Eleanor…\". */\n placeholder?: string\n disabled?: boolean\n /**\n * A send is in flight: swaps the icon for a spinner and blocks a second\n * submit, so a slow encrypt-and-post can't be fired twice by an impatient\n * Enter.\n */\n busy?: boolean\n /** Called with the trimmed text when the user sends. May reject if the send fails. */\n onSend: (text: string) => void | Promise<void>\n /** Shown under the box when the last send failed. */\n error?: string | null\n /** Extra content between the box and the border (e.g. a peer-specific action). */\n children?: React.ReactNode\n classNames?: Pick<DmClassNames, 'sendButton'>\n}\n\nexport function DmComposer({\n placeholder,\n disabled,\n busy,\n onSend,\n error,\n children,\n classNames,\n}: DmComposerProps) {\n const [draft, setDraft] = useState('')\n const inputRef = useRef<HTMLTextAreaElement>(null)\n\n const submit = async () => {\n const text = draft.trim()\n if (!text || disabled || busy) return\n setDraft('')\n try {\n await onSend(text)\n // Keep the caret in the box so a reply can follow straight on.\n inputRef.current?.focus()\n } catch {\n // The send failed (the error surfaces via `error`) — give the text back\n // rather than losing what the user typed.\n setDraft(text)\n }\n }\n\n const onKeyDown = (e: React.KeyboardEvent<HTMLTextAreaElement>) => {\n if (e.key === 'Enter' && !e.shiftKey) {\n e.preventDefault()\n void submit()\n }\n }\n\n return (\n <div className=\"border-t border-border p-3\">\n {children}\n <div className=\"flex items-end gap-2\">\n <Textarea\n ref={inputRef}\n value={draft}\n onChange={(e) => setDraft(e.target.value)}\n onKeyDown={onKeyDown}\n placeholder={placeholder}\n rows={1}\n disabled={disabled}\n className=\"max-h-40 min-h-[44px] resize-none\"\n data-testid=\"arbi-dm-input\"\n />\n <Button\n type=\"button\"\n onClick={() => void submit()}\n disabled={disabled || busy || !draft.trim()}\n className={cn(classNames?.sendButton)}\n data-testid=\"arbi-dm-send\"\n aria-label=\"Send message\"\n >\n {busy ? <Loader2 className=\"size-4 animate-spin\" /> : <Send className=\"size-4\" />} Send\n </Button>\n </div>\n {error && (\n <p className=\"mt-2 text-xs text-destructive\" data-testid=\"arbi-dm-error\">\n {error}\n </p>\n )}\n </div>\n )\n}\n","/**\n * DirectMessages — the turnkey DM block.\n *\n * A two-column messenger (conversation rail + open thread + composer) wired to\n * the real, E2E-encrypted DM backend via `useDirectMessages`. Drop it in under\n * an ArbiProvider + ArbiWebSocketProvider and it lists, opens, marks-read and\n * sends real messages. Brand accents are themed via the `classNames` slots.\n */\n\nimport { useEffect, useMemo, useState } from 'react'\nimport { cn } from '../lib/utils'\nimport type { DmClassNames } from './types'\nimport { userDisplayName } from './utils'\nimport { useDirectMessages } from './useDirectMessages'\nimport { ConversationList } from './ConversationList'\nimport { MessageThread } from './MessageThread'\nimport { DmComposer } from './DmComposer'\n\nexport interface DirectMessagesProps {\n /** Extra classes for the outer card (e.g. a page-specific height). */\n className?: string\n /** Per-slot brand overrides (own bubble, unread pill, send button…). */\n classNames?: DmClassNames\n /** Rendered in the thread pane when no conversation is selected. */\n emptyThread?: React.ReactNode\n /** Rendered in the rail when there are no conversations. */\n emptyList?: React.ReactNode\n}\n\nexport function DirectMessages({\n className,\n classNames,\n emptyThread,\n emptyList,\n}: DirectMessagesProps) {\n const {\n conversations,\n isLoading,\n isError,\n error,\n sendMessage,\n sendMessageTo,\n sendError,\n markRead,\n } = useDirectMessages()\n const [selectedPeerId, setSelectedPeerId] = useState<string | null>(null)\n\n // The contacts rail renders even when the message list fails, so without this\n // a failed load looks exactly like an empty inbox.\n const loadError = isError\n ? error instanceof Error\n ? error.message\n : 'Couldn’t load messages.'\n : null\n\n const selected = useMemo(\n () => conversations.find((c) => c.peer.external_id === selectedPeerId) ?? null,\n [conversations, selectedPeerId]\n )\n\n // Mark a conversation's inbound messages read once it's open.\n useEffect(() => {\n if (!selected || selected.unreadCount === 0) return\n const unreadIds = selected.messages.filter((m) => !m.isMine && !m.read).map((m) => m.externalId)\n if (unreadIds.length) void markRead(unreadIds)\n // eslint-disable-next-line react-hooks/exhaustive-deps\n }, [selected?.peer.external_id, selected?.unreadCount])\n\n const handleSend = async (text: string) => {\n if (!selected) return\n // Existing threads carry the peer's public key; a contact opened fresh may\n // not, so fall back to resolve-by-id (the SDK looks the key up internally).\n // A rejection here (e.g. an unresolvable recipient) lands in `sendError`,\n // which the composer surfaces — a send must never fail invisibly.\n if (selected.peer.encryption_public_key) {\n await sendMessage(selected.peer.external_id, selected.peer.encryption_public_key, text)\n } else {\n await sendMessageTo(selected.peer.external_id, text)\n }\n }\n\n return (\n <div\n data-testid=\"arbi-dm\"\n style={{ height: 'calc(100vh - 16rem)', minHeight: '28rem' }}\n className={cn(\n 'relative flex flex-col overflow-hidden rounded-xl border border-border bg-card md:flex-row',\n className\n )}\n >\n {loadError && (\n <p\n data-testid=\"arbi-dm-load-error\"\n className=\"absolute inset-x-0 top-0 z-10 bg-destructive/10 px-3 py-2 text-center text-xs text-destructive\"\n >\n {loadError}\n </p>\n )}\n <ConversationList\n conversations={conversations}\n selectedPeerId={selected?.peer.external_id ?? null}\n onSelect={setSelectedPeerId}\n classNames={classNames}\n emptyState={isLoading ? 'Loading messages…' : emptyList}\n />\n <div className=\"flex min-h-0 min-w-0 flex-1 flex-col\">\n <MessageThread conversation={selected} classNames={classNames} emptyState={emptyThread} />\n {selected ? (\n <DmComposer\n placeholder={`Message ${userDisplayName(selected.peer).split(' ')[0]}…`}\n onSend={handleSend}\n error={sendError?.message ?? null}\n classNames={classNames}\n />\n ) : null}\n </div>\n </div>\n )\n}\n","/**\n * ImageCropper — a themeable pan/zoom crop surface (react-easy-crop) with an\n * optional aspect-ratio picker. Reports the chosen crop rectangle (in source\n * pixels) via `onCropComplete`; pair it with {@link cropImage} to export.\n *\n * react-easy-crop always constrains to a fixed aspect (you move the image under\n * a fixed frame), so \"change the aspect ratio\" is a discrete ratio picker, not\n * free-form rectangle dragging.\n */\n\nimport { useCallback, useEffect, useState } from 'react'\nimport Cropper, { type Area } from 'react-easy-crop'\nimport { Slider } from '../ui/slider'\nimport { cn } from '../lib/utils'\nimport type { CropArea } from './cropImage'\n\n/** A selectable aspect ratio (width / height). */\nexport interface AspectOption {\n label: string\n value: number\n}\n\n/** A sensible default ratio set (square, landscape, portrait, wide, tall). */\nexport const DEFAULT_ASPECT_OPTIONS: AspectOption[] = [\n { label: '1:1', value: 1 },\n { label: '4:3', value: 4 / 3 },\n { label: '3:4', value: 3 / 4 },\n { label: '16:9', value: 16 / 9 },\n { label: '9:16', value: 9 / 16 },\n]\n\nexport interface ImageCropperProps {\n image: string\n /** Fixed aspect ratio (w/h). Default 1. Ignored once the user picks from `aspectOptions`. */\n aspect?: number\n /** Show a ratio picker with these options (first is the initial selection). */\n aspectOptions?: AspectOption[]\n cropShape?: 'rect' | 'round'\n minZoom?: number\n maxZoom?: number\n className?: string\n /** The crop rectangle (source pixels) + the active aspect, on every change. */\n onCropComplete?: (area: CropArea, aspect: number) => void\n}\n\nexport function ImageCropper({\n image,\n aspect = 1,\n aspectOptions,\n cropShape = 'rect',\n minZoom = 1,\n maxZoom = 3,\n className,\n onCropComplete,\n}: ImageCropperProps) {\n const [crop, setCrop] = useState({ x: 0, y: 0 })\n const [zoom, setZoom] = useState(1)\n const [activeAspect, setActiveAspect] = useState(aspectOptions?.[0]?.value ?? aspect)\n\n // Keep the reported aspect in sync when the caller changes the fixed `aspect`.\n useEffect(() => {\n if (!aspectOptions) setActiveAspect(aspect)\n }, [aspect, aspectOptions])\n\n const handleComplete = useCallback(\n (_: Area, areaPixels: Area) => {\n onCropComplete?.(areaPixels, activeAspect)\n },\n [onCropComplete, activeAspect]\n )\n\n return (\n <div className={cn('flex flex-col gap-3', className)}>\n <div className=\"relative h-72 w-full overflow-hidden rounded-md bg-foreground/95\">\n <Cropper\n image={image}\n crop={crop}\n zoom={zoom}\n aspect={activeAspect}\n cropShape={cropShape}\n showGrid={cropShape === 'rect'}\n onCropChange={setCrop}\n onZoomChange={setZoom}\n onCropComplete={handleComplete}\n objectFit=\"contain\"\n />\n </div>\n\n {aspectOptions && aspectOptions.length > 1 ? (\n <div className=\"flex flex-wrap items-center gap-1\" data-testid=\"image-cropper-aspects\">\n <span className=\"mr-1 text-xs font-semibold uppercase tracking-wider text-muted-foreground\">\n Ratio\n </span>\n {aspectOptions.map((opt) => {\n const on = opt.value === activeAspect\n return (\n <button\n key={opt.label}\n type=\"button\"\n onClick={() => setActiveAspect(opt.value)}\n data-testid={`image-cropper-aspect-${opt.label}`}\n className={cn(\n 'rounded-md px-2 py-1 text-xs font-medium transition-colors',\n on\n ? 'bg-primary text-primary-foreground'\n : 'text-muted-foreground hover:bg-accent hover:text-foreground'\n )}\n >\n {opt.label}\n </button>\n )\n })}\n </div>\n ) : null}\n\n <div className=\"space-y-1.5\">\n <label className=\"text-xs font-semibold uppercase tracking-wider text-muted-foreground\">\n Zoom\n </label>\n <Slider\n value={[zoom]}\n onValueChange={([v]) => setZoom(v ?? 1)}\n min={minZoom}\n max={maxZoom}\n step={0.01}\n />\n </div>\n </div>\n )\n}\n","/**\n * Crop a region of an image to a canvas and export it — the shared engine\n * behind every \"frame this image\" surface (avatars, builder image fields, …).\n *\n * `area` is the pixel rectangle react-easy-crop reports (`onCropComplete`'s\n * second arg). Output is rectangular (a round crop is a UI overlay only — JPEG\n * has no alpha), optionally downscaled so the longest edge fits `maxSize`.\n */\n\n/** Pixel crop rectangle in the source image's natural coordinates. */\nexport interface CropArea {\n x: number\n y: number\n width: number\n height: number\n}\n\nexport interface CropOutput {\n /** Cap the longest output edge to this many px (preserves aspect). Omit = native crop size. */\n maxSize?: number\n /** Output MIME type. Default `image/jpeg`. */\n mimeType?: string\n /** Quality for lossy formats, 0..1. Default 0.9. */\n quality?: number\n /** Background painted before the crop (JPEG has no alpha). Default `#ffffff`. */\n background?: string\n}\n\nexport interface CropResult {\n dataUrl: string\n blob: Blob\n width: number\n height: number\n}\n\nfunction loadImage(src: string): Promise<HTMLImageElement> {\n return new Promise((resolve, reject) => {\n const img = new Image()\n // Allow exporting cross-origin images the server marks CORS-safe; harmless for data/blob URLs.\n img.crossOrigin = 'anonymous'\n img.onload = () => resolve(img)\n img.onerror = () => reject(new Error('Failed to load image for cropping'))\n img.src = src\n })\n}\n\nexport async function cropImage(\n imageSrc: string,\n area: CropArea,\n output: CropOutput = {}\n): Promise<CropResult> {\n const { maxSize, mimeType = 'image/jpeg', quality = 0.9, background = '#ffffff' } = output\n const img = await loadImage(imageSrc)\n\n let outW = Math.max(1, Math.round(area.width))\n let outH = Math.max(1, Math.round(area.height))\n if (maxSize && Math.max(outW, outH) > maxSize) {\n const scale = maxSize / Math.max(outW, outH)\n outW = Math.max(1, Math.round(outW * scale))\n outH = Math.max(1, Math.round(outH * scale))\n }\n\n const canvas = document.createElement('canvas')\n canvas.width = outW\n canvas.height = outH\n const ctx = canvas.getContext('2d')\n if (!ctx) throw new Error('canvas 2d context unavailable')\n\n if (mimeType === 'image/jpeg') {\n ctx.fillStyle = background\n ctx.fillRect(0, 0, outW, outH)\n }\n ctx.drawImage(img, area.x, area.y, area.width, area.height, 0, 0, outW, outH)\n\n const dataUrl = canvas.toDataURL(mimeType, quality)\n const blob = await new Promise<Blob>((resolve, reject) =>\n canvas.toBlob(\n (b) => (b ? resolve(b) : reject(new Error('canvas toBlob returned null'))),\n mimeType,\n quality\n )\n )\n return { dataUrl, blob, width: outW, height: outH }\n}\n","/**\n * ImageCropModal — a turnkey crop dialog. Wraps {@link ImageCropper} with\n * Save/Cancel and runs {@link cropImage} on save, handing the caller the full\n * result (both a `dataUrl` and a `blob`, plus dimensions) so it can inline a\n * small avatar or upload a larger asset as it sees fit.\n */\n\nimport { useState } from 'react'\nimport { Loader2 } from 'lucide-react'\nimport { Button } from '../ui/button'\nimport { Dialog, DialogContent, DialogFooter, DialogHeader, DialogTitle } from '../ui/dialog'\nimport { cropImage, type CropArea, type CropOutput, type CropResult } from './cropImage'\nimport { ImageCropper, type AspectOption } from './ImageCropper'\n\nexport interface ImageCropModalProps {\n open: boolean\n image: string | null\n title?: string\n saveLabel?: string\n aspect?: number\n aspectOptions?: AspectOption[]\n cropShape?: 'rect' | 'round'\n /** Export options (max size, mime, quality). */\n output?: CropOutput\n /** Called with the exported crop on save. */\n onComplete: (result: CropResult) => void | Promise<void>\n onCancel: () => void\n}\n\nexport function ImageCropModal({\n open,\n image,\n title = 'Crop image',\n saveLabel = 'Save',\n aspect,\n aspectOptions,\n cropShape = 'rect',\n output,\n onComplete,\n onCancel,\n}: ImageCropModalProps) {\n const [area, setArea] = useState<CropArea | null>(null)\n const [busy, setBusy] = useState(false)\n\n const handleSave = async () => {\n if (!image || !area) return\n setBusy(true)\n try {\n const result = await cropImage(image, area, output)\n await onComplete(result)\n } finally {\n setBusy(false)\n }\n }\n\n return (\n <Dialog open={open} onOpenChange={(next) => (!next ? onCancel() : undefined)}>\n <DialogContent className=\"sm:max-w-md\" data-testid=\"image-crop-modal\">\n <DialogHeader>\n <DialogTitle>{title}</DialogTitle>\n </DialogHeader>\n\n {image ? (\n <ImageCropper\n image={image}\n aspect={aspect}\n aspectOptions={aspectOptions}\n cropShape={cropShape}\n onCropComplete={setArea}\n />\n ) : null}\n\n <DialogFooter className=\"gap-2 sm:gap-2\">\n <Button variant=\"ghost\" onClick={onCancel} disabled={busy}>\n Cancel\n </Button>\n <Button onClick={handleSave} disabled={!area || busy} data-testid=\"image-crop-save\">\n {busy ? <Loader2 className=\"mr-1 size-4 animate-spin\" /> : null}\n {saveLabel}\n </Button>\n </DialogFooter>\n </DialogContent>\n </Dialog>\n )\n}\n","import { useEffect, useMemo, useRef, useState } from 'react'\nimport { Sparkles, CornerDownLeft, ArrowRight, FileText } from 'lucide-react'\nimport { Dialog, DialogContent, DialogTitle } from '../ui/dialog'\nimport { Button } from '../ui/button'\nimport { cn } from '../lib/utils'\nimport { useAiTask, useSemanticSearch, AiAnswer } from '../ai'\nimport type { PaletteNavItem, CommandPaletteClassNames } from './types'\n\nexport interface CommandPaletteProps {\n open: boolean\n onOpenChange: (open: boolean) => void\n /** Destinations the palette can filter and jump to. */\n navItems: PaletteNavItem[]\n /** Invoked with an item's `to` when a nav result is chosen. */\n onNavigate: (to: string) => void\n /** Turn the raw query into the grounded AI prompt (default: identity). */\n buildAskPrompt?: (query: string) => string\n /** Document ids the AI answer is grounded on. */\n askDocIds?: string[]\n model?: string\n /** Document ids to semantic-search as the user types (omit to disable search). */\n searchDocIds?: string[]\n /** Invoked with a document id when a search hit is chosen. */\n onOpenDoc?: (docId: string) => void\n placeholder?: string\n /** Footnote under the \"Ask AI\" action (e.g. what it's grounded in). */\n askHint?: string\n classNames?: CommandPaletteClassNames\n testId?: string\n}\n\nconst MAX_NAV = 5\nconst MAX_DOCS = 4\n\n/**\n * The single pane of glass: one ⌘K spotlight that navigates the app, runs a\n * grounded cited AI query, and (optionally) semantic-searches the workspace — all\n * from one input. Firm-agnostic: navigation, prompt and grounding arrive as props;\n * styling tracks the shadcn + AI-accent semantic tokens.\n */\nexport function CommandPalette({\n open,\n onOpenChange,\n navItems,\n onNavigate,\n buildAskPrompt = (q) => q,\n askDocIds = [],\n model,\n searchDocIds,\n onOpenDoc,\n placeholder = 'Ask AI, or jump to a page…',\n askHint = 'Grounded in the live workspace',\n classNames,\n testId = 'command-palette',\n}: CommandPaletteProps) {\n const task = useAiTask()\n const searchable = !!searchDocIds && searchDocIds.length > 0\n const { results, search, status: searchStatus } = useSemanticSearch(searchDocIds ?? [])\n const [query, setQuery] = useState('')\n const inputRef = useRef<HTMLInputElement>(null)\n\n // Reset each time the palette opens.\n useEffect(() => {\n if (open) {\n setQuery('')\n task.reset()\n const t = setTimeout(() => inputRef.current?.focus(), 40)\n return () => clearTimeout(t)\n }\n // eslint-disable-next-line react-hooks/exhaustive-deps\n }, [open])\n\n const showingAnswer = task.status !== 'idle'\n\n // Debounced semantic search as the user types (only when grounding docs exist).\n useEffect(() => {\n if (!searchable || showingAnswer) return\n const q = query.trim()\n if (q.length < 2) return\n const t = setTimeout(() => void search(q, 'hybrid'), 300)\n return () => clearTimeout(t)\n }, [query, searchable, showingAnswer, search])\n\n const navMatches = useMemo(() => {\n const q = query.trim().toLowerCase()\n if (!q) return navItems.slice(0, MAX_NAV)\n return navItems\n .filter(\n (i) =>\n i.label.toLowerCase().includes(q) ||\n (i.keywords ? i.keywords.toLowerCase().includes(q) : false)\n )\n .slice(0, MAX_NAV)\n }, [query, navItems])\n\n const docHits = useMemo(() => results.slice(0, MAX_DOCS), [results])\n\n const go = (to: string) => {\n onOpenChange(false)\n onNavigate(to)\n }\n\n const openDoc = (docId: string) => {\n onOpenChange(false)\n onOpenDoc?.(docId)\n }\n\n const ask = () => {\n const q = query.trim()\n if (!q || task.isRunning) return\n void task.run(buildAskPrompt(q), askDocIds, { model })\n }\n\n return (\n <Dialog open={open} onOpenChange={onOpenChange}>\n <DialogContent\n className={cn(\n 'top-[12%] max-w-2xl translate-y-0 gap-0 overflow-hidden p-0',\n classNames?.dialog\n )}\n data-testid={testId}\n >\n <DialogTitle className=\"sr-only\">Command palette</DialogTitle>\n\n {/* Input row */}\n <div className=\"flex items-center gap-3 border-b border-border px-4\">\n <Sparkles className={cn('size-4 shrink-0 text-ai-accent', classNames?.leadingIcon)} />\n <input\n ref={inputRef}\n value={query}\n onChange={(e) => setQuery(e.target.value)}\n onKeyDown={(e) => {\n if (e.key === 'Enter') {\n e.preventDefault()\n ask()\n }\n }}\n placeholder={placeholder}\n className={cn(\n 'h-14 flex-1 bg-transparent text-base outline-none placeholder:text-muted-foreground',\n classNames?.input\n )}\n data-testid={`${testId}-input`}\n />\n <kbd className=\"hidden rounded border border-border px-1.5 py-0.5 text-xs text-muted-foreground sm:inline\">\n ⌘K\n </kbd>\n </div>\n\n <div className=\"max-h-[60vh] overflow-y-auto p-2\">\n {/* Ask AI primary action */}\n {query.trim() && !showingAnswer && (\n <button\n type=\"button\"\n onClick={ask}\n className={cn(\n 'mb-1 flex w-full items-center gap-3 rounded-lg px-3 py-2.5 text-left hover:bg-accent',\n classNames?.askAction\n )}\n data-testid={`${testId}-ask`}\n >\n <span\n className={cn(\n 'flex size-8 items-center justify-center rounded-md bg-ai-surface text-ai-accent',\n classNames?.askChip\n )}\n >\n <Sparkles className=\"size-4\" />\n </span>\n <span className=\"min-w-0 flex-1\">\n <span className=\"block truncate text-sm font-medium text-foreground\">\n Ask AI: “{query.trim()}”\n </span>\n <span className=\"block text-xs text-muted-foreground\">{askHint}</span>\n </span>\n <CornerDownLeft className=\"size-4 text-muted-foreground\" />\n </button>\n )}\n\n {/* Streaming answer */}\n {showingAnswer && (\n <div className=\"px-3 py-2\" data-testid={`${testId}-answer`}>\n <AiAnswer\n status={task.status}\n text={task.text}\n stepCount={task.stepCount}\n error={task.error}\n testId={`${testId}-ai`}\n />\n {task.isDone && (\n <div className=\"mt-3 flex justify-end\">\n <Button\n variant=\"outline\"\n size=\"sm\"\n onClick={() => task.reset()}\n data-testid={`${testId}-clear`}\n >\n Ask another\n </Button>\n </div>\n )}\n </div>\n )}\n\n {/* Navigation + document search */}\n {!showingAnswer && (\n <>\n <p className=\"px-3 pb-1 pt-2 text-xs font-semibold uppercase tracking-wide text-muted-foreground\">\n {query.trim() ? 'Jump to' : 'Go to'}\n </p>\n {navMatches.length === 0 && (\n <p className=\"px-3 py-2 text-sm text-muted-foreground\">\n No pages match — press Enter to ask AI.\n </p>\n )}\n {navMatches.map((item) => (\n <button\n key={item.id}\n type=\"button\"\n onClick={() => go(item.to)}\n className={cn(\n 'flex w-full items-center gap-3 rounded-lg px-3 py-2 text-left hover:bg-accent',\n classNames?.navItem\n )}\n data-testid={`${testId}-nav-${item.id}`}\n >\n {item.icon && <item.icon className=\"size-4 text-muted-foreground\" />}\n <span className=\"flex-1 text-sm text-foreground\">{item.label}</span>\n <ArrowRight className=\"size-3.5 text-muted-foreground\" />\n </button>\n ))}\n\n {searchable && query.trim().length >= 2 && (\n <>\n <p className=\"px-3 pb-1 pt-3 text-xs font-semibold uppercase tracking-wide text-muted-foreground\">\n Documents\n </p>\n {searchStatus === 'done' && docHits.length === 0 && (\n <p className=\"px-3 py-2 text-sm text-muted-foreground\">No passages matched.</p>\n )}\n {docHits.map((hit, i) => (\n <button\n key={`${hit.docId}-${hit.page}-${i}`}\n type=\"button\"\n onClick={() => hit.docId && openDoc(hit.docId)}\n className=\"flex w-full items-start gap-3 rounded-lg px-3 py-2 text-left hover:bg-accent\"\n data-testid={`${testId}-doc-${i}`}\n >\n <FileText className=\"mt-0.5 size-4 shrink-0 text-ai-accent\" />\n <span className=\"min-w-0 flex-1\">\n <span className=\"block truncate text-sm text-foreground\">\n {hit.docTitle ?? 'Document'}\n {hit.page != null && (\n <span className=\"text-muted-foreground\"> · p.{hit.page}</span>\n )}\n </span>\n <span className=\"line-clamp-1 text-xs text-muted-foreground\">\n {hit.content}\n </span>\n </span>\n </button>\n ))}\n </>\n )}\n </>\n )}\n </div>\n </DialogContent>\n </Dialog>\n )\n}\n","import { createContext, useContext } from 'react'\n\n/** Imperative handle to the command palette, exposed to any descendant. */\nexport interface CommandPaletteValue {\n open: () => void\n close: () => void\n toggle: () => void\n isOpen: boolean\n}\n\nexport const CommandPaletteCtx = createContext<CommandPaletteValue | null>(null)\n\n/**\n * Access the palette from anywhere under {@link CommandPaletteProvider} — e.g. a\n * topbar search button calls `useCommandPalette().open()`.\n */\nexport function useCommandPalette(): CommandPaletteValue {\n const v = useContext(CommandPaletteCtx)\n if (!v) throw new Error('useCommandPalette must be used within a CommandPaletteProvider')\n return v\n}\n","import { useCallback, useEffect, useMemo, useState, type ReactNode } from 'react'\nimport { CommandPaletteCtx } from './commandPaletteContext'\nimport { CommandPalette, type CommandPaletteProps } from './CommandPalette'\n\nexport interface CommandPaletteProviderProps extends Omit<\n CommandPaletteProps,\n 'open' | 'onOpenChange'\n> {\n children: ReactNode\n /** Disable the global ⌘K / Ctrl+K binding (default enabled). */\n hotkey?: boolean\n}\n\n/**\n * Wraps the app once with the palette's data (nav items, grounding, prompt) and\n * provides an imperative handle via {@link useCommandPalette}. Binds ⌘K/Ctrl+K\n * globally so any surface — a topbar search button, a menu item — can open it.\n */\nexport function CommandPaletteProvider({\n children,\n hotkey = true,\n ...paletteProps\n}: CommandPaletteProviderProps) {\n const [isOpen, setIsOpen] = useState(false)\n const open = useCallback(() => setIsOpen(true), [])\n const close = useCallback(() => setIsOpen(false), [])\n const toggle = useCallback(() => setIsOpen((o) => !o), [])\n\n useEffect(() => {\n if (!hotkey) return\n const onKey = (e: KeyboardEvent) => {\n if ((e.metaKey || e.ctrlKey) && e.key.toLowerCase() === 'k') {\n e.preventDefault()\n toggle()\n }\n }\n window.addEventListener('keydown', onKey)\n return () => window.removeEventListener('keydown', onKey)\n }, [hotkey, toggle])\n\n const value = useMemo(() => ({ open, close, toggle, isOpen }), [open, close, toggle, isOpen])\n\n return (\n <CommandPaletteCtx.Provider value={value}>\n {children}\n <CommandPalette open={isOpen} onOpenChange={setIsOpen} {...paletteProps} />\n </CommandPaletteCtx.Provider>\n )\n}\n","/**\n * SDK-owned UI store for cross-block coordination.\n *\n * This is a SMALL, decoupled zustand store (NOT the ARBI app's multi-slice\n * store). Blocks such as `DocumentTable` use it as a fallback for selection /\n * \"viewing\" state when the consumer does not drive that state via props.\n */\n\nimport { create } from 'zustand'\n\nexport interface ArbiUiState {\n /** External ids of the currently selected documents. */\n selectedDocIds: string[]\n setSelectedDocIds: (ids: string[]) => void\n /** External id of the document currently being viewed/opened, if any. */\n viewingDocId: string | null\n setViewingDocId: (id: string | null) => void\n}\n\nexport const useArbiUiStore = create<ArbiUiState>((set) => ({\n selectedDocIds: [],\n setSelectedDocIds: (ids) => set({ selectedDocIds: ids }),\n viewingDocId: null,\n setViewingDocId: (id) => set({ viewingDocId: id }),\n}))\n","/**\n * DocumentTable — a reusable AG Grid (community) block that renders a\n * workspace's documents using the promoted entity pills.\n *\n * REUSE-FIRST: this composes AG Grid + `DocumentEntity`/`TagEntity` + the shadcn\n * `Badge`; it is not a bespoke table. Data comes from the SDK `useDocuments`\n * hook (or an explicit `documents` prop). Selection is controlled via\n * `selectedIds`/`onSelectionChange`, falling back to the SDK-owned\n * `useArbiUiStore` when those props are omitted.\n */\n\nimport React from 'react'\nimport { AgGridReact } from 'ag-grid-react'\nimport {\n ModuleRegistry,\n AllCommunityModule,\n type ColDef,\n type ICellRendererParams,\n type RowClickedEvent,\n type SelectionChangedEvent,\n type GridReadyEvent,\n} from 'ag-grid-community'\nimport type { components } from '@arbidocs/client'\n\nimport { useDocuments, useTags } from '../hooks'\nimport { useArbiUiStore } from '../store'\nimport { DocumentEntity } from '../entities/DocumentEntity'\nimport { TagEntity } from '../entities/TagEntity'\nimport { Badge } from '../ui/badge'\n\n// Register the community modules once, at import time (matches the app's usage).\nModuleRegistry.registerModules([AllCommunityModule])\n\ntype DocResponse = components['schemas']['DocResponse']\n\nexport interface DocumentTableProps {\n /** Workspace to load documents from (used when `documents` is not supplied). */\n workspaceId?: string\n /** Explicit rows. When provided, `useDocuments` is not called. */\n documents?: DocResponse[]\n /** Called when a row (document) is opened — row click or name-pill click. */\n onOpenDocument?: (id: string) => void\n /**\n * Whether clicking anywhere in a row opens the document. Default true.\n *\n * Set false when the grid is used for bulk work: a reviewer building a\n * selection to code together will inevitably click a row, and navigating away\n * mid-selection loses it. With this off, the name pill stays the way to open\n * a document and the row is purely a selection target.\n */\n openOnRowClick?: boolean\n /** Controlled selection (external ids). Falls back to the SDK ui store. */\n selectedIds?: string[]\n /** Called with the new selection (external ids). Falls back to the SDK ui store. */\n onSelectionChange?: (ids: string[]) => void\n /** Grid height. Number → pixels; string passed through. Default 480. */\n height?: number | string\n /**\n * Extra columns appended after the built-ins — e.g. one per coding field in a\n * review protocol, so a grid can be coded across rather than document by\n * document. Standard AG Grid `ColDef`s; give each an explicit `colId`, since\n * AG Grid persists column state and auto-generated ids reorder unexpectedly.\n */\n extraColumns?: ColDef<DocResponse>[]\n className?: string\n}\n\n/** Format a byte count as a compact human-readable size. */\nfunction formatBytes(bytes?: number | null): string {\n if (bytes == null || Number.isNaN(bytes)) return '—'\n if (bytes < 1024) return `${bytes} B`\n const units = ['KB', 'MB', 'GB', 'TB']\n let value = bytes / 1024\n let i = 0\n while (value >= 1024 && i < units.length - 1) {\n value /= 1024\n i++\n }\n return `${value.toFixed(value >= 10 || i === 0 ? 0 : 1)} ${units[i]}`\n}\n\nconst STATUS_VARIANTS: Record<string, 'default' | 'secondary' | 'destructive' | 'outline'> = {\n completed: 'default',\n empty: 'secondary',\n 'low-content': 'secondary',\n processing: 'outline',\n queued: 'outline',\n failed: 'destructive',\n skipped: 'destructive',\n}\n\nexport function DocumentTable({\n workspaceId,\n documents,\n onOpenDocument,\n openOnRowClick = true,\n selectedIds,\n onSelectionChange,\n height = 480,\n extraColumns,\n className,\n}: DocumentTableProps) {\n // Server data via the SDK hook, unless rows are supplied directly.\n const query = useDocuments(workspaceId, { enabled: !documents })\n const rows = documents ?? query.data ?? []\n const isLoading = !documents && query.isLoading\n\n // Resolve tag ids → human names so the \"Labels\" column shows real AI tags\n // (e.g. \"Issue\", \"Relevance\") rather than opaque id prefixes.\n const tagsQuery = useTags(workspaceId)\n const tagNameById = React.useMemo(() => {\n const map = new Map<string, string>()\n for (const t of tagsQuery.data ?? []) {\n if (t.external_id) map.set(t.external_id, t.name ?? t.external_id.slice(0, 8))\n }\n return map\n }, [tagsQuery.data])\n\n // Selection: controlled via props, else the SDK-owned ui store.\n const storeSelected = useArbiUiStore((s) => s.selectedDocIds)\n const storeSetSelected = useArbiUiStore((s) => s.setSelectedDocIds)\n const viewingDocId = useArbiUiStore((s) => s.viewingDocId)\n const setViewingDocId = useArbiUiStore((s) => s.setViewingDocId)\n\n const effectiveSelected = selectedIds ?? storeSelected\n const emitSelection = onSelectionChange ?? storeSetSelected\n\n const gridApiRef = React.useRef<GridReadyEvent['api'] | null>(null)\n\n const openDocument = React.useCallback(\n (id: string) => {\n setViewingDocId(id)\n onOpenDocument?.(id)\n },\n [onOpenDocument, setViewingDocId]\n )\n\n // Sync the incoming `effectiveSelected` down into the grid's node selection.\n const applySelection = React.useCallback(() => {\n const api = gridApiRef.current\n if (!api) return\n const wanted = new Set(effectiveSelected)\n api.forEachNode((node) => {\n const id = (node.data as DocResponse | undefined)?.external_id\n const shouldSelect = !!id && wanted.has(id)\n if (node.isSelected() !== shouldSelect) node.setSelected(shouldSelect)\n })\n }, [effectiveSelected])\n\n React.useEffect(() => {\n applySelection()\n }, [applySelection])\n\n const columnDefs = React.useMemo<ColDef<DocResponse>[]>(\n () => [\n {\n colId: 'select',\n headerName: '',\n width: 44,\n pinned: 'left',\n checkboxSelection: true,\n headerCheckboxSelection: true,\n sortable: false,\n filter: false,\n resizable: false,\n suppressMovable: true,\n },\n {\n colId: 'title',\n headerName: 'Document Name',\n flex: 3,\n minWidth: 240,\n sortable: true,\n valueGetter: (p) => p.data?.doc_metadata?.title || p.data?.file_name || '',\n cellRenderer: (p: ICellRendererParams<DocResponse>) => {\n const doc = p.data\n if (!doc) return null\n return (\n <DocumentEntity\n doc={doc}\n size=\"base\"\n fullWidth\n viewing={viewingDocId === doc.external_id}\n onClick={(e) => {\n e.stopPropagation()\n if (doc.external_id) openDocument(doc.external_id)\n }}\n />\n )\n },\n },\n {\n colId: 'status',\n headerName: 'Status',\n width: 140,\n sortable: true,\n field: 'status',\n cellRenderer: (p: ICellRendererParams<DocResponse>) => {\n const status = p.data?.status\n if (!status) return null\n return (\n <Badge variant={STATUS_VARIANTS[status.toLowerCase()] ?? 'secondary'}>{status}</Badge>\n )\n },\n },\n {\n colId: 'all_tags',\n headerName: 'Labels',\n flex: 1,\n minWidth: 160,\n sortable: false,\n filter: false,\n cellRenderer: (p: ICellRendererParams<DocResponse>) => {\n const doctags = p.data?.doctags ?? []\n if (doctags.length === 0) return null\n return (\n <div className=\"flex flex-wrap items-center gap-1 py-1\">\n {doctags.map((dt) => (\n <TagEntity\n key={dt.tag_ext_id}\n size=\"sm\"\n tag={{\n external_id: dt.tag_ext_id,\n name: tagNameById.get(dt.tag_ext_id) ?? dt.tag_ext_id.slice(0, 8),\n }}\n />\n ))}\n </div>\n )\n },\n },\n {\n colId: 'file_size',\n headerName: 'Size',\n width: 110,\n sortable: true,\n field: 'file_size',\n valueFormatter: (p) => formatBytes(p.value as number | null | undefined),\n },\n {\n colId: 'folder',\n headerName: 'Folder',\n flex: 1,\n minWidth: 140,\n sortable: true,\n field: 'folder',\n valueFormatter: (p) => (p.value as string | null | undefined) || '—',\n },\n ...(extraColumns ?? []),\n ],\n [openDocument, viewingDocId, tagNameById, extraColumns]\n )\n\n const handleGridReady = (e: GridReadyEvent) => {\n gridApiRef.current = e.api\n applySelection()\n }\n\n const handleSelectionChanged = (e: SelectionChangedEvent) => {\n const ids = e.api\n .getSelectedRows()\n .map((r) => (r as DocResponse).external_id)\n .filter((id): id is string => !!id)\n emitSelection(ids)\n }\n\n const handleRowClicked = (e: RowClickedEvent) => {\n if (!openOnRowClick) return\n const id = (e.data as DocResponse | undefined)?.external_id\n if (id) openDocument(id)\n }\n\n const getRowId = React.useCallback((params: { data: DocResponse }) => params.data.external_id, [])\n\n const autoHeight = height === 'auto'\n const style: React.CSSProperties = autoHeight\n ? {}\n : { height: typeof height === 'number' ? `${height}px` : height, width: '100%' }\n\n if (isLoading) {\n return (\n <div className={className} style={style}>\n <div className=\"flex h-full w-full items-center justify-center p-8 text-sm text-muted-foreground\">\n Loading documents…\n </div>\n </div>\n )\n }\n\n if (rows.length === 0) {\n return (\n <div className={className} style={style}>\n <div className=\"flex h-full w-full items-center justify-center p-8 text-sm text-muted-foreground\">\n No documents\n </div>\n </div>\n )\n }\n\n return (\n <div className={className} style={style}>\n <AgGridReact<DocResponse>\n columnDefs={columnDefs}\n rowData={rows}\n getRowId={getRowId}\n rowSelection=\"multiple\"\n suppressRowClickSelection\n domLayout={autoHeight ? 'autoHeight' : 'normal'}\n rowHeight={44}\n onGridReady={handleGridReady}\n onSelectionChanged={handleSelectionChanged}\n onRowClicked={handleRowClicked}\n />\n </div>\n )\n}\n","/**\n * The ⋯ actions menu that sits in a document tile's top-right corner.\n *\n * Every item maps to a real SDK operation, so any app that renders a document\n * grid gets the same verbs without re-implementing them. `onOpen` and `onRename`\n * are delegated upward (opening and inline renaming are the grid's concern);\n * download and delete are performed here.\n */\n\nimport React from 'react'\nimport { useMutation, useQueryClient } from '@tanstack/react-query'\nimport { Download, MoreHorizontal, Pencil, SquarePen, Trash2 } from 'lucide-react'\n\nimport { useArbi } from '../useArbi'\nimport { arbiQueryKeys } from '../hooks'\nimport {\n DropdownMenu,\n DropdownMenuContent,\n DropdownMenuItem,\n DropdownMenuSeparator,\n DropdownMenuTrigger,\n} from '../ui/dropdown-menu'\n\nexport interface DocumentCardMenuProps {\n docId: string\n /** Used as the download filename. */\n fileName: string\n onOpen?: () => void\n onRename?: () => void\n /** Omit to hide the delete item (e.g. the user lacks permission). */\n canDelete?: boolean\n testId?: string\n}\n\nexport function DocumentCardMenu({\n docId,\n fileName,\n onOpen,\n onRename,\n canDelete = true,\n testId = 'document-card-menu',\n}: DocumentCardMenuProps) {\n const arbi = useArbi()\n const queryClient = useQueryClient()\n\n const invalidateDocuments = () => {\n const workspaceId = arbi.getWorkspaceId()\n if (workspaceId) {\n void queryClient.invalidateQueries({ queryKey: arbiQueryKeys.documents(workspaceId) })\n }\n }\n\n const download = useMutation({\n mutationFn: async () => {\n const response = await arbi.documents.download(docId)\n if (!response.ok) throw new Error(`Failed to download ${fileName}`)\n return response.blob()\n },\n onSuccess: (blob) => {\n // Hand the bytes to the browser, then release the object URL.\n const url = URL.createObjectURL(blob)\n const anchor = document.createElement('a')\n anchor.href = url\n anchor.download = fileName\n anchor.click()\n URL.revokeObjectURL(url)\n },\n })\n\n const remove = useMutation({\n mutationFn: () => arbi.documents.delete([docId]),\n onSuccess: invalidateDocuments,\n })\n\n return (\n <DropdownMenu>\n <DropdownMenuTrigger asChild>\n <button\n type=\"button\"\n aria-label=\"More actions\"\n data-testid={testId}\n onClick={(e) => e.stopPropagation()}\n className=\"flex size-6 items-center justify-center rounded-md bg-background/90 text-muted-foreground shadow-sm backdrop-blur-sm transition hover:bg-background hover:text-foreground data-[state=open]:bg-background data-[state=open]:text-foreground\"\n >\n <MoreHorizontal className=\"size-4\" />\n </button>\n </DropdownMenuTrigger>\n <DropdownMenuContent align=\"start\" onClick={(e) => e.stopPropagation()} className=\"w-44\">\n {onOpen && (\n <DropdownMenuItem onSelect={onOpen} data-testid={`${testId}-open`}>\n <SquarePen className=\"mr-2 size-4\" />\n Open\n </DropdownMenuItem>\n )}\n {onRename && (\n <DropdownMenuItem onSelect={onRename} data-testid={`${testId}-rename`}>\n <Pencil className=\"mr-2 size-4\" />\n Rename\n </DropdownMenuItem>\n )}\n <DropdownMenuItem\n onSelect={() => download.mutate()}\n disabled={download.isPending}\n data-testid={`${testId}-download`}\n >\n <Download className=\"mr-2 size-4\" />\n Download\n </DropdownMenuItem>\n {canDelete && (\n <>\n <DropdownMenuSeparator />\n <DropdownMenuItem\n onSelect={() => remove.mutate()}\n disabled={remove.isPending}\n className=\"text-destructive focus:text-destructive\"\n data-testid={`${testId}-delete`}\n >\n <Trash2 className=\"mr-2 size-4\" />\n Delete\n </DropdownMenuItem>\n </>\n )}\n </DropdownMenuContent>\n </DropdownMenu>\n )\n}\n","/**\n * DocumentGallery — a reusable thumbnail-grid view of a workspace's documents.\n *\n * REUSE-FIRST: a sibling of `DocumentTable` sharing the exact same data sources\n * (`useDocuments` + `useTags` + the SDK-owned `useArbiUiStore` selection state).\n * The only extra dependency is `useThumbnails`, which batch-loads real first-page\n * previews. Each tile is a `DocumentCard`; this component only binds it to data.\n */\n\nimport React from 'react'\nimport { useMutation, useQueryClient } from '@tanstack/react-query'\nimport type { components } from '@arbidocs/client'\n\nimport { useArbi } from '../useArbi'\nimport { arbiQueryKeys, useDocuments, useTags, useThumbnails } from '../hooks'\nimport { useArbiUiStore } from '../store'\nimport { DocumentCard } from './DocumentCard'\nimport { DocumentCardMenu } from './DocumentCardMenu'\nimport { cn } from '../lib/utils'\n\ntype DocResponse = components['schemas']['DocResponse']\n\nexport interface DocumentGalleryProps {\n /** Workspace to load documents from (used when `documents` is not supplied). */\n workspaceId?: string\n /** Explicit rows. When provided, `useDocuments` is not called. */\n documents?: DocResponse[]\n /** Called when a card (document) is opened. */\n onOpenDocument?: (id: string) => void\n /** Controlled selection (external ids). Falls back to the SDK ui store. */\n selectedIds?: string[]\n /** Called with the new selection (external ids). Falls back to the SDK ui store. */\n onSelectionChange?: (ids: string[]) => void\n /** Min tile width in px — the grid auto-fills as many columns as fit. Default 148. */\n minTileWidth?: number\n className?: string\n}\n\nfunction docTitle(doc: DocResponse): string {\n return doc.doc_metadata?.title || doc.file_name || 'Untitled'\n}\n\n/** The tile's hover card: the full (unclamped) title, then the document's labels. */\nfunction TileTooltip({ title, labels }: { title: string; labels: string[] }) {\n return (\n <div className=\"max-w-xs space-y-2\">\n <div className=\"break-words text-xs font-semibold leading-snug\">{title}</div>\n {labels.length > 0 && (\n <div className=\"flex flex-wrap gap-1 border-t border-border/60 pt-1.5\">\n {labels.map((label) => (\n <span\n key={label}\n className=\"rounded bg-muted px-1.5 py-0.5 text-xs font-medium text-foreground/80\"\n >\n {label}\n </span>\n ))}\n </div>\n )}\n </div>\n )\n}\n\nexport function DocumentGallery({\n workspaceId,\n documents,\n onOpenDocument,\n selectedIds,\n onSelectionChange,\n minTileWidth = 148,\n className,\n}: DocumentGalleryProps) {\n const query = useDocuments(workspaceId, { enabled: !documents })\n const rows = documents ?? query.data ?? []\n const isLoading = !documents && query.isLoading\n\n const tagsQuery = useTags(workspaceId)\n const tagNameById = React.useMemo(() => {\n const map = new Map<string, string>()\n for (const t of tagsQuery.data ?? []) {\n if (t.external_id) map.set(t.external_id, t.name ?? t.external_id.slice(0, 8))\n }\n return map\n }, [tagsQuery.data])\n\n const docIds = React.useMemo(\n () => rows.map((d) => d.external_id).filter((id): id is string => !!id),\n [rows]\n )\n const thumbsQuery = useThumbnails(docIds)\n const thumbs = thumbsQuery.data ?? {}\n\n // Selection: controlled via props, else the SDK-owned ui store.\n const storeSelected = useArbiUiStore((s) => s.selectedDocIds)\n const storeSetSelected = useArbiUiStore((s) => s.setSelectedDocIds)\n const viewingDocId = useArbiUiStore((s) => s.viewingDocId)\n const setViewingDocId = useArbiUiStore((s) => s.setViewingDocId)\n\n const effectiveSelected = selectedIds ?? storeSelected\n const emitSelection = onSelectionChange ?? storeSetSelected\n const selectedSet = React.useMemo(() => new Set(effectiveSelected), [effectiveSelected])\n\n const toggleSelected = React.useCallback(\n (id: string) => {\n const next = new Set(effectiveSelected)\n if (next.has(id)) next.delete(id)\n else next.add(id)\n emitSelection([...next])\n },\n [effectiveSelected, emitSelection]\n )\n\n const openDocument = React.useCallback(\n (id: string) => {\n setViewingDocId(id)\n onOpenDocument?.(id)\n },\n [onOpenDocument, setViewingDocId]\n )\n\n // Inline rename lives here rather than in the tile: only one document at a\n // time can be renamed, and the mutation belongs with the other data wiring.\n const arbi = useArbi()\n const queryClient = useQueryClient()\n const [renamingId, setRenamingId] = React.useState<string | null>(null)\n\n const rename = useMutation({\n mutationFn: ({ doc, title }: { doc: DocResponse; title: string }) =>\n arbi.documents.update([\n { external_id: doc.external_id, doc_metadata: { ...doc.doc_metadata, title } },\n ]),\n onSettled: () => {\n setRenamingId(null)\n const activeWorkspace = workspaceId ?? arbi.getWorkspaceId()\n if (activeWorkspace) {\n void queryClient.invalidateQueries({ queryKey: arbiQueryKeys.documents(activeWorkspace) })\n }\n },\n })\n\n if (isLoading) {\n return (\n <div\n className={cn(\n 'flex items-center justify-center p-8 text-sm text-muted-foreground',\n className\n )}\n >\n Loading documents…\n </div>\n )\n }\n\n if (rows.length === 0) {\n return (\n <div\n className={cn(\n 'flex items-center justify-center p-8 text-sm text-muted-foreground',\n className\n )}\n >\n No documents\n </div>\n )\n }\n\n return (\n <div\n data-testid=\"document-gallery\"\n className={cn('grid gap-3', className)}\n style={{ gridTemplateColumns: `repeat(auto-fill, minmax(${minTileWidth}px, 1fr))` }}\n >\n {rows.map((doc) => {\n const id = doc.external_id\n if (!id) return null\n const title = docTitle(doc)\n const labels = (doc.doctags ?? []).map(\n (dt) => tagNameById.get(dt.tag_ext_id) ?? dt.tag_ext_id.slice(0, 8)\n )\n\n return (\n <div key={id} data-doc-id={id} data-testid=\"document-gallery-card\">\n <DocumentCard\n doc={doc}\n thumbnailUrl={thumbs[id]}\n status={doc.status}\n selected={selectedSet.has(id)}\n onToggleSelect={() => toggleSelected(id)}\n viewing={viewingDocId === id}\n onOpen={() => openDocument(id)}\n renaming={renamingId === id}\n onCommitRename={(newTitle) => rename.mutate({ doc, title: newTitle })}\n onCancelRename={() => setRenamingId(null)}\n actions={\n <DocumentCardMenu\n docId={id}\n fileName={doc.file_name ?? title}\n onOpen={() => openDocument(id)}\n onRename={() => setRenamingId(id)}\n testId={`document-card-menu-${id}`}\n />\n }\n tooltipContent={<TileTooltip title={title} labels={labels} />}\n />\n </div>\n )\n })}\n </div>\n )\n}\n","/**\n * VoiceNoteRecorder\n *\n * A toggle-style recorder (press to start, pause/resume, stop, review, then\n * save or discard) as opposed to a press-and-hold mic. Shares its\n * capture/metering engine (useAudioRecorder) and its REC-badge/timer/waveform\n * visual (MicWaveformIndicator) with any other recorder a host app builds.\n *\n * REUSE-FIRST: no app coupling. The host supplies `onSave`/`onDiscard` (and\n * optionally `onError`) — this component owns only the recording UI and\n * in-memory blob, never persistence. Nothing is uploaded until the host's\n * `onSave` is called and resolves.\n */\n\nimport { useEffect, useState } from 'react'\nimport { Mic, Pause, Play, Square, Trash2, Check, Loader2, RotateCcw } from 'lucide-react'\nimport { Button } from '../ui/button'\nimport { AudioViewer } from '../viewers/AudioViewer'\nimport { useAudioRecorder } from './useAudioRecorder'\nimport { MicWaveformIndicator } from './MicWaveformIndicator'\n\nexport interface VoiceNoteRecorderProps {\n /** Called with the reviewed recording when the user hits Save. Resolve to\n * let the host close/replace this recorder; the recorder shows a saving\n * spinner while the promise is pending. */\n onSave: (blob: Blob, mimeType: string | null) => Promise<void> | void\n /** Called when the user discards the draft. */\n onDiscard: () => void\n /** Surfaces recorder failures (e.g. denied mic permission) — wire this to\n * the host's own notification system. Without it, failures are silent. */\n onError?: (message: string) => void\n /** Title passed through to the playback preview. */\n title?: string\n /** External saving state, e.g. while the host's onSave promise is\n * pending — disables actions and shows a spinner on Save. */\n isSaving?: boolean\n /**\n * Optional: called once with the finished recording as soon as it stops,\n * to produce a quick rough transcript shown inline during review. Purely\n * client-side and ephemeral — it's never uploaded and has no bearing on\n * what onSave receives; a host with real (e.g. diarized) transcription as\n * part of its normal document processing can skip this prop entirely.\n */\n transcribe?: (blob: Blob) => Promise<string>\n}\n\nexport function VoiceNoteRecorder({\n onSave,\n onDiscard,\n onError,\n title = 'Voice Memo',\n isSaving = false,\n transcribe,\n}: VoiceNoteRecorderProps) {\n const recorder = useAudioRecorder()\n const [transcript, setTranscript] = useState<string | null>(null)\n const [isTranscribing, setIsTranscribing] = useState(false)\n\n useEffect(() => {\n if (recorder.error) onError?.(recorder.error)\n // eslint-disable-next-line react-hooks/exhaustive-deps\n }, [recorder.error])\n\n // Kick off the rough transcript the moment a recording is ready to review,\n // so it's usually done by the time the user has looked at the playback\n // controls. Reset on any state other than 'stopped' (re-record, discard)\n // so a stale transcript from a previous take never lingers.\n useEffect(() => {\n if (recorder.state !== 'stopped' || !recorder.blob) {\n setTranscript(null)\n setIsTranscribing(false)\n return\n }\n if (!transcribe) return\n let cancelled = false\n setIsTranscribing(true)\n transcribe(recorder.blob)\n .then((text) => {\n if (!cancelled) setTranscript(text)\n })\n .catch(() => {\n // Best-effort: a failed rough transcript just means the review UI\n // shows nothing extra — the real transcript still arrives later.\n })\n .finally(() => {\n if (!cancelled) setIsTranscribing(false)\n })\n return () => {\n cancelled = true\n }\n // eslint-disable-next-line react-hooks/exhaustive-deps\n }, [recorder.state, recorder.blob])\n\n const handleSave = () => {\n if (!recorder.blob) return\n void onSave(recorder.blob, recorder.mimeType)\n }\n\n return (\n <div className=\"flex h-full flex-col items-center justify-center gap-6 p-8\">\n {recorder.state === 'idle' && (\n <>\n <Button\n type=\"button\"\n size=\"lg\"\n className=\"h-16 w-16 rounded-full p-0\"\n onClick={() => void recorder.start()}\n data-testid=\"voice-note-record-button\"\n >\n <Mic className=\"h-6 w-6\" />\n </Button>\n <p className=\"text-sm text-muted-foreground\">Press to start recording</p>\n </>\n )}\n\n {(recorder.state === 'recording' || recorder.state === 'paused') && (\n <>\n <MicWaveformIndicator\n level={recorder.level}\n elapsedMs={recorder.elapsedMs}\n paused={recorder.state === 'paused'}\n />\n <div className=\"flex items-center gap-3\">\n {recorder.state === 'recording' ? (\n <Button\n type=\"button\"\n variant=\"outline\"\n onClick={recorder.pause}\n data-testid=\"voice-note-pause-button\"\n >\n <Pause className=\"mr-1.5 h-4 w-4\" />\n Pause\n </Button>\n ) : (\n <Button\n type=\"button\"\n variant=\"outline\"\n onClick={recorder.resume}\n data-testid=\"voice-note-resume-button\"\n >\n <Play className=\"mr-1.5 h-4 w-4\" />\n Resume\n </Button>\n )}\n <Button type=\"button\" onClick={recorder.stop} data-testid=\"voice-note-stop-button\">\n <Square className=\"mr-1.5 h-3.5 w-3.5 fill-current\" />\n Stop\n </Button>\n </div>\n </>\n )}\n\n {recorder.state === 'stopped' && recorder.blob && (\n <>\n <div className=\"w-full max-w-md\">\n <AudioViewer blob={recorder.blob} title={title} />\n </div>\n {(isTranscribing || transcript) && (\n <div\n className=\"w-full max-w-md rounded-md border border-border bg-muted/30 p-3 text-sm text-muted-foreground\"\n data-testid=\"voice-note-rough-transcript\"\n >\n {isTranscribing ? (\n <span className=\"flex items-center gap-1.5\">\n <Loader2 className=\"h-3.5 w-3.5 animate-spin\" />\n Transcribing…\n </span>\n ) : (\n <>\n <p className=\"mb-1 text-xs font-semibold uppercase tracking-wide\">\n Rough transcript\n </p>\n <p>{transcript}</p>\n </>\n )}\n </div>\n )}\n <div className=\"flex items-center gap-3\">\n <Button\n type=\"button\"\n variant=\"outline\"\n onClick={onDiscard}\n disabled={isSaving}\n data-testid=\"voice-note-discard-button\"\n >\n <Trash2 className=\"mr-1.5 h-4 w-4\" />\n Discard\n </Button>\n <Button\n type=\"button\"\n variant=\"outline\"\n onClick={recorder.reset}\n disabled={isSaving}\n data-testid=\"voice-note-record-again-button\"\n >\n <RotateCcw className=\"mr-1.5 h-4 w-4\" />\n Record again\n </Button>\n <Button\n type=\"button\"\n onClick={handleSave}\n disabled={isSaving}\n data-testid=\"voice-note-save-button\"\n >\n {isSaving ? (\n <Loader2 className=\"mr-1.5 h-4 w-4 animate-spin\" />\n ) : (\n <Check className=\"mr-1.5 h-4 w-4\" />\n )}\n {isSaving ? 'Saving…' : 'Save'}\n </Button>\n </div>\n </>\n )}\n </div>\n )\n}\n","/**\n * DraftTitleControls\n *\n * A title field + an auto-name toggle for an unsaved draft (blank document,\n * voice note, or anything else a host app drafts before it exists on the\n * backend) — so picking a name or leaving AI generation on doesn't require a\n * separate settings surface.\n *\n * REUSE-FIRST: props/callbacks in, no store or config-API coupling. The host\n * owns where `title` is stored and what `autoRename` actually controls (in\n * ARBI-frontend, the same `DoctagLLM.AUTO_RENAME` config field the Upload\n * modal's toggle already writes).\n */\n\nimport { Sparkles } from 'lucide-react'\nimport { IconToggle } from '../ui/IconToggle'\n\nconst AUTO_RENAME_COLORS = { text: 'text-amber-700', bg: 'bg-amber-500' }\n\nexport interface DraftTitleControlsProps {\n title: string\n onTitleChange: (title: string) => void\n placeholder: string\n autoRename: boolean\n onAutoRenameChange: (value: boolean) => void\n}\n\nexport function DraftTitleControls({\n title,\n onTitleChange,\n placeholder,\n autoRename,\n onAutoRenameChange,\n}: DraftTitleControlsProps) {\n return (\n <div className=\"flex min-w-0 flex-shrink-0 items-center gap-1.5\">\n <input\n type=\"text\"\n value={title}\n onChange={(e) => onTitleChange(e.target.value)}\n placeholder={placeholder}\n className=\"min-w-0 max-w-[220px] rounded-md bg-muted px-2 py-1 text-sm font-medium outline-none focus-visible:ring-1 focus-visible:ring-primary\"\n data-testid=\"draft-title-input\"\n />\n <IconToggle\n icon={Sparkles}\n isActive={autoRename}\n onToggle={onAutoRenameChange}\n colors={AUTO_RENAME_COLORS}\n tooltipActive=\"Auto-name from content is on — generates a title once saved\"\n tooltipInactive=\"Auto-name from content is off — uses the name typed above\"\n data-testid=\"draft-auto-rename-toggle\"\n />\n </div>\n )\n}\n","/**\n * useCameraStream\n *\n * Shared camera-acquisition engine for photo and video capture — requests\n * `getUserMedia`, hands back the live `MediaStream` for a host to bind to a\n * `<video>` element, and tears the tracks down on stop()/unmount. Mirrors\n * `useAudioRecorder`'s permission/error handling (same DOMException\n * classification, via `classifyMediaError`) but stays a separate hook rather\n * than folding into it: audio's state machine centers on an AnalyserNode\n * level meter with no visual preview, while camera capture centers on a live\n * video preview with no metering — sharing \"here is a device stream and an\n * error string\" is the useful overlap, not the recording state machine\n * itself. `useVideoRecorder` layers MediaRecorder on top of the stream this\n * returns; photo capture reads a frame off it directly (see capture-frame.ts).\n *\n * REUSE-FIRST: no app coupling, failures surface via `error` rather than a\n * toast call — same contract as useAudioRecorder.\n */\n\nimport { useCallback, useEffect, useRef, useState } from 'react'\nimport { classifyMediaError } from './media-error'\n\nexport interface UseCameraStreamResult {\n /** The live camera stream, or null before start()/after stop(). */\n stream: MediaStream | null\n /** True while the getUserMedia() prompt/negotiation is in flight. */\n isStarting: boolean\n /** A human-readable message from the last failed start() attempt. */\n error: string | null\n start: () => Promise<void>\n /** Stops all tracks and clears the stream. Safe to call repeatedly. */\n stop: () => void\n}\n\n/**\n * @param constraints The `video`/`audio` constraints passed to getUserMedia.\n * Defaults to video-only (photo capture never needs a mic); video capture\n * passes `{ video: true, audio: true }` to record sound with the picture.\n */\nexport function useCameraStream(\n constraints: MediaStreamConstraints = { video: true, audio: false }\n): UseCameraStreamResult {\n const [stream, setStream] = useState<MediaStream | null>(null)\n const [isStarting, setIsStarting] = useState(false)\n const [error, setError] = useState<string | null>(null)\n const streamRef = useRef<MediaStream | null>(null)\n\n const stop = useCallback(() => {\n streamRef.current?.getTracks().forEach((t) => t.stop())\n streamRef.current = null\n setStream(null)\n }, [])\n\n // Constraints are read fresh each start() call rather than becoming a hook\n // dependency: a host re-rendering with a new (but equivalent) constraints\n // object shouldn't force callers to memoize it just to avoid an effect loop.\n const constraintsRef = useRef(constraints)\n constraintsRef.current = constraints\n\n const start = useCallback(async () => {\n if (streamRef.current) return\n setError(null)\n setIsStarting(true)\n try {\n const media = await navigator.mediaDevices.getUserMedia(constraintsRef.current)\n streamRef.current = media\n setStream(media)\n } catch (err) {\n setError(classifyMediaError(err, 'camera'))\n } finally {\n setIsStarting(false)\n }\n }, [])\n\n useEffect(() => () => stop(), [stop])\n\n return { stream, isStarting, error, start, stop }\n}\n","/**\n * useVideoRecorder\n *\n * MediaRecorder lifecycle for video capture, layered on top of an\n * already-live camera `MediaStream` (see useCameraStream — this hook does\n * NOT call getUserMedia itself, so the same stream stays open across a\n * stop()/reset() \"record again\" without re-prompting for permission).\n *\n * Deliberately simpler than useAudioRecorder: no pause/resume (tap-to-start,\n * tap-to-stop is the whole interaction — see MediaCaptureRecorder) and no\n * level meter (there's a live video preview instead; a bar-graph loudness\n * meter would be redundant chrome on top of it).\n */\n\nimport { useCallback, useEffect, useRef, useState } from 'react'\n\nexport type VideoRecorderState = 'idle' | 'recording' | 'stopped'\n\nexport interface UseVideoRecorderResult {\n state: VideoRecorderState\n /** Recorded duration so far (ms). Frozen at its final value once stopped. */\n elapsedMs: number\n /** The finished recording. Only set once state === 'stopped'. */\n blob: Blob | null\n /** The MediaRecorder MIME type used (e.g. 'video/webm'). */\n mimeType: string | null\n start: () => void\n stop: () => void\n /** Back to idle: clears blob/elapsedMs, ready to record again on the same stream. */\n reset: () => void\n}\n\nconst ELAPSED_TICK_MS = 200\n\n/** @param stream The live camera stream to record — null while the camera\n * hasn't started yet; start() is a no-op until it's set. */\nexport function useVideoRecorder(stream: MediaStream | null): UseVideoRecorderResult {\n const [state, setState] = useState<VideoRecorderState>('idle')\n const [elapsedMs, setElapsedMs] = useState(0)\n const [blob, setBlob] = useState<Blob | null>(null)\n const [mimeType, setMimeType] = useState<string | null>(null)\n\n const mediaRecorderRef = useRef<MediaRecorder | null>(null)\n const chunksRef = useRef<Blob[]>([])\n const startedAtRef = useRef(0)\n const tickRef = useRef<ReturnType<typeof setInterval> | null>(null)\n const stateRef = useRef<VideoRecorderState>('idle')\n stateRef.current = state\n\n const stopTicking = useCallback(() => {\n if (tickRef.current !== null) clearInterval(tickRef.current)\n tickRef.current = null\n }, [])\n\n useEffect(() => stopTicking, [stopTicking])\n\n const start = useCallback(() => {\n if (!stream || stateRef.current === 'recording') return\n const mt = MediaRecorder.isTypeSupported('video/webm') ? 'video/webm' : 'video/mp4'\n const recorder = new MediaRecorder(stream, { mimeType: mt })\n chunksRef.current = []\n recorder.ondataavailable = (e) => {\n if (e.data.size > 0) chunksRef.current.push(e.data)\n }\n mediaRecorderRef.current = recorder\n setMimeType(mt)\n setBlob(null)\n startedAtRef.current = performance.now()\n setElapsedMs(0)\n recorder.start()\n setState('recording')\n tickRef.current = setInterval(() => {\n setElapsedMs(performance.now() - startedAtRef.current)\n }, ELAPSED_TICK_MS)\n }, [stream])\n\n const stop = useCallback(() => {\n const recorder = mediaRecorderRef.current\n if (!recorder || recorder.state === 'inactive') return\n const finalElapsed = performance.now() - startedAtRef.current\n stopTicking()\n recorder.onstop = () => {\n const finalBlob = chunksRef.current.length\n ? new Blob(chunksRef.current, { type: recorder.mimeType })\n : null\n setBlob(finalBlob)\n setElapsedMs(finalElapsed)\n setState('stopped')\n }\n recorder.stop()\n }, [stopTicking])\n\n const reset = useCallback(() => {\n setState('idle')\n setBlob(null)\n setElapsedMs(0)\n setMimeType(null)\n }, [])\n\n return { state, elapsedMs, blob, mimeType, start, stop, reset }\n}\n","/**\n * Captures the current frame of a live `<video>` element (bound to a camera\n * `MediaStream`, e.g. via useCameraStream) as an image Blob — the shutter\n * action for photo capture. Draws to an off-screen canvas rather than reading\n * pixels any other way, since `HTMLCanvasElement.toBlob` is the one\n * cross-browser path from \"a decoded video frame\" to \"an encoded image file\".\n */\nexport function captureFrameAsBlob(video: HTMLVideoElement, mimeType = 'image/png'): Promise<Blob> {\n return new Promise((resolve, reject) => {\n const canvas = document.createElement('canvas')\n canvas.width = video.videoWidth\n canvas.height = video.videoHeight\n const ctx = canvas.getContext('2d')\n if (!ctx) {\n reject(new Error('Canvas 2D context is not available'))\n return\n }\n ctx.drawImage(video, 0, 0, canvas.width, canvas.height)\n canvas.toBlob((blob) => {\n if (blob) resolve(blob)\n else reject(new Error('Failed to capture the photo'))\n }, mimeType)\n })\n}\n","/**\n * PhotoCapture\n *\n * Camera capture UI: live preview → shutter → review (retake or save).\n * Shares its shape (onSave/onDiscard/onError/isSaving) with VoiceNoteRecorder\n * so a host app wires them identically — see MediaCaptureRecorder.tsx (the\n * ARBI-frontend wrapper) for how the three capture modes plug into the same\n * draft/save contract.\n *\n * REUSE-FIRST: no app coupling. This component owns only the capture UI and\n * in-memory blob, never persistence — nothing is uploaded until the host's\n * `onSave` is called.\n */\n\nimport { useEffect, useRef, useState } from 'react'\nimport { Camera, Check, Loader2, RotateCcw, Trash2 } from 'lucide-react'\nimport { Button } from '../ui/button'\nimport { ImageViewer } from '../viewers/ImageViewer'\nimport { useCameraStream } from './useCameraStream'\nimport { captureFrameAsBlob } from './capture-frame'\n\nexport interface PhotoCaptureProps {\n /** Called with the captured photo when the user hits Save. Resolve to let\n * the host close/replace this capture UI; shows a saving spinner while\n * the promise is pending. */\n onSave: (blob: Blob, mimeType: string | null) => Promise<void> | void\n /** Called when the user discards the draft. */\n onDiscard: () => void\n /** Surfaces camera failures (e.g. denied permission) — wire this to the\n * host's own notification system. Without it, failures are silent. */\n onError?: (message: string) => void\n isSaving?: boolean\n}\n\nexport function PhotoCapture({ onSave, onDiscard, onError, isSaving = false }: PhotoCaptureProps) {\n const camera = useCameraStream({ video: true, audio: false })\n const videoRef = useRef<HTMLVideoElement>(null)\n const [capturedBlob, setCapturedBlob] = useState<Blob | null>(null)\n const [captureError, setCaptureError] = useState<string | null>(null)\n\n useEffect(() => {\n void camera.start()\n // Start the camera once on mount — camera.start is stable (useCallback\n // with no deps), so this intentionally doesn't re-run per render.\n // eslint-disable-next-line react-hooks/exhaustive-deps\n }, [])\n\n useEffect(() => {\n if (camera.error) onError?.(camera.error)\n // eslint-disable-next-line react-hooks/exhaustive-deps\n }, [camera.error])\n\n useEffect(() => {\n const video = videoRef.current\n if (!video) return\n video.srcObject = camera.stream\n if (camera.stream) void video.play().catch(() => {})\n }, [camera.stream])\n\n const handleShutter = () => {\n const video = videoRef.current\n if (!video) return\n setCaptureError(null)\n captureFrameAsBlob(video)\n .then(setCapturedBlob)\n .catch((err) => {\n const message = err instanceof Error ? err.message : 'Failed to capture the photo'\n setCaptureError(message)\n onError?.(message)\n })\n }\n\n const handleRetake = () => setCapturedBlob(null)\n\n const handleSave = () => {\n if (!capturedBlob) return\n void onSave(capturedBlob, 'image/png')\n }\n\n return (\n <div className=\"flex h-full flex-col items-center justify-center gap-6 p-8\">\n {!capturedBlob && (\n <>\n <div className=\"w-full max-w-md overflow-hidden rounded-lg bg-muted/30\">\n <video\n ref={videoRef}\n autoPlay\n muted\n playsInline\n className=\"w-full max-h-[60vh] object-contain\"\n data-testid=\"photo-capture-preview\"\n />\n </div>\n <Button\n type=\"button\"\n size=\"lg\"\n className=\"h-16 w-16 rounded-full p-0\"\n onClick={handleShutter}\n disabled={!camera.stream}\n data-testid=\"photo-capture-shutter-button\"\n >\n <Camera className=\"h-6 w-6\" />\n </Button>\n <p className=\"text-sm text-muted-foreground\">\n {camera.isStarting\n ? 'Starting camera…'\n : camera.stream\n ? 'Press to take a photo'\n : 'Waiting for camera access…'}\n </p>\n {captureError && <p className=\"text-sm text-red-text\">{captureError}</p>}\n </>\n )}\n\n {capturedBlob && (\n <>\n <div className=\"w-full max-w-md\">\n <ImageViewer blob={capturedBlob} alt=\"Captured photo\" />\n </div>\n <div className=\"flex items-center gap-3\">\n <Button\n type=\"button\"\n variant=\"outline\"\n onClick={onDiscard}\n disabled={isSaving}\n data-testid=\"photo-capture-discard-button\"\n >\n <Trash2 className=\"mr-1.5 h-4 w-4\" />\n Discard\n </Button>\n <Button\n type=\"button\"\n variant=\"outline\"\n onClick={handleRetake}\n disabled={isSaving}\n data-testid=\"photo-capture-retake-button\"\n >\n <RotateCcw className=\"mr-1.5 h-4 w-4\" />\n Retake\n </Button>\n <Button\n type=\"button\"\n onClick={handleSave}\n disabled={isSaving}\n data-testid=\"photo-capture-save-button\"\n >\n {isSaving ? (\n <Loader2 className=\"mr-1.5 h-4 w-4 animate-spin\" />\n ) : (\n <Check className=\"mr-1.5 h-4 w-4\" />\n )}\n {isSaving ? 'Saving…' : 'Save'}\n </Button>\n </div>\n </>\n )}\n </div>\n )\n}\n","/**\n * VideoCapture\n *\n * Camera capture UI: live preview → tap to record / tap to stop → review\n * (playback, retake, or save). Shares its shape (onSave/onDiscard/onError/\n * isSaving) with VoiceNoteRecorder and PhotoCapture — see\n * MediaCaptureRecorder.tsx (the ARBI-frontend wrapper) for how the three\n * capture modes plug into the same draft/save contract.\n *\n * Deliberately a simple tap-to-start/tap-to-stop toggle rather than a\n * press-and-hold gesture — matches VoiceNoteRecorder's toggle interaction\n * and needs no extra gesture handling for a first cut of camera video.\n *\n * REUSE-FIRST: no app coupling. This component owns only the capture UI and\n * in-memory blob, never persistence — nothing is uploaded until the host's\n * `onSave` is called.\n */\n\nimport { useEffect, useRef } from 'react'\nimport { Check, Circle, Loader2, RotateCcw, Square, Trash2 } from 'lucide-react'\nimport { Button } from '../ui/button'\nimport { VideoViewer } from '../viewers/VideoViewer'\nimport { useCameraStream } from './useCameraStream'\nimport { useVideoRecorder } from './useVideoRecorder'\nimport { formatElapsed } from './format-elapsed'\n\nexport interface VideoCaptureProps {\n /** Called with the recorded clip when the user hits Save. Resolve to let\n * the host close/replace this capture UI; shows a saving spinner while\n * the promise is pending. */\n onSave: (blob: Blob, mimeType: string | null) => Promise<void> | void\n /** Called when the user discards the draft. */\n onDiscard: () => void\n /** Surfaces camera failures (e.g. denied permission) — wire this to the\n * host's own notification system. Without it, failures are silent. */\n onError?: (message: string) => void\n isSaving?: boolean\n}\n\nexport function VideoCapture({ onSave, onDiscard, onError, isSaving = false }: VideoCaptureProps) {\n // Camera audio too, not just video — a silent clip would surprise anyone\n // used to phone camera video capture.\n const camera = useCameraStream({ video: true, audio: true })\n const recorder = useVideoRecorder(camera.stream)\n const videoRef = useRef<HTMLVideoElement>(null)\n\n useEffect(() => {\n void camera.start()\n // Start the camera once on mount — see PhotoCapture's identical effect.\n // eslint-disable-next-line react-hooks/exhaustive-deps\n }, [])\n\n useEffect(() => {\n if (camera.error) onError?.(camera.error)\n // eslint-disable-next-line react-hooks/exhaustive-deps\n }, [camera.error])\n\n // Live preview binds to the camera stream while previewing/recording; once\n // stopped, the video element is replaced by VideoViewer playing the\n // recorded blob (below), so this effect only matters pre-stop.\n useEffect(() => {\n const video = videoRef.current\n if (!video || recorder.state === 'stopped') return\n video.srcObject = camera.stream\n if (camera.stream) void video.play().catch(() => {})\n }, [camera.stream, recorder.state])\n\n const handleRetake = () => {\n recorder.reset()\n }\n\n const handleSave = () => {\n if (!recorder.blob) return\n void onSave(recorder.blob, recorder.mimeType)\n }\n\n return (\n <div className=\"flex h-full flex-col items-center justify-center gap-6 p-8\">\n {recorder.state !== 'stopped' && (\n <>\n <div className=\"w-full max-w-md overflow-hidden rounded-lg bg-muted/30\">\n <video\n ref={videoRef}\n autoPlay\n muted\n playsInline\n className=\"w-full max-h-[60vh] object-contain\"\n data-testid=\"video-capture-preview\"\n />\n </div>\n {recorder.state === 'recording' && (\n <div className=\"flex items-center gap-2\" data-testid=\"video-capture-rec-indicator\">\n <span className=\"relative flex h-2 w-2\">\n <span className=\"absolute inline-flex h-full w-full animate-ping rounded-full bg-red-500 opacity-75\" />\n <span className=\"relative inline-flex h-2 w-2 rounded-full bg-red-500\" />\n </span>\n <span className=\"text-xs font-semibold uppercase tracking-wide text-red-500\">\n Rec\n </span>\n <span className=\"font-mono text-xs tabular-nums text-muted-foreground\">\n {formatElapsed(recorder.elapsedMs)}\n </span>\n </div>\n )}\n {recorder.state === 'recording' ? (\n <Button\n type=\"button\"\n size=\"lg\"\n className=\"h-16 w-16 rounded-full p-0\"\n onClick={recorder.stop}\n data-testid=\"video-capture-stop-button\"\n >\n <Square className=\"h-5 w-5 fill-current\" />\n </Button>\n ) : (\n <Button\n type=\"button\"\n size=\"lg\"\n className=\"h-16 w-16 rounded-full p-0\"\n onClick={recorder.start}\n disabled={!camera.stream}\n data-testid=\"video-capture-record-button\"\n >\n <Circle className=\"h-6 w-6 fill-current\" />\n </Button>\n )}\n <p className=\"text-sm text-muted-foreground\">\n {recorder.state === 'recording'\n ? 'Tap to stop recording'\n : camera.isStarting\n ? 'Starting camera…'\n : camera.stream\n ? 'Tap to start recording'\n : 'Waiting for camera access…'}\n </p>\n </>\n )}\n\n {recorder.state === 'stopped' && recorder.blob && (\n <>\n <div className=\"w-full max-w-md\">\n <VideoViewer blob={recorder.blob} title=\"Captured video\" />\n </div>\n <div className=\"flex items-center gap-3\">\n <Button\n type=\"button\"\n variant=\"outline\"\n onClick={onDiscard}\n disabled={isSaving}\n data-testid=\"video-capture-discard-button\"\n >\n <Trash2 className=\"mr-1.5 h-4 w-4\" />\n Discard\n </Button>\n <Button\n type=\"button\"\n variant=\"outline\"\n onClick={handleRetake}\n disabled={isSaving}\n data-testid=\"video-capture-retake-button\"\n >\n <RotateCcw className=\"mr-1.5 h-4 w-4\" />\n Record again\n </Button>\n <Button\n type=\"button\"\n onClick={handleSave}\n disabled={isSaving}\n data-testid=\"video-capture-save-button\"\n >\n {isSaving ? (\n <Loader2 className=\"mr-1.5 h-4 w-4 animate-spin\" />\n ) : (\n <Check className=\"mr-1.5 h-4 w-4\" />\n )}\n {isSaving ? 'Saving…' : 'Save'}\n </Button>\n </div>\n </>\n )}\n </div>\n )\n}\n","/**\n * Content-based audio-vs-video detection for containers that don't tell you\n * from the extension alone. WebM in particular can hold audio-only, video-only,\n * or both, and a host app bucketing purely by file extension will get an\n * audio-only recording (e.g. a voice note) wrong, since `.webm` is what\n * MediaRecorder produces either way.\n *\n * No backend involvement needed: most document APIs don't expose a\n * content-type field to check post-upload (only a file name), but loading the\n * bytes into a hidden <video> element and reading its decoded metadata does\n * the job entirely client-side — videoWidth/videoHeight report 0x0 when\n * there's no video track, even though duration/audio still work fine.\n */\nexport function hasVideoTrack(blob: Blob): Promise<boolean> {\n return new Promise((resolve) => {\n const url = URL.createObjectURL(blob)\n const video = document.createElement('video')\n video.preload = 'metadata'\n video.muted = true\n\n const cleanup = () => {\n video.removeAttribute('src')\n video.load()\n URL.revokeObjectURL(url)\n }\n\n video.onloadedmetadata = () => {\n resolve(video.videoWidth > 0 && video.videoHeight > 0)\n cleanup()\n }\n // Couldn't even decode it as a video container — treat conservatively as\n // \"no video track\" rather than leaving the caller hanging.\n video.onerror = () => {\n resolve(false)\n cleanup()\n }\n\n video.src = url\n })\n}\n"]}
1
+ {"version":3,"sources":["../src/hooks.ts","../src/chat/useArbiChat.ts","../src/chat/ChatBubble.tsx","../src/websocket/store.ts","../src/websocket/context.ts","../src/websocket/ArbiWebSocketProvider.tsx","../src/websocket/hooks.ts","../src/websocket/documentSync.ts","../src/workspaces/shell-workspaces.ts","../src/workspaces/useShellWorkspaces.ts","../src/ai/engine.ts","../src/ai/redline.ts","../src/ai/AiAnswer.tsx","../src/ai/AiActionCard.tsx","../src/ai/ArtifactCanvas.tsx","../src/ai/MessageArtifactCard.tsx","../src/ai/DocSearch.tsx","../src/documents/DocumentReview.tsx","../src/ai/SemanticSearch.tsx","../src/ai/DocQaPanel.tsx","../src/ai/CitationRenderer.tsx","../src/icons/DocIcon.tsx","../src/icons/HtmlIcon.tsx","../src/icons/TxtIcon.tsx","../src/icons/XlsIcon.tsx","../src/icons/FileIcon.tsx","../src/icons/AppleIcon.tsx","../src/icons/GoogleIcon.tsx","../src/icons/GitHubIcon.tsx","../src/icons/LinkedInIcon.tsx","../src/icons/OpenAIIcon.tsx","../src/icons/ClaudeIcon.tsx","../src/icons/GeminiIcon.tsx","../src/icons/FireworksIcon.tsx","../src/icons/ProviderIcon.tsx","../src/icons/ArbiIcon.tsx","../src/icons/ArbiBotIcon.tsx","../src/notifications/notification-types.ts","../src/notifications/activity-types.ts","../src/notifications/ActivityFeed.tsx","../src/directmessages/utils.ts","../src/directmessages/useDirectMessages.ts","../src/directmessages/DmAvatar.tsx","../src/directmessages/ConversationList.tsx","../src/directmessages/grouping.ts","../src/directmessages/DateSeparator.tsx","../src/directmessages/MessageBubble.tsx","../src/directmessages/MessageThread.tsx","../src/directmessages/DmComposer.tsx","../src/directmessages/DirectMessages.tsx","../src/imagecrop/ImageCropper.tsx","../src/imagecrop/cropImage.ts","../src/imagecrop/ImageCropModal.tsx","../src/command/CommandPalette.tsx","../src/command/commandPaletteContext.ts","../src/command/CommandPaletteProvider.tsx","../src/store.ts","../src/documents/DocumentTable.tsx","../src/documents/DocumentCardMenu.tsx","../src/documents/DocumentGallery.tsx","../src/documents/VoiceNoteRecorder.tsx","../src/documents/DraftTitleControls.tsx","../src/documents/useCameraStream.ts","../src/documents/useVideoRecorder.ts","../src/documents/capture-frame.ts","../src/documents/PhotoCapture.tsx","../src/documents/VideoCapture.tsx","../src/documents/has-video-track.ts"],"names":["useArbi","useQuery","useMutation","useQueries","useMemo","useState","useRef","useEffect","useCallback","memo","TypingIndicator","jsx","jsxs","ChatBubble","cn","Link","Trash2","CheckCheck","Check","create","createContext","useContext","isMessageType","connectWithReconnect","useQueryClient","diffWords","Loader2","AlertTriangle","Fragment","AiMarkdown","ShieldCheck","Copy","Sparkles","Card","Button","FileText","Badge","GitCompareArrows","Download","AnimatePresence","motion","ImageIcon","Search","CornerDownLeft","React","X","TagEntity","MarkdownRenderer","PassageCard","ArrowLeft","Input","Send","Tags","notify","normalizeCitationMarkup","useLayoutEffect","ReactMarkdown","createPortal","MarkMenu","FILE_TYPE_COLORS","Crown","useId","getEntityIcon","MessageCircleMore","UserCheck","PartyPopper","Gift","Gauge","Activity","Info","SquareArrowOutUpRight","FolderPlus","Pencil","FileX2","FileCheck2","UserEntity","getEntityColorStyles","AgentBadge","formatRelativeTime","MessagesSquare","ScrollArea","Textarea","emptyThread","Cropper","Slider","Dialog","DialogContent","DialogHeader","DialogTitle","DialogFooter","ArrowRight","ModuleRegistry","AllCommunityModule","DocumentEntity","AgGridReact","DropdownMenu","DropdownMenuTrigger","MoreHorizontal","DropdownMenuContent","DropdownMenuItem","SquarePen","DropdownMenuSeparator","DocumentCard","useAudioRecorder","Mic","MicWaveformIndicator","Pause","Play","Square","AudioViewer","RotateCcw","IconToggle","classifyMediaError","Camera","ImageViewer","formatElapsed","Circle","VideoViewer"],"mappings":"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","file":"index.cjs","sourcesContent":["/**\n * React Query hooks that use the Arbi instance from context.\n */\n\nimport { useMemo } from 'react'\nimport { useQuery, useQueries, useMutation } from '@tanstack/react-query'\nimport type {\n SSEStreamResult,\n SSEStreamStartData,\n ResponseOutputItemDoneEvent,\n ArtifactEvent,\n} from '@arbidocs/sdk/browser'\nimport { useArbi } from './useArbi'\nimport type { ParsedDocument } from './documents/parsed-types'\n\n// ── Query keys ──────────────────────────────────────────────────────────────\n\nexport const arbiQueryKeys = {\n workspaces: () => ['arbi', 'workspaces'] as const,\n documents: (workspaceId: string) => ['arbi', 'documents', workspaceId] as const,\n conversations: (workspaceId: string) => ['arbi', 'conversations', workspaceId] as const,\n tags: (workspaceId: string) => ['arbi', 'tags', workspaceId] as const,\n thumbnails: (docIds: string[]) => ['arbi', 'thumbnails', [...docIds].sort().join(',')] as const,\n parsedDoc: (docId: string, stage: string) => ['arbi', 'parsedDoc', docId, stage] as const,\n agents: () => ['arbi', 'agents'] as const,\n sessions: () => ['arbi', 'sessions'] as const,\n health: () => ['arbi', 'health'] as const,\n tasks: () => ['arbi', 'tasks'] as const,\n facts: (workspaceId: string) => ['arbi', 'facts', workspaceId] as const,\n configs: () => ['arbi', 'configs'] as const,\n activity: () => ['arbi', 'activity'] as const,\n projects: () => ['arbi', 'projects'] as const,\n projectUsage: (projectExtId: string, monthsBack: number) =>\n ['arbi', 'projectUsage', projectExtId, monthsBack] as const,\n projectInvoices: (projectExtId: string) => ['arbi', 'projectInvoices', projectExtId] as const,\n userUsageToday: () => ['arbi', 'userUsageToday'] as const,\n}\n\n// ── Hooks ───────────────────────────────────────────────────────────────────\n\n/** List the logged-in user's workspaces. */\nexport function useWorkspaces(options?: { enabled?: boolean }) {\n const arbi = useArbi()\n return useQuery({\n queryKey: arbiQueryKeys.workspaces(),\n queryFn: () => arbi.workspaces.list(),\n enabled: options?.enabled ?? arbi.isLoggedIn,\n })\n}\n\n/** List documents in a workspace. */\nexport function useDocuments(workspaceId: string | undefined, options?: { enabled?: boolean }) {\n const arbi = useArbi()\n return useQuery({\n queryKey: arbiQueryKeys.documents(workspaceId ?? ''),\n queryFn: () => arbi.documents.list(),\n enabled: (options?.enabled ?? true) && !!workspaceId && arbi.hasWorkspace,\n })\n}\n\n/** List conversations in a workspace. */\nexport function useConversations(workspaceId: string | undefined, options?: { enabled?: boolean }) {\n const arbi = useArbi()\n return useQuery({\n queryKey: arbiQueryKeys.conversations(workspaceId ?? ''),\n queryFn: () => arbi.conversations.list(),\n enabled: (options?.enabled ?? true) && !!workspaceId && arbi.hasWorkspace,\n })\n}\n\n/** List tags in a workspace. */\nexport function useTags(workspaceId: string | undefined, options?: { enabled?: boolean }) {\n const arbi = useArbi()\n return useQuery({\n queryKey: arbiQueryKeys.tags(workspaceId ?? ''),\n queryFn: () => arbi.tags.list(),\n enabled: (options?.enabled ?? true) && !!workspaceId && arbi.hasWorkspace,\n })\n}\n\n/**\n * Batch-fetch first-page thumbnails for a set of documents. Returns a map of\n * doc external id → `data:image/webp` URI (or `null` when no thumbnail exists).\n * Cached for a few minutes since thumbnails are effectively immutable per doc.\n */\nexport function useThumbnails(docIds: string[], options?: { enabled?: boolean }) {\n const arbi = useArbi()\n return useQuery({\n queryKey: arbiQueryKeys.thumbnails(docIds),\n queryFn: () => arbi.documents.getThumbnails(docIds),\n enabled: (options?.enabled ?? true) && docIds.length > 0 && arbi.hasWorkspace,\n staleTime: 5 * 60_000,\n })\n}\n\n/**\n * Fetch a document's parsed content (chunks grouped by page) for the review\n * viewer. `stage` defaults to `final` (fully processed); `marker`/`subchunk`\n * expose earlier pipeline stages.\n */\nexport function useParsedDocument(\n docId: string | undefined,\n stage: string = 'final',\n options?: { enabled?: boolean }\n) {\n const arbi = useArbi()\n return useQuery({\n queryKey: arbiQueryKeys.parsedDoc(docId ?? '', stage),\n queryFn: () =>\n arbi.documents.getParsedContent(docId as string, stage) as unknown as Promise<ParsedDocument>,\n enabled: (options?.enabled ?? true) && !!docId && arbi.hasWorkspace,\n })\n}\n\n/** Send a streaming query to the RAG assistant. Returns a mutation. */\nexport function useAssistantQuery() {\n const arbi = useArbi()\n\n return useMutation<\n SSEStreamResult,\n Error,\n {\n question: string\n docIds: string[]\n previousResponseId?: string | null\n model?: string\n onToken?: (content: string) => void\n onStreamStart?: (data: SSEStreamStartData) => void\n onOutputItemDone?: (data: ResponseOutputItemDoneEvent) => void\n onArtifact?: (data: ArtifactEvent) => void\n onError?: (message: string) => void\n onComplete?: () => void\n }\n >({\n mutationFn: ({ question, ...options }) => arbi.assistant.query(question, options),\n })\n}\n\n/** List agents owned by the current user. */\nexport function useAgents(options?: { enabled?: boolean }) {\n const arbi = useArbi()\n return useQuery({\n queryKey: arbiQueryKeys.agents(),\n queryFn: () => arbi.agents.list(),\n enabled: options?.enabled ?? arbi.isLoggedIn,\n })\n}\n\n/** Delete agents. Returns a mutation. */\nexport function useDeleteAgents() {\n const arbi = useArbi()\n return useMutation<unknown, Error, { agentExtIds: string[] }>({\n mutationFn: ({ agentExtIds }) => arbi.agents.delete(agentExtIds),\n })\n}\n\n/** List active sessions. */\nexport function useSessions(options?: { enabled?: boolean }) {\n const arbi = useArbi()\n return useQuery({\n queryKey: arbiQueryKeys.sessions(),\n queryFn: () => arbi.sessions.list(),\n enabled: options?.enabled ?? arbi.isLoggedIn,\n })\n}\n\n/** Authorize a delegated session (generates claim code). Returns a mutation. */\n\n/** Check backend health. */\nexport function useHealth(options?: { enabled?: boolean }) {\n const arbi = useArbi()\n return useQuery({\n queryKey: arbiQueryKeys.health(),\n queryFn: () => arbi.health.check(),\n enabled: options?.enabled,\n })\n}\n\n// ── Scheduled tasks ──────────────────────────────────────────────────────────\n\n/** List the caller's scheduled agent tasks. */\nexport function useTasks(options?: { enabled?: boolean }) {\n const arbi = useArbi()\n return useQuery({\n queryKey: arbiQueryKeys.tasks(),\n queryFn: () => arbi.tasks.list(),\n enabled: options?.enabled ?? arbi.isLoggedIn,\n })\n}\n\n// ── Workspace notes ──────────────────────────────────────────────────────────\n\n/** List the open workspace's facts. */\nexport function useFacts(\n workspaceId: string | undefined,\n options?: { enabled?: boolean; pinnedOnly?: boolean }\n) {\n const arbi = useArbi()\n return useQuery({\n queryKey: arbiQueryKeys.facts(workspaceId ?? ''),\n queryFn: () => arbi.facts.list({ pinnedOnly: options?.pinnedOnly }),\n enabled: (options?.enabled ?? true) && !!workspaceId && arbi.hasWorkspace,\n })\n}\n\n// ── Behaviour-template configs ───────────────────────────────────────────────\n\n/** List the caller's saved agent configurations (behaviour templates). */\nexport function useConfigs(options?: { enabled?: boolean }) {\n const arbi = useArbi()\n return useQuery({\n queryKey: arbiQueryKeys.configs(),\n queryFn: () => arbi.agentConfig.list(),\n enabled: options?.enabled ?? arbi.isLoggedIn,\n })\n}\n\n// ── Activity feed ─────────────────────────────────────────────────────────────\n\n/**\n * List the caller's durable activity feed, newest first.\n *\n * Activity entries are backend-originated, to-self log lines that are always\n * read — they are deliberately kept out of the normal notifications/DM feed and\n * never affect the unread badge, so this is a separate, opt-in query.\n */\nexport function useActivity(options?: { enabled?: boolean; limit?: number; offset?: number }) {\n const arbi = useArbi()\n return useQuery({\n queryKey: arbiQueryKeys.activity(),\n queryFn: () => arbi.dm.listActivity({ limit: options?.limit, offset: options?.offset }),\n enabled: options?.enabled ?? arbi.isLoggedIn,\n })\n}\n\n// ── Projects, usage & spend ───────────────────────────────────────────────────\n\n/** List the logged-in user's projects (billing accounts). */\nexport function useProjects(options?: { enabled?: boolean }) {\n const arbi = useArbi()\n return useQuery({\n queryKey: arbiQueryKeys.projects(),\n queryFn: () => arbi.projects.list(),\n enabled: options?.enabled ?? arbi.isLoggedIn,\n })\n}\n\n/**\n * AI usage + spend breakdown for a project's billing period. `monthsBack`\n * selects the period (0 = current, 1 = previous month, …).\n */\nexport function useProjectUsage(\n projectExtId: string | undefined,\n monthsBack: number = 0,\n options?: { enabled?: boolean }\n) {\n const arbi = useArbi()\n return useQuery({\n queryKey: arbiQueryKeys.projectUsage(projectExtId ?? '', monthsBack),\n queryFn: () => arbi.projects.usage(projectExtId as string, monthsBack),\n enabled: (options?.enabled ?? true) && !!projectExtId && arbi.isLoggedIn,\n })\n}\n\n/** One day of aggregated usage across projects (for a spend/token trend). */\nexport interface AggregatedDailyUsage {\n date: string\n spend: number\n totalTokens: number\n apiRequests: number\n}\n\n/** One model group's aggregated usage across projects (for a breakdown). */\nexport interface AggregatedModelGroupUsage {\n model: string\n spend: number\n totalTokens: number\n promptTokens: number\n completionTokens: number\n successfulRequests: number\n}\n\n/** Aggregated AI usage + spend across several projects. */\nexport interface ProjectsUsageAggregate {\n /** Summed spend across the projects, in USD (the metered currency). */\n totalSpend: number\n /** Summed token count across the projects. */\n totalTokens: number\n /** Summed API request count across the projects. */\n totalRequests: number\n /** Per-day totals merged across every project, oldest first. */\n daily: AggregatedDailyUsage[]\n /** Per-model-group totals merged across every project, biggest spend first. */\n modelGroups: AggregatedModelGroupUsage[]\n /** True while any per-project query is still loading. */\n isLoading: boolean\n /** True if any per-project query errored. */\n isError: boolean\n}\n\n/**\n * Firm-wide AI usage + spend: aggregates {@link useProjectUsage} across several\n * projects (e.g. all of a firm's matters) in parallel and merges the real totals,\n * the daily trend, and the per-model breakdown. Shares the per-project query\n * cache, so it costs nothing extra where a project's usage is already loaded.\n * Numbers are genuine — zero projects (or zero billed work) yields zero totals;\n * callers render that honestly.\n */\nexport function useProjectsUsage(\n projectExtIds: string[],\n monthsBack: number = 0,\n options?: { enabled?: boolean }\n): ProjectsUsageAggregate {\n const arbi = useArbi()\n const enabled = (options?.enabled ?? true) && arbi.isLoggedIn\n const results = useQueries({\n queries: projectExtIds.map((id) => ({\n queryKey: arbiQueryKeys.projectUsage(id, monthsBack),\n queryFn: () => arbi.projects.usage(id, monthsBack),\n enabled: enabled && !!id,\n })),\n })\n\n // Recompute only when a query's data actually changes (not on every parent\n // render — the dashboard re-renders often while a digest streams).\n const signature = results.map((r) => `${r.status}:${r.dataUpdatedAt ?? 0}`).join('|')\n\n return useMemo(() => {\n const dailyMap = new Map<string, AggregatedDailyUsage>()\n const modelMap = new Map<string, AggregatedModelGroupUsage>()\n let totalSpend = 0\n let totalTokens = 0\n let totalRequests = 0\n\n for (const r of results) {\n const d = r.data\n if (!d) continue\n totalSpend += d.total_spend ?? 0\n totalTokens += d.total_tokens ?? 0\n totalRequests += d.total_requests ?? 0\n\n for (const day of d.daily ?? []) {\n const cur = dailyMap.get(day.date) ?? {\n date: day.date,\n spend: 0,\n totalTokens: 0,\n apiRequests: 0,\n }\n cur.spend += day.spend ?? 0\n cur.totalTokens += day.total_tokens ?? 0\n cur.apiRequests += day.api_requests ?? 0\n dailyMap.set(day.date, cur)\n }\n\n for (const [model, mg] of Object.entries(d.model_groups ?? {})) {\n const cur = modelMap.get(model) ?? {\n model,\n spend: 0,\n totalTokens: 0,\n promptTokens: 0,\n completionTokens: 0,\n successfulRequests: 0,\n }\n cur.spend += mg.spend ?? 0\n cur.totalTokens += mg.total_tokens ?? 0\n cur.promptTokens += mg.prompt_tokens ?? 0\n cur.completionTokens += mg.completion_tokens ?? 0\n cur.successfulRequests += mg.successful_requests ?? 0\n modelMap.set(model, cur)\n }\n }\n\n return {\n totalSpend,\n totalTokens,\n totalRequests,\n daily: [...dailyMap.values()].sort((a, b) => a.date.localeCompare(b.date)),\n modelGroups: [...modelMap.values()].sort(\n (a, b) => b.spend - a.spend || b.totalTokens - a.totalTokens\n ),\n isLoading: results.some((r) => r.isLoading),\n isError: results.some((r) => r.isError),\n }\n }, [signature])\n}\n\n/** List the Stripe invoices for a project's subscription. */\nexport function useProjectInvoices(\n projectExtId: string | undefined,\n options?: { enabled?: boolean }\n) {\n const arbi = useArbi()\n return useQuery({\n queryKey: arbiQueryKeys.projectInvoices(projectExtId ?? ''),\n queryFn: () => arbi.projects.invoices(projectExtId as string),\n enabled: (options?.enabled ?? true) && !!projectExtId && arbi.isLoggedIn,\n })\n}\n\n/** Today's deployment-wide credit spend for the current user. */\nexport function useUserUsageToday(options?: { enabled?: boolean }) {\n const arbi = useArbi()\n return useQuery({\n queryKey: arbiQueryKeys.userUsageToday(),\n queryFn: () => arbi.user.usageToday(),\n enabled: options?.enabled ?? arbi.isLoggedIn,\n })\n}\n","/**\n * `useArbiChat` — the chat controller behind a full-page (or docked) assistant.\n *\n * It owns what a chat surface needs and no markup: conversation threads with auto-titles, the\n * message list (the streaming answer included), the documents the questions are grounded on\n * (select, upload), retry after a failure. It binds the SDK; the UI is `@arbidocs/blocks/chat`'s\n * `ChatPage`, whose `chat` prop is exactly this hook's return value:\n *\n * ```tsx\n * const chat = useArbiChat({ workspaceId })\n * <ChatPage chat={chat} aside={<WorkflowLauncher … />} />\n * ```\n *\n * Threads live in memory for the lifetime of the hook (they are reset when `workspaceId`\n * changes); follow-ups chain through the previous response id, so each thread keeps its context.\n */\nimport { useCallback, useEffect, useMemo, useRef, useState } from 'react'\nimport { useArbi } from '../useArbi'\nimport { useAssistantQuery, useDocuments } from '../hooks'\n\nexport type ArbiChatRole = 'user' | 'assistant'\nexport type ArbiChatMessageStatus = 'streaming' | 'complete' | 'error'\n\nexport interface ArbiChatMessage {\n id: string\n role: ArbiChatRole\n /** Markdown for an assistant message, plain text for a user message. */\n content: string\n status: ArbiChatMessageStatus\n /** Why an assistant message failed. */\n error?: string\n /** Agent steps (tool calls, reasoning) the answer took. */\n stepCount?: number\n}\n\nexport interface ArbiChatThread {\n id: string\n /** Auto-titled from the first question; empty until there is one. */\n title: string\n}\n\nexport interface ArbiChatDocument {\n id: string\n name: string\n isSelected: boolean\n}\n\nexport interface UseArbiChatOptions {\n /** The workspace to chat in. Threads and the document selection reset when it changes. */\n workspaceId?: string\n /** Assistant configuration or model id passed to every query. */\n model?: string\n /** Longest auto-title in characters. Default 48. */\n titleLength?: number\n}\n\nexport interface ArbiChat {\n threads: ArbiChatThread[]\n activeThreadId: string\n messages: ArbiChatMessage[]\n /** An answer is streaming. */\n isRunning: boolean\n /** The last turn failed (the message list also carries the failed message). */\n error: string | null\n documents: ArbiChatDocument[]\n isLoadingDocuments: boolean\n isUploading: boolean\n uploadError: string | null\n send: (text: string) => Promise<void>\n /** Re-ask the question whose answer failed. */\n retry: () => Promise<void>\n selectThread: (id: string) => void\n newThread: () => void\n deleteThread: (id: string) => void\n toggleDocument: (id: string) => void\n selectAllDocuments: () => void\n upload: (files: File[]) => Promise<void>\n}\n\ninterface ThreadState extends ArbiChatThread {\n messages: ArbiChatMessage[]\n responseId: string | null\n}\n\nlet counter = 0\nconst nextId = (prefix: string) =>\n `${prefix}-${Date.now().toString(36)}-${(counter++).toString(36)}`\n\nconst emptyThread = (): ThreadState => ({\n id: nextId('thread'),\n title: '',\n messages: [],\n responseId: null,\n})\n\n/** First words of a question as a title: whole words, no trailing punctuation, ellipsis when cut. */\nexport function titleFromQuestion(question: string, maxLength = 48): string {\n const flat = question.replace(/\\s+/g, ' ').trim()\n if (flat.length <= maxLength) return flat\n const cut = flat.slice(0, maxLength)\n const lastSpace = cut.lastIndexOf(' ')\n const words = lastSpace > maxLength / 2 ? cut.slice(0, lastSpace) : cut\n return `${words.replace(/[\\s,;:.\\-–—]+$/, '')}…`\n}\n\nconst messageOf = (e: unknown, fallback: string) => (e instanceof Error ? e.message : fallback)\n\nexport function useArbiChat(options: UseArbiChatOptions = {}): ArbiChat {\n const { workspaceId, model, titleLength = 48 } = options\n const arbi = useArbi()\n const { data: docs = [], isLoading: isLoadingDocuments, refetch } = useDocuments(workspaceId)\n const query = useAssistantQuery()\n const { mutateAsync } = query\n\n const [threads, setThreads] = useState<ThreadState[]>(() => [emptyThread()])\n const [activeId, setActiveId] = useState(() => threads[0].id)\n const [deselected, setDeselected] = useState<ReadonlySet<string>>(new Set())\n const [isRunning, setIsRunning] = useState(false)\n const [isUploading, setIsUploading] = useState(false)\n const [uploadError, setUploadError] = useState<string | null>(null)\n\n // Everything is scoped to one workspace: start clean when it changes.\n const scopeRef = useRef(workspaceId)\n useEffect(() => {\n if (scopeRef.current === workspaceId) return\n scopeRef.current = workspaceId\n const fresh = emptyThread()\n setThreads([fresh])\n setActiveId(fresh.id)\n setDeselected(new Set())\n setUploadError(null)\n }, [workspaceId])\n\n const active = threads.find((t) => t.id === activeId) ?? threads[0]\n\n const selectedIds = useMemo(\n () => docs.map((d) => d.external_id).filter((id): id is string => !!id && !deselected.has(id)),\n [docs, deselected]\n )\n const documents = useMemo<ArbiChatDocument[]>(\n () =>\n docs\n .filter((d): d is typeof d & { external_id: string } => !!d.external_id)\n .map((d) => ({\n id: d.external_id,\n name: d.file_name ?? d.external_id,\n isSelected: !deselected.has(d.external_id),\n })),\n [docs, deselected]\n )\n\n const patchThread = useCallback(\n (id: string, patch: (t: ThreadState) => ThreadState) =>\n setThreads((all) => all.map((t) => (t.id === id ? patch(t) : t))),\n []\n )\n const patchMessage = useCallback(\n (threadId: string, messageId: string, patch: Partial<ArbiChatMessage>) =>\n patchThread(threadId, (t) => ({\n ...t,\n messages: t.messages.map((m) => (m.id === messageId ? { ...m, ...patch } : m)),\n })),\n [patchThread]\n )\n\n const ask = useCallback(\n async (thread: ThreadState, text: string) => {\n const userMessage: ArbiChatMessage = {\n id: nextId('msg'),\n role: 'user',\n content: text,\n status: 'complete',\n }\n const answer: ArbiChatMessage = {\n id: nextId('msg'),\n role: 'assistant',\n content: '',\n status: 'streaming',\n }\n patchThread(thread.id, (t) => ({\n ...t,\n title: t.title || titleFromQuestion(text, titleLength),\n messages: [...t.messages, userMessage, answer],\n }))\n setIsRunning(true)\n let buffer = ''\n let steps = 0\n let streamError: string | null = null\n try {\n const result = await mutateAsync({\n question: text,\n docIds: selectedIds,\n previousResponseId: thread.responseId,\n model,\n onToken: (token) => {\n buffer += token\n patchMessage(thread.id, answer.id, { content: buffer })\n },\n onOutputItemDone: (ev) => {\n const type = (ev.item as { type?: string }).type\n if (type === 'function_call' || type === 'reasoning') {\n steps += 1\n patchMessage(thread.id, answer.id, { stepCount: steps })\n }\n },\n onError: (message) => {\n streamError = message\n },\n })\n const finalText = result.text || buffer\n const failure = streamError || result.errors[0] || null\n if (failure && !finalText) {\n patchMessage(thread.id, answer.id, { status: 'error', error: failure })\n } else {\n patchMessage(thread.id, answer.id, {\n status: 'complete',\n content: finalText,\n stepCount: result.agentSteps.length || steps || undefined,\n })\n patchThread(thread.id, (t) => ({\n ...t,\n responseId: result.assistantMessageExtId ?? t.responseId,\n }))\n }\n } catch (e) {\n patchMessage(thread.id, answer.id, {\n status: 'error',\n error: messageOf(e, 'The assistant request failed.'),\n })\n } finally {\n setIsRunning(false)\n }\n },\n [mutateAsync, patchMessage, patchThread, selectedIds, model, titleLength]\n )\n\n const send = useCallback(\n async (text: string) => {\n const trimmed = text.trim()\n if (!trimmed || isRunning) return\n await ask(active, trimmed)\n },\n [active, ask, isRunning]\n )\n\n const lastMessage = active.messages[active.messages.length - 1]\n const error = lastMessage?.status === 'error' ? (lastMessage.error ?? null) : null\n\n const retry = useCallback(async () => {\n if (isRunning) return\n const messages = active.messages\n const failed = messages[messages.length - 1]\n const question = messages[messages.length - 2]\n if (failed?.status !== 'error' || question?.role !== 'user') return\n const trimmed: ThreadState = { ...active, messages: messages.slice(0, -2) }\n patchThread(active.id, () => trimmed)\n await ask(trimmed, question.content)\n }, [active, ask, isRunning, patchThread])\n\n const newThread = useCallback(() => {\n if (active.messages.length === 0) return\n const fresh = emptyThread()\n setThreads((all) => [fresh, ...all])\n setActiveId(fresh.id)\n }, [active.messages.length])\n\n const deleteThread = useCallback(\n (id: string) => {\n const rest = threads.filter((t) => t.id !== id)\n const next = rest.length > 0 ? rest : [emptyThread()]\n setThreads(next)\n if (id === activeId) setActiveId(next[0].id)\n },\n [threads, activeId]\n )\n\n const toggleDocument = useCallback((id: string) => {\n setDeselected((prev) => {\n const next = new Set(prev)\n if (next.has(id)) next.delete(id)\n else next.add(id)\n return next\n })\n }, [])\n const selectAllDocuments = useCallback(() => setDeselected(new Set()), [])\n\n const upload = useCallback(\n async (files: File[]) => {\n if (files.length === 0) return\n setIsUploading(true)\n setUploadError(null)\n try {\n for (const file of files) await arbi.documents.uploadFile(file, file.name)\n // New documents are not in `deselected`, so they join the selection by default.\n await refetch()\n } catch (e) {\n setUploadError(messageOf(e, 'The upload failed.'))\n } finally {\n setIsUploading(false)\n }\n },\n [arbi, refetch]\n )\n\n return {\n threads: threads.map(({ id, title }) => ({ id, title })),\n activeThreadId: active.id,\n messages: active.messages,\n isRunning,\n error,\n documents,\n isLoadingDocuments,\n isUploading,\n uploadError,\n send,\n retry,\n selectThread: setActiveId,\n newThread,\n deleteThread,\n toggleDocument,\n selectAllDocuments,\n upload,\n }\n}\n","/**\n * Chat Bubble Component\n * iMessage / WhatsApp-style message bubble with read receipts and\n * consecutive-message grouping.\n *\n * Promoted from the ARBI app. To keep `@arbidocs/react` light (peers react /\n * react-dom only), the two host-owned concerns — rendering the message body\n * (the app's heavy markdown renderer) and formatting the timestamp — are\n * injected via the optional `renderMessage` / `formatTimestamp` props. Both\n * default to plain text so the component works standalone; the ARBI app shim\n * wires in `<MarkdownRenderer>` and `formatFriendlyDate` for identical output.\n */\n\nimport { memo, useState, type ReactNode } from 'react'\nimport { Trash2, Check, CheckCheck, Link } from 'lucide-react'\nimport { cn } from '../lib/utils'\n\n/** Animated typing indicator (three bouncing dots) */\nexport const TypingIndicator = memo(function TypingIndicator() {\n return (\n <div className=\"flex w-full justify-start mb-2\" data-testid=\"dm-typing-indicator\">\n <div className=\"bg-card border border-primary rounded-2xl rounded-bl-md px-4 py-2.5\">\n <div className=\"flex gap-1 items-center\">\n <span className=\"w-1.5 h-1.5 rounded-full bg-muted-foreground animate-bounce [animation-delay:0ms]\" />\n <span className=\"w-1.5 h-1.5 rounded-full bg-muted-foreground animate-bounce [animation-delay:150ms]\" />\n <span className=\"w-1.5 h-1.5 rounded-full bg-muted-foreground animate-bounce [animation-delay:300ms]\" />\n </div>\n </div>\n </div>\n )\n})\n\nexport interface ChatBubbleProps {\n message: string\n timestamp: string\n isSent: boolean\n deleted?: boolean\n read?: boolean\n onDelete?: () => void\n /**\n * Copy a shareable deep link to this exact message. Optional — the host\n * builds the URL (it knows the workspace/deployment domain, the light\n * package doesn't), this just renders the affordance and calls back.\n */\n onCopyLink?: () => void\n /** Stable DOM anchor for scroll-to-message (a notification deep link, a\n * \"jump to this message\" action). Typically the message's external id. */\n id?: string\n /** Brief highlight flash — set true right after scrolling into view. */\n highlighted?: boolean\n /** Last bubble in a same-sender run; shows the timestamp and read receipt. */\n isLastOfRun?: boolean\n /**\n * Who sent it. Rendered in the meta row on the last bubble of a run, so a\n * thread that needs attribution (a group, or a rail-less list where the peer\n * isn't in a header) gets it without a row per message.\n */\n senderName?: string\n /** Per-slot brand overrides, so a consumer pins its accent in one place. */\n classNames?: {\n /** The current user's own bubble. */\n ownBubble?: string\n /** The peer's bubble. */\n peerBubble?: string\n }\n /**\n * Render the message body. Injected by the host so the light package doesn't\n * depend on the app's markdown renderer. Defaults to plain text.\n */\n renderMessage?: (message: string) => ReactNode\n /**\n * Format the timestamp shown on the last bubble of a run. Defaults to the\n * raw string.\n */\n formatTimestamp?: (timestamp: string) => string\n /** Marks the message row, including the deleted tombstone. */\n 'data-testid'?: string\n}\n\nexport const ChatBubble = memo(function ChatBubble({\n message,\n timestamp,\n isSent,\n deleted,\n read,\n onDelete,\n onCopyLink,\n id,\n highlighted,\n isLastOfRun = true,\n senderName,\n classNames,\n renderMessage = (m) => m,\n formatTimestamp = (t) => t,\n 'data-testid': testId,\n}: ChatBubbleProps) {\n const [isHovered, setIsHovered] = useState(false)\n const [isFocused, setIsFocused] = useState(false)\n const showActions = isHovered || isFocused\n\n // No \"edited\" indicator: `updated_at` is also bumped by read-state\n // patches, so we can't tell a real content edit from a recipient\n // marking the message as read. The created_at timestamp is the only\n // honest signal we can show here.\n\n if (deleted) {\n return (\n <div\n id={id}\n data-testid={testId}\n className={`flex w-full ${isSent ? 'justify-end' : 'justify-start'} mb-2`}\n >\n <div className=\"text-sm text-muted-foreground italic px-3 py-1\">Message deleted</div>\n </div>\n )\n }\n\n // WhatsApp-style radius: round corners; the side facing the sender gets a\n // smaller corner on the *last* bubble of a run to read as a chat tail.\n const bubbleRadius = cn(\n 'rounded-2xl',\n isSent && isLastOfRun && 'rounded-br-sm',\n !isSent && isLastOfRun && 'rounded-bl-sm'\n )\n\n // Own messages sit on a soft brand tint rather than full `primary`: a\n // saturated block per message shouts on a long thread, and a light surface\n // means markdown needs no colour inversion.\n //\n // The tint is `ai-accent-soft`, NOT `accent`. Plenty of themes set `accent`\n // equal to `muted` and a hair off `background` — ARBI's differ by 3% — so an\n // accent bubble there is invisible against the thread. `ai-accent-soft` is\n // part of the AI-accent contract every consuming app defines explicitly, so\n // it is a tint by construction.\n const bubbleSurface = isSent\n ? cn('bg-ai-accent-soft text-foreground chat-bubble-sent', classNames?.ownBubble)\n : cn('border border-border bg-card text-card-foreground', classNames?.peerBubble)\n\n // Same treatment useScrollBehavior gives a URL-driven deep link to a\n // conversation message: a brief tinted flash, not a persistent style.\n const highlightClass = highlighted && 'ring-2 ring-blue-400 dark:ring-blue-600'\n\n const copyLinkButton = onCopyLink && (\n <button\n onClick={onCopyLink}\n onFocus={() => setIsFocused(true)}\n onBlur={() => setIsFocused(false)}\n className={cn(\n 'self-end p-1 transition-opacity focus:outline-none focus-visible:ring-1 focus-visible:ring-ring rounded',\n showActions ? 'opacity-100 text-foreground' : 'opacity-0 text-muted-foreground'\n )}\n aria-label=\"Copy link to this message\"\n >\n <Link className=\"w-3.5 h-3.5\" />\n </button>\n )\n\n return (\n <div\n id={id}\n data-testid={testId}\n className={cn(\n 'flex w-full items-end',\n isLastOfRun ? 'mb-2' : 'mb-0.5',\n isSent ? 'justify-end' : 'justify-start'\n )}\n onMouseEnter={() => setIsHovered(true)}\n onMouseLeave={() => setIsHovered(false)}\n >\n {/* Sent messages: copy-link + delete on the left */}\n {isSent && (copyLinkButton || onDelete) && (\n <div className=\"flex items-center gap-0.5 mr-1\">\n {copyLinkButton}\n {onDelete && (\n <button\n onClick={onDelete}\n onFocus={() => setIsFocused(true)}\n onBlur={() => setIsFocused(false)}\n className={cn(\n 'self-end p-1 transition-opacity focus:outline-none focus-visible:ring-1 focus-visible:ring-ring rounded',\n showActions ? 'opacity-100 text-destructive' : 'opacity-0 text-muted-foreground'\n )}\n aria-label=\"Delete message\"\n >\n <Trash2 className=\"w-3.5 h-3.5\" />\n </button>\n )}\n </div>\n )}\n\n <div className=\"flex flex-col max-w-[80%] md:max-w-[60%]\">\n <div\n className={cn(\n 'px-3.5 py-2 break-words shadow-sm transition-shadow',\n bubbleRadius,\n bubbleSurface,\n highlightClass\n )}\n >\n <div className=\"text-sm [&_.markdown-content]:space-y-1.5 [&_pre]:max-w-full [&_pre]:overflow-x-auto\">\n {renderMessage(message)}\n </div>\n\n {/* Sender + timestamp + read receipt, only on the last bubble of the\n run — a meta row per message is noise in a 1:1 thread. */}\n {isLastOfRun && (\n <div\n className={cn(\n 'flex items-center gap-1.5 mt-0.5',\n isSent ? 'justify-end' : 'justify-start'\n )}\n >\n {senderName && (\n <span className=\"text-xs font-medium leading-none opacity-90\">{senderName}</span>\n )}\n <span className=\"text-xs leading-none opacity-70\">{formatTimestamp(timestamp)}</span>\n {isSent &&\n (read ? (\n <CheckCheck className=\"w-3.5 h-3.5 flex-shrink-0 opacity-80\" />\n ) : (\n <Check className=\"w-3.5 h-3.5 flex-shrink-0 opacity-60\" />\n ))}\n </div>\n )}\n </div>\n </div>\n\n {/* Received messages: delete + copy-link on the right */}\n {!isSent && (onDelete || copyLinkButton) && (\n <div className=\"flex items-center gap-0.5 ml-1\">\n {onDelete && (\n <button\n onClick={onDelete}\n onFocus={() => setIsFocused(true)}\n onBlur={() => setIsFocused(false)}\n className={cn(\n 'self-end p-1 transition-opacity focus:outline-none focus-visible:ring-1 focus-visible:ring-ring rounded',\n showActions ? 'opacity-100 text-destructive' : 'opacity-0 text-muted-foreground'\n )}\n aria-label=\"Delete message\"\n >\n <Trash2 className=\"w-3.5 h-3.5\" />\n </button>\n )}\n {copyLinkButton}\n </div>\n )}\n </div>\n )\n})\n","/**\n * Canonical WebSocket state, shared across apps.\n *\n * This mirrors the ARBI app's `webSocketSlice` but lives in the SDK so every\n * consumer (the ARBI frontend, clarum, any firm app) gets the *same* rich\n * real-time state from one implementation. The provider feeds it; components\n * read it with the selector hooks in `./hooks`.\n */\n\nimport { create } from 'zustand'\nimport type { WsTaskUpdateMessage, WsPresenceUpdateMessage } from '@arbidocs/client'\n\nexport type ArbiWsStatus = 'disconnected' | 'connecting' | 'connected' | 'reconnecting'\n\nexport interface ArbiWsState {\n /** Live connection status of the shared socket. */\n status: ArbiWsStatus\n /** Latest processing status per document id (the `task_update` stream). */\n tasks: Record<string, WsTaskUpdateMessage>\n /** The most recent `task_update` — a convenient single-value change trigger. */\n lastTaskUpdate: WsTaskUpdateMessage | null\n /** Online status keyed by user id (the `presence_update` stream). */\n presence: Record<string, string>\n setStatus: (status: ArbiWsStatus) => void\n applyTaskUpdate: (msg: WsTaskUpdateMessage) => void\n applyPresence: (msg: WsPresenceUpdateMessage) => void\n reset: () => void\n}\n\nexport const useArbiWsStore = create<ArbiWsState>((set) => ({\n status: 'disconnected',\n tasks: {},\n lastTaskUpdate: null,\n presence: {},\n setStatus: (status) => set({ status }),\n applyTaskUpdate: (msg) =>\n set((s) => ({ tasks: { ...s.tasks, [msg.doc_ext_id]: msg }, lastTaskUpdate: msg })),\n applyPresence: (msg) => set((s) => ({ presence: { ...s.presence, [msg.user_id]: msg.status } })),\n reset: () => set({ status: 'disconnected', tasks: {}, lastTaskUpdate: null, presence: {} }),\n}))\n","/**\n * Context for the shared WebSocket — the subscribe registry the provider fills\n * and the hooks read. Kept separate from the provider component so both can be\n * imported without tripping react-refresh's component-only-export rule.\n */\n\nimport { createContext, useContext } from 'react'\nimport type { WebSocketServerMessage } from '@arbidocs/client'\n\nexport type ArbiWsSubscriber = (msg: WebSocketServerMessage) => void\n\nexport interface ArbiWsContextValue {\n subscribe: (fn: ArbiWsSubscriber) => () => void\n}\n\nexport const ArbiWsContext = createContext<ArbiWsContextValue | null>(null)\n\nexport function useArbiWsContext(): ArbiWsContextValue {\n const ctx = useContext(ArbiWsContext)\n if (!ctx) {\n throw new Error('useArbiWebSocket hooks must be used within an <ArbiWebSocketProvider>')\n }\n return ctx\n}\n","/**\n * ArbiWebSocketProvider — one shared, reconnecting WebSocket for the whole app.\n *\n * Opens a single authenticated socket (via the SDK transport's\n * `connectWithReconnect`, which handles auth, backoff, and live-token refresh),\n * feeds the canonical WS store, and fans every typed message out to subscribers\n * registered by the `useArbiWebSocket` / `useArbiWsMessage` hooks.\n *\n * Mount it inside an `<ArbiProvider>` (it reads the Arbi instance for the base\n * URL + live access token). Gate it with `enabled` so it connects only once the\n * app is authenticated against a live backend.\n */\n\nimport { useEffect, useMemo, useRef, type ReactNode } from 'react'\nimport { connectWithReconnect, type ReconnectableWsConnection } from '@arbidocs/sdk/browser'\nimport {\n isMessageType,\n type WebSocketServerMessage,\n type WsTaskUpdateMessage,\n type WsPresenceUpdateMessage,\n} from '@arbidocs/client'\nimport { useArbi } from '../useArbi'\nimport { useArbiWsStore } from './store'\nimport { ArbiWsContext, type ArbiWsContextValue, type ArbiWsSubscriber } from './context'\n\nexport interface ArbiWebSocketProviderProps {\n /**\n * Open the socket only when the app is authenticated against a live backend.\n * Defaults to `true`; pass the connection status so demo/logged-out sessions\n * don't try to connect.\n */\n enabled?: boolean\n children: ReactNode\n}\n\nexport function ArbiWebSocketProvider({ enabled = true, children }: ArbiWebSocketProviderProps) {\n const arbi = useArbi()\n const subscribersRef = useRef<Set<ArbiWsSubscriber>>(new Set())\n const setStatus = useArbiWsStore((s) => s.setStatus)\n const applyTaskUpdate = useArbiWsStore((s) => s.applyTaskUpdate)\n const applyPresence = useArbiWsStore((s) => s.applyPresence)\n const reset = useArbiWsStore((s) => s.reset)\n\n // Stable subscribe API — the subscriber set lives in a ref, so registering a\n // handler never re-opens the socket.\n const context = useMemo<ArbiWsContextValue>(\n () => ({\n subscribe: (fn) => {\n subscribersRef.current.add(fn)\n return () => {\n subscribersRef.current.delete(fn)\n }\n },\n }),\n []\n )\n\n useEffect(() => {\n if (!enabled) {\n reset()\n return\n }\n\n let conn: ReconnectableWsConnection | null = null\n let cancelled = false\n\n const onMessage = (msg: WebSocketServerMessage) => {\n // Canonical store updates (the same shape the ARBI app maintains).\n if (isMessageType<WsTaskUpdateMessage>(msg, 'task_update')) applyTaskUpdate(msg)\n else if (isMessageType<WsPresenceUpdateMessage>(msg, 'presence_update')) applyPresence(msg)\n\n // Fan out to app subscribers. A throwing subscriber must not kill the stream.\n for (const fn of subscribersRef.current) {\n try {\n fn(msg)\n } catch {\n /* swallow — one bad handler can't break the socket */\n }\n }\n }\n\n const start = async () => {\n const info = arbi.getConnectionInfo()\n if (!info) return // not authenticated yet; the effect re-runs when `enabled` flips\n setStatus('connecting')\n try {\n const c = await connectWithReconnect({\n baseUrl: info.baseUrl,\n accessToken: info.accessToken,\n // Resolve the freshest token on every (re)connect so rotation is picked up.\n getAccessToken: () => arbi.getConnectionInfo()?.accessToken ?? null,\n onMessage,\n onReconnecting: () => setStatus('reconnecting'),\n onReconnected: () => setStatus('connected'),\n onClose: () => {\n if (!cancelled) setStatus('reconnecting')\n },\n })\n if (cancelled) {\n c.close()\n return\n }\n conn = c\n setStatus('connected')\n } catch {\n setStatus('disconnected')\n }\n }\n void start()\n\n return () => {\n cancelled = true\n conn?.close()\n reset()\n }\n }, [enabled, arbi, setStatus, applyTaskUpdate, applyPresence, reset])\n\n return <ArbiWsContext.Provider value={context}>{children}</ArbiWsContext.Provider>\n}\n","/**\n * Typed subscription + selector hooks for the shared WebSocket.\n *\n * All message typing flows from the OpenAPI-derived `WebSocketServerMessage`\n * union — handlers are narrowed by the discriminant `type`, exactly like the\n * rest of the SDK.\n */\n\nimport { useEffect, useRef } from 'react'\nimport { isMessageType, type WebSocketServerMessage } from '@arbidocs/client'\nimport { useArbiWsContext } from './context'\nimport { useArbiWsStore, type ArbiWsStatus } from './store'\n\n/**\n * Subscribe to every server message. The handler is kept in a ref, so passing a\n * new inline function each render does not resubscribe.\n */\nexport function useArbiWebSocket(onMessage: (msg: WebSocketServerMessage) => void): void {\n const { subscribe } = useArbiWsContext()\n const handlerRef = useRef(onMessage)\n handlerRef.current = onMessage\n useEffect(() => subscribe((msg) => handlerRef.current(msg)), [subscribe])\n}\n\n/**\n * Subscribe to a single message type, fully narrowed to that variant.\n *\n * @example\n * useArbiWsMessage<WsBatchCompleteMessage>('batch_complete', (msg) => {\n * // msg.batch_type, msg.doc_ext_ids are typed\n * })\n */\nexport function useArbiWsMessage<T extends WebSocketServerMessage>(\n type: T['type'],\n handler: (msg: T) => void\n): void {\n const { subscribe } = useArbiWsContext()\n const handlerRef = useRef(handler)\n handlerRef.current = handler\n useEffect(\n () =>\n subscribe((msg) => {\n if (isMessageType<T>(msg, type)) handlerRef.current(msg)\n }),\n [subscribe, type]\n )\n}\n\n/** Live connection status of the shared socket. */\nexport function useArbiWsStatus(): ArbiWsStatus {\n return useArbiWsStore((s) => s.status)\n}\n\n/** `true` once the shared socket is authenticated and connected. */\nexport function useArbiConnected(): boolean {\n return useArbiWsStore((s) => s.status === 'connected')\n}\n\n/** The latest processing status per document id (the `task_update` stream). */\nexport function useArbiWsTasks() {\n return useArbiWsStore((s) => s.tasks)\n}\n\n/** The latest processing status for a single document, if any. */\nexport function useArbiWsTask(docId: string) {\n return useArbiWsStore((s) => s.tasks[docId])\n}\n","/**\n * Keep a workspace's documents (and tags) query live from WebSocket events —\n * the shared, no-polling replacement for refetch loops.\n *\n * Mount `useArbiDocumentSync(workspaceId)` once wherever the document list\n * matters. It refetches the documents query on:\n * - `batch_complete` (upload OR doctag_generate) for this workspace, and\n * - a terminal `task_update` for a document (processing finished),\n * so freshly-uploaded, freshly-coded, or freshly-processed docs appear without\n * anyone polling.\n */\n\nimport { useQueryClient } from '@tanstack/react-query'\nimport {\n isMessageType,\n type WsBatchCompleteMessage,\n type WsTaskUpdateMessage,\n} from '@arbidocs/client'\nimport { arbiQueryKeys } from '../hooks'\nimport { useArbiWebSocket } from './hooks'\n\n// Processing statuses that mean a document is done (success or otherwise) — the\n// point at which its row is worth refetching. Mirrors the SDK transport set.\nconst TERMINAL_STATUSES: ReadonlySet<string> = new Set([\n 'completed',\n 'failed',\n 'skipped',\n 'empty',\n 'low-content',\n])\n\nexport function useArbiDocumentSync(workspaceId: string | undefined): void {\n const queryClient = useQueryClient()\n\n useArbiWebSocket((msg) => {\n if (!workspaceId) return\n\n if (isMessageType<WsBatchCompleteMessage>(msg, 'batch_complete')) {\n if (msg.workspace_ext_id !== workspaceId) return\n void queryClient.invalidateQueries({ queryKey: arbiQueryKeys.documents(workspaceId) })\n void queryClient.invalidateQueries({ queryKey: arbiQueryKeys.tags(workspaceId) })\n return\n }\n\n if (isMessageType<WsTaskUpdateMessage>(msg, 'task_update')) {\n if (msg.workspace_ext_id !== workspaceId) return\n if (TERMINAL_STATUSES.has(msg.status)) {\n void queryClient.invalidateQueries({ queryKey: arbiQueryKeys.documents(workspaceId) })\n }\n }\n })\n}\n","/**\n * Pure workspace adapters: an SDK `WorkspaceResponse` (or the host's own copy of it) to the view\n * models the shell and the workspaces gallery show. No React state, no SDK calls, so a host that\n * does not mount an `<ArbiProvider>` can use them too.\n */\n\nimport type { ReactNode } from 'react'\n\n/** Workspace visibility: public = common, several members = shared, else private. */\nexport type ShellWorkspaceKind = 'private' | 'shared' | 'common'\n\n/** One face on a workspace card. */\nexport interface ShellWorkspaceMember {\n name: string\n picture?: string | null\n}\n\n/**\n * The fields of an SDK workspace the adapters read. Every field but the id and the name is\n * optional, so the SDK's `WorkspaceResponse` and a host's own copy of it are both assignable.\n */\nexport interface ShellWorkspaceSource {\n external_id: string\n name: string\n description?: string | null\n is_public?: boolean\n project_name?: string | null\n updated_at?: string\n shared_document_count?: number\n private_document_count?: number\n users?: ReadonlyArray<{\n user?: {\n given_name?: string | null\n family_name?: string | null\n email?: string | null\n picture?: string | null\n }\n /** Set when the member is an agent: agents are not people and are left off the faces. */\n agent_ext_id?: string | null\n }>\n}\n\n/**\n * A workspace as the shell and the gallery see it. Structurally a superset of blocks'\n * `ShellWorkspace` and `WorkspaceSummary`, so it is passed to both unchanged.\n */\nexport interface ShellWorkspaceItem {\n id: string\n name: string\n kind: ShellWorkspaceKind\n description?: string | null\n projectName?: string | null\n /** A rendered project pill; the host supplies it (see `decorate`). */\n projectLine?: ReactNode\n /** Shared plus private documents. */\n docCount: number\n /** People in the workspace (agents excluded). */\n memberCount: number\n members: ShellWorkspaceMember[]\n /** ISO timestamp. */\n updatedAt?: string\n}\n\n/** A workspace offered in the switcher menu. */\nexport interface ShellRecentWorkspaceItem extends ShellWorkspaceItem {\n /** Pre-formatted \"last seen\" text, when the host supplies `formatLastSeen`. */\n lastSeen?: string\n}\n\n/** Public, several members: shared. Otherwise private. */\nexport function getWorkspaceKind(\n workspace: Pick<ShellWorkspaceSource, 'is_public' | 'users'>\n): ShellWorkspaceKind {\n if (workspace.is_public) return 'common'\n if ((workspace.users?.length ?? 0) > 1) return 'shared'\n return 'private'\n}\n\nfunction memberName(user: NonNullable<ShellWorkspaceSource['users']>[number]['user']): string {\n const full = [user?.given_name, user?.family_name].filter(Boolean).join(' ').trim()\n return full || user?.email || ''\n}\n\n/** Adapt one SDK workspace to the shell and gallery view model. */\nexport function toShellWorkspace(workspace: ShellWorkspaceSource): ShellWorkspaceItem {\n const people = (workspace.users ?? []).filter((u) => !u.agent_ext_id)\n return {\n id: workspace.external_id,\n name: workspace.name,\n kind: getWorkspaceKind(workspace),\n description: workspace.description,\n projectName: workspace.project_name,\n docCount: (workspace.shared_document_count ?? 0) + (workspace.private_document_count ?? 0),\n memberCount: people.length,\n members: people.map((u) => ({ name: memberName(u.user), picture: u.user?.picture })),\n updatedAt: workspace.updated_at,\n }\n}\n\n/** The moment a workspace was last opened here, else last updated; 0 when neither is known. */\nfunction recency(\n workspace: ShellWorkspaceItem,\n lastOpened: Readonly<Record<string, number>> | undefined\n): number {\n const opened = lastOpened?.[workspace.id]\n if (opened !== undefined) return opened\n const updated = Date.parse(workspace.updatedAt ?? '')\n return Number.isNaN(updated) ? 0 : updated\n}\n\n/**\n * The workspace the app is in. Order: the host's selection if it is in the list; else the first\n * workspace of a live list; else the seed's active one; else the first workspace.\n */\nexport function resolveActiveWorkspace(\n items: readonly ShellWorkspaceItem[],\n selectedId: string | null | undefined,\n options: { isSeed?: boolean; seedActiveId?: string } = {}\n): ShellWorkspaceItem | undefined {\n const selected = selectedId ? items.find((w) => w.id === selectedId) : undefined\n if (selected) return selected\n if (options.isSeed && options.seedActiveId) {\n const seeded = items.find((w) => w.id === options.seedActiveId)\n if (seeded) return seeded\n }\n return items[0]\n}\n\n/** The other workspaces for the quick-switch menu, most recently opened first, capped. */\nexport function pickRecentWorkspaces(\n items: readonly ShellWorkspaceItem[],\n activeId: string | undefined,\n options: {\n limit?: number\n lastOpened?: Readonly<Record<string, number>>\n formatLastSeen?: (timestamp: number) => string\n } = {}\n): ShellRecentWorkspaceItem[] {\n const { limit = 4, lastOpened, formatLastSeen } = options\n return items\n .filter((w) => w.id !== activeId)\n .map((w) => ({ w, at: recency(w, lastOpened) }))\n .sort((a, b) => b.at - a.at)\n .slice(0, limit)\n .map(({ w, at }) => (formatLastSeen ? { ...w, lastSeen: formatLastSeen(at) } : w))\n}\n","/**\n * `useShellWorkspaces`: the user's workspaces as the shell's switcher and the workspaces gallery\n * show them, the one the app is in, and `open(workspace)`.\n *\n * Source-agnostic on purpose: the host hands in the list and the selection mechanism it already\n * has (ARBI-frontend its React Query hook and workspace store, a connected app `useWorkspaces`\n * plus the connection's `setWorkspace`). `useArbiShellWorkspaces` is the same hook wired to an\n * `<ArbiProvider>`.\n */\n\nimport { useCallback, useMemo, useRef, useState } from 'react'\nimport { useArbi } from '../useArbi'\nimport { useWorkspaces } from '../hooks'\nimport {\n pickRecentWorkspaces,\n resolveActiveWorkspace,\n toShellWorkspace,\n type ShellRecentWorkspaceItem,\n type ShellWorkspaceItem,\n type ShellWorkspaceSource,\n} from './shell-workspaces'\n\n/** Workspaces to show while the account has none (a demo); the host owns the data. */\nexport interface ShellWorkspaceSeed {\n workspaces: readonly ShellWorkspaceItem[]\n /** The seed workspace that counts as the current one when nothing is selected. */\n activeId?: string\n}\n\nexport interface UseShellWorkspacesOptions<S extends ShellWorkspaceSource = ShellWorkspaceSource> {\n /** The account's workspaces (SDK shape). `undefined` while loading. */\n workspaces: readonly S[] | undefined\n isLoading?: boolean\n /** The list query's error, passed through as `error`. */\n loadError?: unknown\n /** The workspace the host says the app is in (the connection's selection). */\n selectedId?: string | null\n /**\n * Make the workspace the app's current one: open it on the server and record the selection.\n * Throw (reject) to report failure. Called for EVERY open, including the current workspace, so\n * a click on the current card still re-opens it and then navigates.\n */\n select: (workspace: ShellWorkspaceItem) => Promise<unknown> | unknown\n /** After a successful select: navigate, toast, close a menu. The \"switch, then navigate\" hook. */\n onOpened?: (workspace: ShellWorkspaceItem) => void\n /** When select rejects. The active workspace is unchanged. Without it the error is in `error`. */\n onOpenError?: (error: unknown, workspace: ShellWorkspaceItem) => void\n /** Demo list for an account that has no workspaces (never while loading). */\n seed?: ShellWorkspaceSeed\n /** Host decoration per workspace, e.g. a rendered project pill. Merged over the adapter. */\n decorate?: (item: ShellWorkspaceItem, source: S) => Partial<ShellWorkspaceItem>\n /** How many recent workspaces the switcher offers. Default 4. */\n recentLimit?: number\n /** `workspace id -> epoch ms` last opened here; orders `recent`, falling back to `updatedAt`. */\n lastOpened?: Readonly<Record<string, number>>\n /** Format a recency timestamp into `recent[].lastSeen`. */\n formatLastSeen?: (timestamp: number) => string\n}\n\nexport interface UseShellWorkspacesResult {\n /** All workspaces: the account's, or the seed when it has none. */\n items: ShellWorkspaceItem[]\n /** The single current workspace; undefined only when there are no workspaces at all. */\n active: ShellWorkspaceItem | undefined\n /** The other workspaces, most recently opened first, for the quick-switch menu. */\n recent: ShellRecentWorkspaceItem[]\n /** The account's own workspaces: false while `items` is the seed. */\n isLive: boolean\n isLoading: boolean\n /** The list query's error or the last failed open; cleared by the next open. */\n error: unknown\n /** Id of the workspace being opened, else null (for a spinner on its card). */\n openingId: string | null\n /** Select the workspace (always, even the current one), then `onOpened`. False if select threw. */\n open: (workspace: Pick<ShellWorkspaceItem, 'id'> | string) => Promise<boolean>\n}\n\nexport function useShellWorkspaces<S extends ShellWorkspaceSource = ShellWorkspaceSource>(\n options: UseShellWorkspacesOptions<S>\n): UseShellWorkspacesResult {\n const {\n workspaces,\n isLoading = false,\n loadError,\n selectedId,\n seed,\n decorate,\n recentLimit,\n lastOpened,\n formatLastSeen,\n } = options\n\n const live = useMemo(\n () =>\n (workspaces ?? []).map((source) => {\n const item = toShellWorkspace(source)\n return decorate ? { ...item, ...decorate(item, source) } : item\n }),\n [workspaces, decorate]\n )\n const isLive = live.length > 0\n const isSeed = !isLive && !isLoading && !!seed\n const items = useMemo(\n () => (isLive ? live : isSeed ? [...seed.workspaces] : []),\n [isLive, live, isSeed, seed]\n )\n const active = useMemo(\n () => resolveActiveWorkspace(items, selectedId, { isSeed, seedActiveId: seed?.activeId }),\n [items, selectedId, isSeed, seed?.activeId]\n )\n const recent = useMemo(\n () =>\n pickRecentWorkspaces(items, active?.id, { limit: recentLimit, lastOpened, formatLastSeen }),\n [items, active?.id, recentLimit, lastOpened, formatLastSeen]\n )\n\n const [openingId, setOpeningId] = useState<string | null>(null)\n const [openError, setOpenError] = useState<unknown>(undefined)\n // Latest callbacks without re-creating `open` on every render.\n const callbacks = useRef({\n select: options.select,\n onOpened: options.onOpened,\n onOpenError: options.onOpenError,\n })\n callbacks.current = {\n select: options.select,\n onOpened: options.onOpened,\n onOpenError: options.onOpenError,\n }\n const itemsRef = useRef(items)\n itemsRef.current = items\n\n const open = useCallback(async (target: Pick<ShellWorkspaceItem, 'id'> | string) => {\n const id = typeof target === 'string' ? target : target.id\n const workspace = itemsRef.current.find((w) => w.id === id)\n if (!workspace) return false\n setOpenError(undefined)\n setOpeningId(id)\n try {\n await callbacks.current.select(workspace)\n } catch (err) {\n setOpenError(err)\n setOpeningId(null)\n callbacks.current.onOpenError?.(err, workspace)\n return false\n }\n setOpeningId(null)\n callbacks.current.onOpened?.(workspace)\n return true\n }, [])\n\n return {\n items,\n active,\n recent,\n isLive,\n isLoading,\n error: openError ?? loadError ?? null,\n openingId,\n open,\n }\n}\n\nexport interface UseArbiShellWorkspacesOptions extends Omit<\n UseShellWorkspacesOptions,\n 'workspaces' | 'isLoading' | 'loadError' | 'select'\n> {\n /**\n * Override how a workspace is made current. Default: `arbi.selectWorkspace(id)`, which opens it\n * on the server for the session. A host with its own selection state (the connection layer's\n * `setWorkspace`) passes it here.\n */\n select?: UseShellWorkspacesOptions['select']\n}\n\n/** `useShellWorkspaces` over the `<ArbiProvider>`'s workspace list and `selectWorkspace`. */\nexport function useArbiShellWorkspaces(\n options: UseArbiShellWorkspacesOptions = {}\n): UseShellWorkspacesResult {\n const arbi = useArbi()\n const query = useWorkspaces()\n const { select, ...rest } = options\n const defaultSelect = useCallback(\n (workspace: ShellWorkspaceItem) => arbi.selectWorkspace(workspace.id),\n [arbi]\n )\n return useShellWorkspaces({\n ...rest,\n workspaces: Array.isArray(query.data) ? (query.data as ShellWorkspaceSource[]) : undefined,\n isLoading: query.isLoading,\n loadError: query.error,\n select: select ?? defaultSelect,\n })\n}\n","/**\n * The AI engine — domain-agnostic hooks for building an AI-native app on ARBI.\n *\n * `useAiTask` runs a streaming, cited agentic query (tokens, agent steps and\n * artifacts accumulate live, with follow-up threading). `useWorkspaceDocs`\n * resolves a workspace's document ids to ground on, and `useSemanticSearch`\n * returns retrieval-only cited passages. These wrap the low-level SDK hooks so a\n * vertical app never re-implements the streaming/accumulation plumbing.\n */\n\nimport { useCallback, useMemo, useRef, useState } from 'react'\nimport { useMutation } from '@tanstack/react-query'\nimport type { SSEStreamResult, ArtifactEvent } from '@arbidocs/sdk/browser'\nimport { useDocuments, useAssistantQuery } from '../hooks'\nimport { useArbi } from '../useArbi'\n\nexport type { ArtifactEvent }\n\n/**\n * Resolve a workspace's document set and their external ids. Pass the active\n * `workspaceId`; the kit stays agnostic about how selection is managed.\n */\nexport function useWorkspaceDocs(workspaceId?: string) {\n const { data: docs = [], isLoading, isError } = useDocuments(workspaceId)\n\n const docIds = useMemo(\n () =>\n docs.map((d: { external_id?: string }) => d.external_id).filter((id): id is string => !!id),\n [docs]\n )\n\n return { wsId: workspaceId, docs, docIds, isLoading, isError, ready: docIds.length > 0 }\n}\n\nexport type AiTaskStatus = 'idle' | 'running' | 'done' | 'error'\n\nexport interface AiRunOptions {\n /** Continue a prior turn (follow-up questions in the same thread). */\n previousResponseId?: string | null\n model?: string\n}\n\n/**\n * Run a single streaming agentic task grounded in a set of documents.\n *\n * Returns live state (`text` accumulates tokens as they stream) plus a `run`\n * that resolves to the full {@link SSEStreamResult} — including the response id\n * needed to chain follow-ups.\n */\nexport function useAiTask() {\n const mutation = useAssistantQuery()\n const [status, setStatus] = useState<AiTaskStatus>('idle')\n const [text, setText] = useState('')\n const [stepCount, setStepCount] = useState(0)\n const [error, setError] = useState<string | null>(null)\n const [responseId, setResponseId] = useState<string | null>(null)\n const [artifacts, setArtifacts] = useState<ArtifactEvent[]>([])\n const bufferRef = useRef('')\n const artifactsRef = useRef<Map<string, ArtifactEvent>>(new Map())\n\n const reset = useCallback(() => {\n setStatus('idle')\n setText('')\n setStepCount(0)\n setError(null)\n setResponseId(null)\n setArtifacts([])\n artifactsRef.current = new Map()\n bufferRef.current = ''\n }, [])\n\n const run = useCallback(\n async (\n question: string,\n docIds: string[],\n opts?: AiRunOptions\n ): Promise<SSEStreamResult | null> => {\n setStatus('running')\n setText('')\n setStepCount(0)\n setError(null)\n setArtifacts([])\n artifactsRef.current = new Map()\n bufferRef.current = ''\n let streamError: string | null = null\n try {\n const result = await mutation.mutateAsync({\n question,\n docIds,\n previousResponseId: opts?.previousResponseId ?? undefined,\n model: opts?.model,\n onToken: (c: string) => {\n bufferRef.current += c\n setText(bufferRef.current)\n },\n onOutputItemDone: (ev) => {\n const t = (ev.item as { type?: string }).type\n if (t === 'function_call' || t === 'reasoning') setStepCount((n) => n + 1)\n },\n onArtifact: (a: ArtifactEvent) => {\n // Artifacts are documents; keep the latest version per doc.\n artifactsRef.current.set(a.doc_ext_id, a)\n setArtifacts([...artifactsRef.current.values()])\n },\n onError: (m: string) => {\n streamError = m\n },\n })\n const finalText = result.text || bufferRef.current\n setText(finalText)\n setResponseId(result.assistantMessageExtId)\n setStepCount(result.agentSteps.length || 0)\n if (result.artifacts?.length) {\n for (const a of result.artifacts) artifactsRef.current.set(a.doc_ext_id, a)\n setArtifacts([...artifactsRef.current.values()])\n }\n const err = streamError || result.errors[0] || null\n if (err && !finalText) {\n setError(err)\n setStatus('error')\n } else {\n setStatus('done')\n }\n return result\n } catch (e) {\n setError(e instanceof Error ? e.message : 'The assistant request failed.')\n setStatus('error')\n return null\n }\n },\n [mutation]\n )\n\n return {\n status,\n text,\n stepCount,\n error,\n responseId,\n artifacts,\n run,\n reset,\n isRunning: status === 'running',\n isDone: status === 'done',\n }\n}\n\n// ── Semantic search (retrieval-only, cited chunks — no LLM generation) ────────\n\nexport interface SearchChunk {\n /**\n * Stable chunk id — the join key that ties a search hit to its rendered\n * location in the document viewer (`<div data-chunk-id={chunkExtId}>`). This\n * is what lets a result open the split-screen viewer scrolled to, and\n * highlighting, the exact matched passage. May be absent for legacy chunks.\n */\n chunkExtId?: string | null\n docId?: string | null\n docTitle?: string | null\n page?: number | null\n score?: number | null\n content: string\n}\n\n/**\n * Search a set of documents and return the top matching passages.\n *\n * Retrieval is a triggered action, so it's modelled as a React Query\n * `useMutation` (like {@link useAiTask}) rather than an auto-running query. The\n * SDK's `assistant.retrieve` (POST `/v1/assistant/retrieve` with a\n * `retrieval_chunk` tool) is the only network call — the hook maps its response\n * into ranked {@link SearchChunk}s carrying the `chunkExtId` join key.\n */\nexport function useSemanticSearch(docIds: string[]) {\n const arbi = useArbi()\n const [query, setQuery] = useState('')\n\n const mutation = useMutation<\n SearchChunk[],\n Error,\n { query: string; mode: 'semantic' | 'keyword' | 'hybrid' }\n >({\n mutationFn: async ({ query: q, mode }) => {\n const res = await arbi.assistant.retrieve(q, docIds, { searchMode: mode })\n const byTool = res.retrieval_chunk?.tool_responses ?? {}\n return Object.values(byTool)\n .flat()\n .map(\n (c: {\n metadata: {\n chunk_ext_id?: string | null\n doc_ext_id?: string | null\n doc_title?: string | null\n page_number?: number | null\n rerank_score?: number | null\n score?: number | null\n }\n content: string\n }) => ({\n chunkExtId: c.metadata.chunk_ext_id,\n docId: c.metadata.doc_ext_id,\n docTitle: c.metadata.doc_title,\n page: c.metadata.page_number,\n score: c.metadata.rerank_score ?? c.metadata.score,\n content: c.content,\n })\n )\n .sort((a, b) => (b.score ?? 0) - (a.score ?? 0))\n },\n })\n\n const { mutateAsync, reset } = mutation\n const search = useCallback(\n async (q: string, mode: 'semantic' | 'keyword' | 'hybrid' = 'hybrid') => {\n const trimmed = q.trim()\n setQuery(trimmed)\n // Nothing to search — clear back to the idle state.\n if (!trimmed || docIds.length === 0) {\n reset()\n return\n }\n try {\n await mutateAsync({ query: trimmed, mode })\n } catch {\n // Error state is exposed via `error`; swallow the rejection so callers\n // can `void search(...)` from an event handler without an unhandled\n // promise rejection.\n }\n },\n [mutateAsync, reset, docIds]\n )\n\n const status: AiTaskStatus = mutation.isPending\n ? 'running'\n : mutation.isError\n ? 'error'\n : mutation.isSuccess\n ? 'done'\n : 'idle'\n\n return {\n query,\n results: mutation.data ?? [],\n status,\n error: mutation.error ? (mutation.error.message ?? 'Search failed.') : null,\n search,\n isRunning: mutation.isPending,\n }\n}\n","/**\n * Client-side redlining — turn an original + revised text into track-changes\n * markdown (`<del>` strikethrough deletions, `<ins>` insertions). Rendered by\n * {@link AiMarkdown} (via rehype-raw) and the {@link ArtifactCanvas}.\n */\nimport { diffWords } from 'diff'\nimport type { ArtifactEvent } from '@arbidocs/sdk/browser'\n\n/** Produce inline `<del>/<ins>` redline markdown from two document versions. */\nexport function toRedlineMarkdown(original: string, revised: string): string {\n const parts = diffWords(original ?? '', revised ?? '')\n return parts\n .map((p) => {\n if (p.added) return `<ins>${p.value}</ins>`\n if (p.removed) return `<del>${p.value}</del>`\n return p.value\n })\n .join('')\n}\n\n/** Count added/removed words between two versions (for a redline summary). */\nexport function redlineStats(original: string, revised: string) {\n let added = 0\n let removed = 0\n for (const p of diffWords(original ?? '', revised ?? '')) {\n const words = p.value.trim() ? p.value.trim().split(/\\s+/).length : 0\n if (p.added) added += words\n else if (p.removed) removed += words\n }\n return { added, removed }\n}\n\n/** Wrap arbitrary text/markdown as a synthetic artifact for the canvas. */\nexport function textToArtifact(\n title: string,\n content: string,\n opts?: { mode?: ArtifactEvent['mode']; isComplete?: boolean; version?: number; id?: string }\n): ArtifactEvent {\n return {\n type: 'arbi.artifact',\n doc_ext_id: opts?.id ?? `local-${title.replace(/\\W+/g, '-').toLowerCase()}`,\n title,\n mode: opts?.mode ?? 'markdown',\n content,\n // Content-backed (markdown/text/html) artifacts carry no blob; file_type is\n // required on ArtifactEvent and defaults to \"\" for non-image artifacts.\n file_type: '',\n is_complete: opts?.isComplete ?? true,\n version: opts?.version ?? 1,\n message_ext_id: null,\n t: null,\n }\n}\n","import { useState } from 'react'\nimport { Sparkles, Loader2, AlertTriangle, Copy, Check, ShieldCheck } from 'lucide-react'\nimport { cn } from '../lib/utils'\nimport type { AiTaskStatus } from './engine'\nimport { AiMarkdown } from './AiMarkdown'\n\n/**\n * Renders the live state of a single agentic task: streaming tokens, a \"thinking\"\n * indicator with the running step count, errors, and a grounded/cited footer with\n * copy-to-clipboard. Shared by every AI feature so streaming looks identical\n * everywhere. Copy is customisable via `groundedNote` / `runningHint`.\n */\nexport function AiAnswer({\n status,\n text,\n stepCount,\n error,\n className,\n emptyHint,\n groundedNote = 'Grounded in the live workspace · verify citations before relying on it',\n runningHint = 'Reading the documents…',\n testId = 'ai-answer',\n}: {\n status: AiTaskStatus\n text: string\n stepCount?: number\n error?: string | null\n className?: string\n emptyHint?: string\n groundedNote?: string\n runningHint?: string\n testId?: string\n}) {\n const [copied, setCopied] = useState(false)\n const running = status === 'running'\n const hasText = text.trim().length > 0\n\n const copy = async () => {\n await navigator.clipboard.writeText(text)\n setCopied(true)\n setTimeout(() => setCopied(false), 1600)\n }\n\n if (status === 'idle' && !hasText) {\n return emptyHint ? (\n <p className={cn('text-sm text-muted-foreground', className)} data-testid={`${testId}-empty`}>\n {emptyHint}\n </p>\n ) : null\n }\n\n return (\n <div className={cn('space-y-3', className)} data-testid={testId} data-status={status}>\n {running && (\n <div\n className=\"flex items-center gap-2 text-xs font-medium text-ai-accent\"\n data-testid={`${testId}-thinking`}\n >\n <Loader2 className=\"size-3.5 animate-spin\" />\n {stepCount && stepCount > 0\n ? `Working — ${stepCount} step${stepCount === 1 ? '' : 's'}…`\n : 'Thinking…'}\n </div>\n )}\n\n {status === 'error' && !hasText && (\n <div\n className=\"flex items-start gap-2 rounded-lg border border-destructive/30 bg-destructive/5 p-3 text-sm text-destructive\"\n data-testid={`${testId}-error`}\n >\n <AlertTriangle className=\"mt-0.5 size-4 shrink-0\" />\n <span>{error ?? 'The assistant request failed.'}</span>\n </div>\n )}\n\n {hasText && (\n <>\n <AiMarkdown isStreaming={running}>{text}</AiMarkdown>\n {!running && (\n <div className=\"flex items-center justify-between border-t border-border pt-2.5\">\n <span className=\"inline-flex items-center gap-1.5 text-xs text-muted-foreground\">\n <ShieldCheck className=\"size-3.5 text-ai-accent\" />\n {groundedNote}\n </span>\n <button\n type=\"button\"\n onClick={copy}\n className=\"inline-flex items-center gap-1 text-xs font-medium text-muted-foreground hover:text-foreground\"\n data-testid={`${testId}-copy`}\n >\n {copied ? (\n <Check className=\"size-3.5 text-ai-accent\" />\n ) : (\n <Copy className=\"size-3.5\" />\n )}\n {copied ? 'Copied' : 'Copy'}\n </button>\n </div>\n )}\n </>\n )}\n\n {running && !hasText && (\n <div className=\"flex items-center gap-1.5 text-sm text-muted-foreground\">\n <Sparkles className=\"size-4 animate-pulse text-ai-accent\" /> {runningHint}\n </div>\n )}\n </div>\n )\n}\n","import type { LucideIcon } from 'lucide-react'\nimport { Sparkles } from 'lucide-react'\nimport { Card } from '../ui/card'\nimport { Button } from '../ui/button'\nimport { useAiTask } from './engine'\nimport { AiAnswer } from './AiAnswer'\n\n/**\n * A self-contained one-click agentic workflow: title + description + a Run button\n * that streams a grounded, cited result inline. Drop it on any page — it owns its\n * own task state via `useAiTask`.\n */\nexport function AiActionCard({\n icon: Icon = Sparkles,\n title,\n description,\n prompt,\n docIds,\n runLabel = 'Run',\n noDocsHint = 'Connect to the workspace to run this.',\n disabled,\n testId,\n}: {\n icon?: LucideIcon\n title: string\n description: string\n /** The fully-built prompt to run, or a factory (deferred until click). */\n prompt: string | (() => string)\n docIds: string[]\n runLabel?: string\n noDocsHint?: string\n disabled?: boolean\n testId?: string\n}) {\n const task = useAiTask()\n const noDocs = docIds.length === 0\n\n const onRun = () => {\n const p = typeof prompt === 'function' ? prompt() : prompt\n void task.run(p, docIds)\n }\n\n return (\n <Card variant=\"elevated\" className=\"rounded-xl p-5\" data-testid={testId}>\n <div className=\"flex items-start justify-between gap-4\">\n <div className=\"flex items-start gap-3\">\n <div className=\"flex size-9 shrink-0 items-center justify-center rounded-lg bg-ai-accent-soft text-ai-accent\">\n <Icon className=\"size-4\" />\n </div>\n <div>\n <p className=\"text-sm font-semibold text-foreground\">{title}</p>\n <p className=\"mt-0.5 text-xs leading-relaxed text-muted-foreground\">{description}</p>\n </div>\n </div>\n <Button\n variant={task.isDone ? 'outline' : 'accent'}\n size=\"sm\"\n onClick={onRun}\n disabled={disabled || noDocs || task.isRunning}\n data-testid={testId && `${testId}-run`}\n >\n <Sparkles className=\"size-3.5\" />\n {task.isRunning ? 'Running…' : task.isDone ? 'Re-run' : runLabel}\n </Button>\n </div>\n\n {(task.status !== 'idle' || noDocs) && (\n <div className=\"mt-4\">\n {noDocs ? (\n <p className=\"text-xs text-muted-foreground\">{noDocsHint}</p>\n ) : (\n <AiAnswer\n status={task.status}\n text={task.text}\n stepCount={task.stepCount}\n error={task.error}\n testId={testId && `${testId}-answer`}\n />\n )}\n </div>\n )}\n </Card>\n )\n}\n","import { useEffect, useState } from 'react'\nimport {\n FileText,\n Download,\n Copy,\n Check,\n Loader2,\n GitCompareArrows,\n AlertTriangle,\n} from 'lucide-react'\nimport { motion, AnimatePresence } from 'framer-motion'\nimport { Badge } from '../ui/badge'\nimport { cn } from '../lib/utils'\nimport type { ArtifactEvent } from './engine'\nimport { AiMarkdown } from './AiMarkdown'\n\n/**\n * The artifacts canvas — renders agent-produced documents (drafts, redlines,\n * memos) as first-class artifacts in a paper-styled panel. Markdown mode supports\n * redlines (`<del>` deletions / `<ins>` additions). Streams live: content grows\n * and `is_complete` flips when finished. Token-neutral: the \"paper\" surface is\n * the kit's `ai-surface` colour.\n */\nexport function ArtifactCanvas({\n artifacts,\n className,\n emptyHint = 'Draft artifacts produced by the agent will open here.',\n busy = false,\n busyHint = 'The agent is working through the documents…',\n stepCount,\n error = null,\n}: {\n artifacts: ArtifactEvent[]\n className?: string\n emptyHint?: string\n /** A run failed before producing content — show it instead of the empty hint. */\n error?: string | null\n /**\n * The agent is running but hasn't produced streamable content yet. Agentic\n * drafts spend a while planning/retrieving before the first token, so show a\n * live working state instead of the empty hint — otherwise the canvas reads\n * as broken during a perfectly normal multi-step run.\n */\n busy?: boolean\n busyHint?: string\n /** Agent steps completed so far, surfaced in the working state when > 0. */\n stepCount?: number\n}) {\n const [activeId, setActiveId] = useState<string | null>(null)\n const [copied, setCopied] = useState(false)\n\n // Follow the most recent artifact as they stream in.\n useEffect(() => {\n if (artifacts.length && (!activeId || !artifacts.some((a) => a.doc_ext_id === activeId))) {\n setActiveId(artifacts[artifacts.length - 1].doc_ext_id)\n }\n }, [artifacts, activeId])\n\n if (artifacts.length === 0) {\n // A failed run with no partial content — surface the error, not a dead hint.\n if (error && !busy) {\n return (\n <div\n className={cn(\n 'flex h-full min-h-[280px] flex-col items-center justify-center rounded-xl border border-destructive/30 bg-destructive/5 p-8 text-center',\n className\n )}\n data-testid=\"artifact-canvas-error\"\n >\n <AlertTriangle className=\"size-8 text-destructive/70\" />\n <p className=\"mt-3 max-w-md text-sm text-foreground\">{error}</p>\n </div>\n )\n }\n // Running-but-empty: the agent is planning/retrieving before it streams.\n if (busy) {\n return (\n <div\n className={cn(\n 'flex h-full min-h-[280px] flex-col items-center justify-center rounded-xl border border-border bg-ai-surface/40 p-8 text-center',\n className\n )}\n data-testid=\"artifact-canvas-busy\"\n >\n <Loader2 className=\"size-8 animate-spin text-ai-accent\" />\n <p className=\"mt-4 max-w-xs text-sm font-medium text-foreground\">{busyHint}</p>\n {typeof stepCount === 'number' && stepCount > 0 && (\n <p className=\"mt-1 text-xs text-muted-foreground\" data-testid=\"artifact-canvas-steps\">\n {stepCount} {stepCount === 1 ? 'step' : 'steps'} so far\n </p>\n )}\n </div>\n )\n }\n return (\n <div\n className={cn(\n 'flex h-full min-h-[280px] flex-col items-center justify-center rounded-xl border border-dashed border-border bg-secondary/30 p-8 text-center',\n className\n )}\n data-testid=\"artifact-canvas-empty\"\n >\n <FileText className=\"size-8 text-muted-foreground/50\" />\n <p className=\"mt-3 max-w-xs text-sm text-muted-foreground\">{emptyHint}</p>\n </div>\n )\n }\n\n const active = artifacts.find((a) => a.doc_ext_id === activeId) ?? artifacts[artifacts.length - 1]\n const isRedline = /~~|<ins|<del|<mark/i.test(active.content)\n\n const copy = async () => {\n await navigator.clipboard.writeText(active.content)\n setCopied(true)\n setTimeout(() => setCopied(false), 1600)\n }\n\n const download = () => {\n const ext = active.mode === 'html' ? 'html' : active.mode === 'text' ? 'txt' : 'md'\n const blob = new Blob([active.content], { type: 'text/plain' })\n const url = URL.createObjectURL(blob)\n const a = document.createElement('a')\n a.href = url\n a.download = `${active.title.replace(/[^\\w.-]+/g, '_') || 'artifact'}.${ext}`\n a.click()\n URL.revokeObjectURL(url)\n }\n\n return (\n <div\n className={cn(\n 'flex h-full flex-col overflow-hidden rounded-xl border border-border bg-card',\n className\n )}\n data-testid=\"artifact-canvas\"\n >\n {/* Header */}\n <div className=\"flex items-center gap-2 border-b border-border bg-secondary/40 px-4 py-2.5\">\n <FileText className=\"size-4 shrink-0 text-ai-accent\" />\n <span\n className=\"min-w-0 flex-1 truncate text-sm font-medium text-foreground\"\n data-testid=\"artifact-title\"\n >\n {active.title}\n </span>\n {isRedline && (\n <Badge variant=\"accent\" className=\"gap-1\">\n <GitCompareArrows className=\"size-3\" /> Redline\n </Badge>\n )}\n <Badge variant=\"secondary\">v{active.version}</Badge>\n {!active.is_complete ? (\n <span\n className=\"inline-flex items-center gap-1 text-xs text-ai-accent\"\n data-testid=\"artifact-streaming\"\n >\n <Loader2 className=\"size-3 animate-spin\" /> drafting\n </span>\n ) : (\n <div className=\"flex items-center gap-1\">\n <button\n onClick={copy}\n className=\"rounded p-1 text-muted-foreground hover:bg-accent hover:text-foreground\"\n title=\"Copy\"\n data-testid=\"artifact-copy\"\n >\n {copied ? (\n <Check className=\"size-3.5 text-ai-accent\" />\n ) : (\n <Copy className=\"size-3.5\" />\n )}\n </button>\n <button\n onClick={download}\n className=\"rounded p-1 text-muted-foreground hover:bg-accent hover:text-foreground\"\n title=\"Download\"\n data-testid=\"artifact-download\"\n >\n <Download className=\"size-3.5\" />\n </button>\n </div>\n )}\n </div>\n\n {/* Tabs when multiple artifacts */}\n {artifacts.length > 1 && (\n <div className=\"flex gap-1 overflow-x-auto border-b border-border bg-card px-2 py-1.5\">\n {artifacts.map((a) => (\n <button\n key={a.doc_ext_id}\n onClick={() => setActiveId(a.doc_ext_id)}\n className={cn(\n 'shrink-0 rounded-md px-2.5 py-1 text-xs font-medium',\n a.doc_ext_id === active.doc_ext_id\n ? 'bg-ai-accent-soft text-ai-accent'\n : 'text-muted-foreground hover:bg-accent'\n )}\n >\n {a.title.slice(0, 28)}\n </button>\n ))}\n </div>\n )}\n\n {/* Paper body */}\n <div className=\"flex-1 overflow-y-auto bg-ai-surface/40 p-6\">\n <AnimatePresence mode=\"wait\">\n <motion.div\n key={active.doc_ext_id}\n initial={{ opacity: 0, y: 6 }}\n animate={{ opacity: 1, y: 0 }}\n transition={{ duration: 0.2 }}\n className=\"mx-auto max-w-2xl rounded-lg bg-card p-8 shadow-sm ring-1 ring-border\"\n >\n {active.mode === 'html' ? (\n <div className=\"text-sm\" dangerouslySetInnerHTML={{ __html: active.content }} />\n ) : active.mode === 'text' ? (\n <pre className=\"whitespace-pre-wrap font-mono text-xs text-foreground\">\n {active.content}\n </pre>\n ) : (\n <AiMarkdown>{active.content}</AiMarkdown>\n )}\n </motion.div>\n </AnimatePresence>\n </div>\n </div>\n )\n}\n","import React from 'react'\nimport { FileText, Image as ImageIcon } from 'lucide-react'\nimport { Card } from '../ui/card'\n\n/**\n * The minimal artifact shape this card renders. A structural subset of the\n * ARBI app's `StreamingDocument`, defined here so the light package doesn't\n * depend on the app store — any object carrying these fields is accepted.\n */\nexport interface MessageArtifact {\n /** External id of the drafted document; opened in the docked viewer. */\n docExtId: string\n /** Display title; falls back when empty. */\n title: string\n /** Whether generation has finished. */\n isComplete: boolean\n /** Content mode; `image` swaps in image-specific labels and icon. */\n mode: 'markdown' | 'html' | 'text' | 'image'\n}\n\ninterface MessageArtifactCardProps {\n /** The streaming/drafted document linked to this assistant message. */\n artifact: MessageArtifact\n /** Opens the drafted document (docExtId) in the docked viewer. */\n onOpen: (docExtId: string) => void\n}\n\n/**\n * Inline \"View draft\" affordance shown inside the assistant message that\n * produced a drafted document — so the artifact lives in the conversation\n * narrative (dyad-style) instead of only a hidden docked panel.\n *\n * Clean-ARBI contract: flat outline card, one chat type size, brand\n * accent on the action, tap-friendly (a real button — no hover-only).\n */\nexport function MessageArtifactCard({\n artifact,\n onOpen,\n}: MessageArtifactCardProps): React.JSX.Element {\n const { docExtId, title, isComplete, mode } = artifact\n const isImage = mode === 'image'\n const Icon = isImage ? ImageIcon : FileText\n const statusText = isImage\n ? isComplete\n ? 'Image ready'\n : 'Generating…'\n : isComplete\n ? 'Draft ready'\n : 'Drafting…'\n\n return (\n <Card\n variant=\"outline\"\n className=\"mt-3 flex items-center gap-3 px-3 py-2.5\"\n data-testid={`message-artifact-card-${docExtId}`}\n >\n <Icon className=\"h-4 w-4 shrink-0 text-muted-foreground\" aria-hidden />\n <div className=\"min-w-0 flex-1\">\n <div\n className=\"truncate text-chat font-semibold text-foreground\"\n data-testid=\"artifact-title\"\n >\n {title || (isImage ? 'Generated image' : 'Untitled draft')}\n </div>\n <div className=\"text-sm text-muted-foreground\" data-testid=\"artifact-status\">\n {statusText}\n </div>\n </div>\n <button\n type=\"button\"\n onClick={() => onOpen(docExtId)}\n className=\"shrink-0 rounded-md bg-secondary/15 px-3 py-1.5 text-sm font-semibold text-secondary transition-colors hover:bg-secondary/25\"\n data-testid={`view-artifact-button-${docExtId}`}\n >\n {isImage ? 'View image' : 'View draft'}\n </button>\n </Card>\n )\n}\n","import { useState } from 'react'\nimport { Search, Loader2, FileText, CornerDownLeft } from 'lucide-react'\nimport { Card } from '../ui/card'\nimport { Badge } from '../ui/badge'\nimport { useSemanticSearch } from './engine'\nimport { cn } from '../lib/utils'\n\n/**\n * Semantic search across a document set — retrieval-only (no LLM), returning the\n * top matching passages with their source document and page. Uses the SDK's\n * `assistant.retrieve`, so every hit is a real, cited chunk of a real document.\n */\nexport function DocSearch({\n docIds,\n onOpenDoc,\n placeholder = 'Semantic search across your documents…',\n className,\n}: {\n docIds: string[]\n onOpenDoc?: (docId: string) => void\n placeholder?: string\n className?: string\n}) {\n const { results, status, error, search, isRunning, query } = useSemanticSearch(docIds)\n const [value, setValue] = useState('')\n\n const submit = () => {\n if (value.trim()) void search(value, 'hybrid')\n }\n\n return (\n <div className={cn('space-y-3', className)} data-testid=\"doc-search\">\n <div className=\"relative\">\n <Search className=\"pointer-events-none absolute left-3 top-1/2 size-4 -translate-y-1/2 text-muted-foreground\" />\n {isRunning && (\n <Loader2 className=\"absolute right-3 top-1/2 size-4 -translate-y-1/2 animate-spin text-ai-accent\" />\n )}\n <input\n value={value}\n onChange={(e) => setValue(e.target.value)}\n onKeyDown={(e) => e.key === 'Enter' && (e.preventDefault(), submit())}\n placeholder={placeholder}\n className=\"h-11 w-full rounded-lg border border-input bg-background pl-9 pr-24 text-sm outline-none focus:border-ai-accent/50 focus:ring-2 focus:ring-ai-accent/15\"\n data-testid=\"doc-search-input\"\n />\n <button\n type=\"button\"\n onClick={submit}\n className=\"absolute right-2 top-1/2 flex -translate-y-1/2 items-center gap-1 rounded-md bg-ai-accent px-2.5 py-1 text-xs font-medium text-ai-accent-foreground\"\n data-testid=\"doc-search-submit\"\n >\n Search <CornerDownLeft className=\"size-3\" />\n </button>\n </div>\n\n {status === 'error' && (\n <p className=\"text-sm text-destructive\" data-testid=\"doc-search-error\">\n {error}\n </p>\n )}\n\n {status === 'done' && (\n <div className=\"space-y-2\" data-testid=\"doc-search-results\">\n <p className=\"text-xs text-muted-foreground\">\n {results.length === 0\n ? `No passages matched “${query}”.`\n : `${results.length} passage${results.length === 1 ? '' : 's'} for “${query}”`}\n </p>\n {results.slice(0, 8).map((r, i) => (\n <Card\n key={`${r.docId}-${r.page}-${i}`}\n variant=\"elevated\"\n className={cn(\n 'rounded-xl p-3',\n onOpenDoc && r.docId && 'cursor-pointer transition-colors hover:border-ai-accent/40'\n )}\n onClick={() => r.docId && onOpenDoc?.(r.docId)}\n data-testid={`doc-search-hit-${i}`}\n >\n <div className=\"mb-1 flex items-center gap-2\">\n <FileText className=\"size-3.5 text-ai-accent\" />\n <span className=\"truncate text-xs font-medium text-foreground\">\n {r.docTitle ?? 'Document'}\n </span>\n {r.page != null && <Badge variant=\"secondary\">p.{r.page}</Badge>}\n {r.score != null && (\n <span className=\"ml-auto text-xs text-muted-foreground\">\n score {r.score.toFixed(2)}\n </span>\n )}\n </div>\n <p className=\"line-clamp-3 text-xs leading-relaxed text-muted-foreground\">\n {r.content}\n </p>\n </Card>\n ))}\n </div>\n )}\n </div>\n )\n}\n","/**\n * DocumentReview — a reusable, decoupled \"review mode\" viewer for a single\n * document. It renders the parsed content (chunks grouped by page, as markdown)\n * and overlays the document's AI findings: each tag citation highlights the\n * chunks it references and is listed in a findings rail that jumps to the\n * passage on click.\n *\n * REUSE-FIRST: reads purely from SDK data — `useParsedDocument` for the body,\n * the passed-in `doc.doctags[].citations` for findings, `useTags` for label\n * names, and `MarkdownRenderer` for rendering. No app store / react-pdf / Zustand\n * coupling; citation-jump is plain `scrollIntoView` on `data-chunk-id`.\n */\n\nimport React from 'react'\nimport { X } from 'lucide-react'\nimport type { components } from '@arbidocs/client'\n\nimport { useParsedDocument, useTags } from '../hooks'\nimport { MarkdownRenderer } from '../ai/MarkdownRenderer'\nimport { TagEntity } from '../entities/TagEntity'\nimport { Badge } from '../ui/badge'\nimport { cn } from '../lib/utils'\nimport type { ParsedChunk } from './parsed-types'\n\ntype DocResponse = components['schemas']['DocResponse']\n\nexport interface DocumentReviewProps {\n /** Document to review. */\n docId: string\n /** The document object (from `useDocuments`) — supplies title + AI findings\n * (`doctags[].citations`). Optional: without it the viewer is a plain reader. */\n doc?: DocResponse\n /** Workspace id — used to resolve tag ids → human names for findings. */\n workspaceId?: string\n /** Parse stage to render. Default `final`. */\n stage?: string\n /**\n * A chunk to scroll to and persistently highlight — the join key is the\n * parsed chunk's `chunk_ext_id`. This is how a semantic-search hit drives the\n * viewer: passing the matched passage's `chunkExtId` scrolls the body to it\n * and marks it, mirroring the monolith's `viewingPassageId` behaviour.\n * Independent of AI findings (which highlight via `doctags[].citations`).\n */\n activeChunkId?: string | null\n /** When provided, a close button is shown in the header. */\n onClose?: () => void\n className?: string\n}\n\ninterface Finding {\n key: string\n tagExtId: string\n statement: string\n chunkIds: string[]\n}\n\nexport function DocumentReview({\n docId,\n doc,\n workspaceId,\n stage = 'final',\n activeChunkId,\n onClose,\n className,\n}: DocumentReviewProps) {\n const parsedQuery = useParsedDocument(docId, stage)\n const tagsQuery = useTags(workspaceId)\n\n const tagNameById = React.useMemo(() => {\n const map = new Map<string, string>()\n for (const t of tagsQuery.data ?? []) {\n if (t.external_id) map.set(t.external_id, t.name ?? t.external_id.slice(0, 8))\n }\n return map\n }, [tagsQuery.data])\n\n const title = doc?.doc_metadata?.title || doc?.file_name || 'Document'\n\n // Findings: one per grounded doctag, plus an index of which chunks it\n // highlights. A doctag used to carry a per-statement citation map, so this\n // produced several findings per tag; each statement was a verbatim copy of\n // the doctag's own note, so the tag's note IS the finding text now.\n const { findings, chunkToTag } = React.useMemo(() => {\n const list: Finding[] = []\n const chunkTag = new Map<string, string>() // chunk_ext_id → tag_ext_id\n for (const dt of doc?.doctags ?? []) {\n const chunkIds = (dt.citations ?? []).flatMap((d) => (d.chunks ?? []).map((c) => c.chunk_id))\n if (chunkIds.length === 0) continue\n list.push({\n key: dt.tag_ext_id,\n tagExtId: dt.tag_ext_id,\n statement: dt.note ?? '',\n chunkIds,\n })\n for (const cid of chunkIds) if (!chunkTag.has(cid)) chunkTag.set(cid, dt.tag_ext_id)\n }\n return { findings: list, chunkToTag: chunkTag }\n }, [doc?.doctags])\n\n // Group parsed chunks by page.\n const pages = React.useMemo(() => {\n const chunks = (parsedQuery.data?.chunks ?? []) as ParsedChunk[]\n const byPage = new Map<number, ParsedChunk[]>()\n for (const c of chunks) {\n const p = c.metadata?.page_number ?? 0\n if (!byPage.has(p)) byPage.set(p, [])\n byPage.get(p)!.push(c)\n }\n return [...byPage.entries()].sort((a, b) => a[0] - b[0])\n }, [parsedQuery.data])\n\n const scrollRef = React.useRef<HTMLDivElement | null>(null)\n const [flash, setFlash] = React.useState<string | null>(null)\n\n const jumpToChunk = React.useCallback((chunkId: string) => {\n const el = scrollRef.current?.querySelector<HTMLElement>(`[data-chunk-id=\"${chunkId}\"]`)\n if (!el) return\n el.scrollIntoView({ behavior: 'smooth', block: 'center' })\n setFlash(chunkId)\n window.setTimeout(() => setFlash((c) => (c === chunkId ? null : c)), 1600)\n }, [])\n\n // Drive the viewer from an external passage selection (semantic-search hit).\n // Scroll to + flash the target chunk once its element is in the DOM — which,\n // since this viewer renders every chunk eagerly, is as soon as the parsed\n // body has loaded. Re-runs whenever the selected passage changes so clicking\n // successive results re-navigates, matching `viewingPassageId` in the monolith.\n const parsedReady = !parsedQuery.isLoading && !!parsedQuery.data\n React.useEffect(() => {\n if (!activeChunkId || !parsedReady) return\n // Defer to the next frame so the chunk nodes are committed before we query.\n const raf = window.requestAnimationFrame(() => jumpToChunk(activeChunkId))\n return () => window.cancelAnimationFrame(raf)\n }, [activeChunkId, parsedReady, jumpToChunk])\n\n return (\n <div\n data-testid=\"document-review\"\n className={cn(\n 'flex h-full min-h-0 flex-col overflow-hidden rounded-lg border bg-card',\n className\n )}\n >\n {/* Header */}\n <div className=\"flex items-center gap-3 border-b px-4 py-3\">\n <div className=\"min-w-0 flex-1\">\n <div className=\"truncate text-sm font-semibold\" title={title}>\n {title}\n </div>\n <div className=\"text-xs text-muted-foreground\">\n {parsedQuery.data?.metadata?.total_number_of_pages\n ? `${parsedQuery.data.metadata.total_number_of_pages} pages`\n : `${pages.length} pages`}\n {findings.length ? ` · ${findings.length} findings` : ''}\n </div>\n </div>\n {doc?.status ? <Badge variant=\"secondary\">{doc.status}</Badge> : null}\n {onClose ? (\n <button\n type=\"button\"\n aria-label=\"Close review\"\n data-testid=\"document-review-close\"\n onClick={onClose}\n className=\"rounded p-1 text-muted-foreground hover:bg-muted hover:text-foreground\"\n >\n <X className=\"size-4\" />\n </button>\n ) : null}\n </div>\n\n <div className=\"flex min-h-0 flex-1\">\n {/* Findings rail */}\n {findings.length > 0 ? (\n <aside\n className=\"hidden w-64 shrink-0 overflow-y-auto border-r p-3 md:block\"\n data-testid=\"document-review-findings\"\n >\n <div className=\"mb-2 text-xs font-medium uppercase tracking-wide text-muted-foreground\">\n AI findings\n </div>\n <ul className=\"space-y-2\">\n {findings.map((f) => (\n <li key={f.key}>\n {/* role=button (not <button>) so the TagEntity pill — itself a\n button — isn't nested inside a button (invalid HTML). */}\n <div\n role=\"button\"\n tabIndex={0}\n data-testid=\"review-finding\"\n onClick={() => jumpToChunk(f.chunkIds[0])}\n onKeyDown={(e) => {\n if (e.key === 'Enter' || e.key === ' ') {\n e.preventDefault()\n jumpToChunk(f.chunkIds[0])\n }\n }}\n className=\"w-full cursor-pointer rounded-md border p-2 text-left text-xs transition hover:border-ring hover:bg-muted/50 focus:outline-none focus-visible:ring-2 focus-visible:ring-ring\"\n >\n <TagEntity\n size=\"sm\"\n tag={{\n external_id: f.tagExtId,\n name: tagNameById.get(f.tagExtId) ?? f.tagExtId.slice(0, 8),\n }}\n />\n <p className=\"mt-1 line-clamp-3 text-muted-foreground\">{f.statement}</p>\n </div>\n </li>\n ))}\n </ul>\n </aside>\n ) : null}\n\n {/* Document body */}\n <div ref={scrollRef} className=\"min-w-0 flex-1 overflow-y-auto px-6 py-4\">\n {parsedQuery.isLoading ? (\n <div className=\"flex h-full items-center justify-center text-sm text-muted-foreground\">\n Loading document…\n </div>\n ) : parsedQuery.isError ? (\n <div className=\"flex h-full items-center justify-center text-sm text-muted-foreground\">\n Could not load this document’s content.\n </div>\n ) : pages.length === 0 ? (\n <div className=\"flex h-full items-center justify-center text-sm text-muted-foreground\">\n No readable content.\n </div>\n ) : (\n <div className=\"mx-auto max-w-3xl space-y-8\">\n {pages.map(([pageNum, chunks]) => (\n <section key={pageNum}>\n <div className=\"mb-3 flex items-center gap-3\">\n <span className=\"text-xs font-medium uppercase tracking-wide text-muted-foreground\">\n Page {pageNum}\n </span>\n <div className=\"h-px flex-1 bg-border\" />\n </div>\n <div className=\"space-y-3\">\n {chunks.map((c, i) => {\n const cid = c.metadata?.chunk_ext_id\n const tagExtId = cid ? chunkToTag.get(cid) : undefined\n const highlighted = !!tagExtId\n const isActive = !!cid && cid === activeChunkId\n return (\n <div\n key={cid ?? i}\n data-chunk-id={cid}\n data-testid={\n isActive\n ? 'review-chunk-active'\n : highlighted\n ? 'review-chunk-cited'\n : 'review-chunk'\n }\n className={cn(\n 'scroll-mt-4 rounded-md px-2 py-1 transition-colors',\n highlighted &&\n 'bg-[var(--color-ai-accent-soft,theme(colors.amber.100))] ring-1 ring-inset ring-border',\n // The externally-selected search passage wins the\n // styling: a stronger accent ring so the matched\n // hit stands out from any AI-finding highlights.\n isActive &&\n 'bg-[var(--color-ai-accent-soft,theme(colors.amber.100))] ring-2 ring-inset ring-ai-accent',\n flash === cid && 'ring-2 ring-ring'\n )}\n >\n {highlighted ? (\n <div className=\"mb-1\">\n <TagEntity\n size=\"sm\"\n tag={{\n external_id: tagExtId!,\n name: tagNameById.get(tagExtId!) ?? tagExtId!.slice(0, 8),\n }}\n />\n </div>\n ) : null}\n <MarkdownRenderer className=\"prose prose-sm max-w-none dark:prose-invert\">\n {c.content}\n </MarkdownRenderer>\n </div>\n )\n })}\n </div>\n </section>\n ))}\n </div>\n )}\n </div>\n </div>\n </div>\n )\n}\n","/**\n * SemanticSearch — a drop-in, Google-style semantic search over a document set\n * with a split-screen document viewer.\n *\n * Left: a query box + ranked result rows (document title, matched snippet with\n * the query context, a relevance affordance and page meta). Right: the selected\n * document rendered inline, scrolled to and highlighting the matched passage.\n *\n * Architecture mirrors the ARBI-frontend monolith's retrieve → navigate →\n * highlight flow:\n * - `useSemanticSearch` calls `POST /v1/assistant/retrieve` (via the SDK's\n * `assistant.retrieve`) and returns ranked chunks, each carrying a stable\n * `chunkExtId`.\n * - Selecting a result passes that `chunkExtId` to <DocumentReview>, whose\n * body renders every parsed chunk as an addressable `data-chunk-id` node;\n * it scrolls to and marks the matching node — the shared key that ties a\n * search hit to its location in the rendered document.\n *\n * Data + hooks stay in @arbidocs/react. Theming is semantic tokens only\n * (shadcn tokens + the AI-accent contract) — no firm look is hardcoded.\n */\n\nimport { useCallback, useMemo, useState } from 'react'\nimport { ArrowLeft, FileText, Loader2, Search, CornerDownLeft } from 'lucide-react'\nimport type { components } from '@arbidocs/client'\nimport { Badge } from '../ui/badge'\nimport { Button } from '../ui/button'\nimport { cn } from '../lib/utils'\nimport { useDocuments } from '../hooks'\nimport { DocumentReview } from '../documents/DocumentReview'\nimport { PassageCard } from './PassageCard'\nimport { useSemanticSearch, type SearchChunk } from './engine'\n\ntype DocResponse = components['schemas']['DocResponse']\n\nexport interface SemanticSearchProps {\n /**\n * The document corpus to search. The caller resolves this from the active\n * workspace (e.g. via `useWorkspaceDocs`), keeping the block agnostic about\n * how workspace selection is managed — retrieval runs against the SDK's open\n * workspace.\n */\n docIds: string[]\n /**\n * Active workspace id — forwarded to the viewer so AI-finding tag ids resolve\n * to human names, and used to enrich each hit's document title/findings.\n */\n workspaceId?: string\n /** Which search mode to run. Default `hybrid` (keyword + semantic). */\n searchMode?: 'hybrid' | 'semantic' | 'keyword'\n /** Placeholder for the query box. */\n placeholder?: string\n className?: string\n 'data-testid'?: string\n}\n\n/** Significant words to emphasise in a snippet (quoted phrases + long words). */\nfunction queryTerms(query: string): string[] {\n const terms = new Set<string>()\n for (const phrase of query.match(/\"([^\"]+)\"/g) ?? []) {\n const inner = phrase.slice(1, -1).trim()\n if (inner) terms.add(inner)\n }\n for (const word of query.replace(/\"/g, ' ').split(/\\s+/)) {\n if (word.length > 2) terms.add(word)\n }\n return [...terms]\n}\n\n/** Render a snippet with the query terms marked, as React nodes (no raw HTML). */\nfunction HighlightedSnippet({ text, terms }: { text: string; terms: string[] }) {\n const nodes = useMemo(() => {\n if (terms.length === 0) return [text]\n const escaped = terms.map((t) => t.replace(/[.*+?^${}()|[\\]\\\\]/g, '\\\\$&'))\n const re = new RegExp(`(${escaped.join('|')})`, 'gi')\n // Unstyled on purpose — <PassageCard> styles the marks it contains.\n return text.split(re).map((part, i) => (i % 2 === 1 ? <mark key={i}>{part}</mark> : part))\n }, [text, terms])\n return <>{nodes}</>\n}\n\nfunction ResultRow({\n result,\n index,\n terms,\n isActive,\n onSelect,\n}: {\n result: SearchChunk\n index: number\n terms: string[]\n isActive: boolean\n onSelect: () => void\n}) {\n return (\n <PassageCard\n onClick={onSelect}\n active={isActive}\n score={result.score}\n data-testid={`arbi-semantic-search-result-${index}`}\n header={\n <>\n <FileText className=\"size-3.5 shrink-0 text-ai-accent\" />\n <span className=\"truncate text-xs font-medium text-foreground\">\n {result.docTitle ?? 'Document'}\n </span>\n {result.page != null && <Badge variant=\"secondary\">p.{result.page}</Badge>}\n </>\n }\n >\n <p className=\"line-clamp-3 text-xs leading-relaxed text-muted-foreground\">\n <span className=\"text-muted-foreground/60\">… </span>\n <HighlightedSnippet text={result.content} terms={terms} />\n <span className=\"text-muted-foreground/60\"> …</span>\n </p>\n </PassageCard>\n )\n}\n\nexport function SemanticSearch({\n docIds,\n workspaceId,\n searchMode = 'hybrid',\n placeholder = 'Search your documents by meaning…',\n className,\n 'data-testid': testId = 'arbi-semantic-search',\n}: SemanticSearchProps) {\n const { results, status, error, search, isRunning, query } = useSemanticSearch(docIds)\n const [value, setValue] = useState('')\n const [selected, setSelected] = useState<SearchChunk | null>(null)\n\n // Enrich hits with the full document (title + AI findings) when a workspace is\n // known. Without it the viewer still reads title/pages from parsed metadata.\n const { data: docs = [] } = useDocuments(workspaceId, { enabled: !!workspaceId })\n const docMap = useMemo(() => {\n const map = new Map<string, DocResponse>()\n for (const d of docs as DocResponse[]) if (d.external_id) map.set(d.external_id, d)\n return map\n }, [docs])\n\n const terms = useMemo(() => queryTerms(query), [query])\n\n const submit = useCallback(() => {\n const q = value.trim()\n if (!q) return\n setSelected(null)\n void search(q, searchMode)\n }, [value, search, searchMode])\n\n const selectedDoc = selected?.docId ? docMap.get(selected.docId) : undefined\n const hasResults = status === 'done' && results.length > 0\n\n return (\n <div data-testid={testId} className={cn('flex min-h-0 flex-col gap-4 md:flex-row', className)}>\n {/* Results panel — hidden on mobile once a document is open. */}\n <div\n className={cn(\n 'flex min-h-0 flex-col gap-3 md:w-[22rem] md:shrink-0',\n selected && 'hidden md:flex'\n )}\n >\n <div className=\"relative\">\n <Search className=\"pointer-events-none absolute left-3 top-1/2 size-4 -translate-y-1/2 text-muted-foreground\" />\n {isRunning && (\n <Loader2 className=\"absolute right-3 top-1/2 size-4 -translate-y-1/2 animate-spin text-ai-accent\" />\n )}\n <input\n value={value}\n onChange={(e) => setValue(e.target.value)}\n onKeyDown={(e) => e.key === 'Enter' && (e.preventDefault(), submit())}\n placeholder={placeholder}\n aria-label=\"Semantic search query\"\n className=\"h-11 w-full rounded-lg border border-input bg-background pl-9 pr-24 text-sm outline-none focus:border-ai-accent/50 focus:ring-2 focus:ring-ai-accent/15\"\n data-testid=\"arbi-semantic-search-input\"\n />\n <button\n type=\"button\"\n onClick={submit}\n disabled={!value.trim() || isRunning}\n className=\"absolute right-2 top-1/2 flex -translate-y-1/2 items-center gap-1 rounded-md bg-ai-accent px-2.5 py-1 text-xs font-medium text-ai-accent-foreground disabled:opacity-50\"\n data-testid=\"arbi-semantic-search-submit\"\n >\n Search <CornerDownLeft className=\"size-3\" />\n </button>\n </div>\n\n {status === 'error' && (\n <p className=\"text-sm text-destructive\" data-testid=\"arbi-semantic-search-error\">\n {error}\n </p>\n )}\n\n {status === 'done' && (\n <div\n className=\"flex min-h-0 flex-col gap-2 overflow-y-auto\"\n data-testid=\"arbi-semantic-search-results\"\n >\n <p className=\"text-xs text-muted-foreground\">\n {results.length === 0\n ? `No passages matched “${query}”.`\n : `${results.length} passage${results.length === 1 ? '' : 's'} for “${query}”`}\n </p>\n {results.map((r, i) => (\n <ResultRow\n key={r.chunkExtId ?? `${r.docId}-${r.page}-${i}`}\n result={r}\n index={i}\n terms={terms}\n isActive={selected?.chunkExtId != null && selected.chunkExtId === r.chunkExtId}\n onSelect={() => setSelected(r)}\n />\n ))}\n </div>\n )}\n </div>\n\n {/* Viewer panel — the split screen. On mobile it replaces the list. */}\n <div\n className={cn('min-h-0 min-w-0 flex-1', !selected && 'hidden md:block')}\n data-testid=\"arbi-semantic-search-viewer\"\n >\n {selected && selected.docId ? (\n <div className=\"flex h-full min-h-0 flex-col gap-2\">\n <Button\n variant=\"ghost\"\n size=\"sm\"\n className=\"self-start md:hidden\"\n onClick={() => setSelected(null)}\n data-testid=\"arbi-semantic-search-back\"\n >\n <ArrowLeft className=\"size-4\" /> Back to results\n </Button>\n <DocumentReview\n key={selected.docId}\n docId={selected.docId}\n doc={selectedDoc}\n workspaceId={workspaceId}\n activeChunkId={selected.chunkExtId ?? undefined}\n className=\"min-h-0 flex-1\"\n />\n </div>\n ) : (\n <div\n className=\"flex h-full min-h-[16rem] items-center justify-center rounded-lg border border-dashed border-border bg-muted/20 p-8 text-center\"\n data-testid=\"arbi-semantic-search-empty\"\n >\n <div className=\"max-w-xs\">\n <Search className=\"mx-auto mb-3 size-6 text-muted-foreground/50\" />\n <p className=\"text-sm text-muted-foreground\">\n {hasResults\n ? 'Select a passage to open the document alongside, scrolled to the match.'\n : 'Search across the record — every hit is a real, cited passage you can open in place.'}\n </p>\n </div>\n </div>\n )}\n </div>\n </div>\n )\n}\n","import { useState } from 'react'\nimport { Send, Tags } from 'lucide-react'\nimport { Button } from '../ui/button'\nimport { Input } from '../ui/input'\nimport { useAiTask } from './engine'\nimport { AiAnswer } from './AiAnswer'\n\n/**\n * Ask questions grounded in a SINGLE document (docId scoped to one file), plus a\n * one-click \"suggest tags\" action. Drop it in a document viewer.\n */\nexport function DocQaPanel({ docId, docName }: { docId: string; docName?: string }) {\n const task = useAiTask()\n const [q, setQ] = useState('')\n\n const ask = () => {\n const question = q.trim()\n if (!question || task.isRunning) return\n void task.run(\n `You are answering strictly from the single document \"${docName ?? docId}\". Cite the page/section for each point and say if the document does not address the question.\\n\\nQuestion: ${question}`,\n [docId]\n )\n }\n\n const suggestTags = () =>\n void task.run(\n `Suggest 3-6 concise, reusable labels for the document \"${docName ?? docId}\" — covering document type, the key issues it touches, and any key parties. Return them as a short comma-separated list with a one-line rationale for each.`,\n [docId]\n )\n\n return (\n <div className=\"min-w-0 space-y-3\" data-testid=\"doc-qa\">\n {/* min-w-0 on the field and shrink-0 on the buttons: without them a flex\n row refuses to shrink past the input's intrinsic width, so the actions\n overflow the container in any narrow host (a docked review rail, a\n split pane). */}\n <div className=\"flex min-w-0 items-center gap-2\">\n <Input\n value={q}\n onChange={(e) => setQ(e.target.value)}\n onKeyDown={(e) => e.key === 'Enter' && (e.preventDefault(), ask())}\n placeholder=\"Ask about this document…\"\n className=\"min-w-0 flex-1 bg-card text-sm placeholder:text-muted-foreground/70 focus-visible:border-ring/60 focus-visible:ring-2 focus-visible:ring-ring/50\"\n data-testid=\"doc-qa-input\"\n />\n <Button\n variant=\"accent\"\n size=\"icon\"\n onClick={ask}\n disabled={task.isRunning || !q.trim()}\n className=\"shrink-0\"\n data-testid=\"doc-qa-send\"\n >\n <Send className=\"size-4\" />\n </Button>\n <Button\n variant=\"outline\"\n size=\"sm\"\n onClick={suggestTags}\n disabled={task.isRunning}\n className=\"shrink-0\"\n data-testid=\"doc-qa-tags\"\n >\n <Tags className=\"size-4\" /> Tags\n </Button>\n </div>\n <AiAnswer\n status={task.status}\n text={task.text}\n stepCount={task.stepCount}\n error={task.error}\n emptyHint=\"Ask a question, or suggest tags — answered from this document only.\"\n testId=\"doc-qa-answer\"\n />\n </div>\n )\n}\n","import React, { useMemo, useCallback, useEffect, useLayoutEffect, useRef, useState } from 'react'\nimport { createPortal } from 'react-dom'\nimport ReactMarkdown, { Components } from 'react-markdown'\nimport type { components } from '@arbidocs/client'\nimport { MarkMenu, type MarkMenuItem } from '../ui/mark-menu'\nimport { cn } from '../lib/utils'\nimport { normalizeCitationMarkup } from './normalize-citations'\n\n/**\n * Presentational core of the ARBI citation renderer — promoted from the monolith\n * as the callback-injection reference for the AI family. It owns all the hard-won\n * citation behaviour (numbering, per-doc grouping, hover/active highlighting,\n * click/open flows, emphasis-safe markdown parsing) but knows NOTHING about the\n * app's store, router or React Query. Every app coupling is injected:\n *\n * - `renderMarkdown` — the app's `MarkdownRenderer` (KaTeX / Mermaid / doc-entity\n * pills all stay app-side; the core just hands it the citation `a` override).\n * - `ExternalLink` — the app's confirm-before-open external-link component.\n * - `onOpenCitation` / `onActivateChunk` — replace the two store writes that used\n * to fire when a citation opens / a chunk card is clicked.\n * - `useCitationState` — an injected hook the popover calls to read the reactive\n * active-citation / viewing-passage / active-page state (kept as a hook so the\n * subscription stays local to each popover, exactly as before — the top-level\n * renderer never re-renders on citation state changes, so the markdown is never\n * re-parsed mid-interaction).\n * - `onCloseCitation` / `onDismissCitation` — the two distinct close flows.\n */\n\n// Renders markdown inline (no block wrappers) for single-line truncated display\nconst INLINE_MD_COMPONENTS = {\n p: ({ children }: { children?: React.ReactNode }) => <>{children}</>,\n strong: ({ children }: { children?: React.ReactNode }) => (\n <strong className=\"font-semibold\">{children}</strong>\n ),\n em: ({ children }: { children?: React.ReactNode }) => <em>{children}</em>,\n code: ({ children }: { children?: React.ReactNode }) => (\n <code className=\"font-mono\">{children}</code>\n ),\n a: ({ children }: { children?: React.ReactNode }) => <>{children}</>,\n ul: ({ children }: { children?: React.ReactNode }) => <>{children}</>,\n ol: ({ children }: { children?: React.ReactNode }) => <>{children}</>,\n li: ({ children }: { children?: React.ReactNode }) => <span>{children} </span>,\n h1: ({ children }: { children?: React.ReactNode }) => <>{children}</>,\n h2: ({ children }: { children?: React.ReactNode }) => <>{children}</>,\n h3: ({ children }: { children?: React.ReactNode }) => <>{children}</>,\n h4: ({ children }: { children?: React.ReactNode }) => <>{children}</>,\n h5: ({ children }: { children?: React.ReactNode }) => <>{children}</>,\n h6: ({ children }: { children?: React.ReactNode }) => <>{children}</>,\n blockquote: ({ children }: { children?: React.ReactNode }) => <>{children}</>,\n pre: ({ children }: { children?: React.ReactNode }) => <>{children}</>,\n}\n\n// Structural citation types, sourced from the canonical OpenAPI schema so the\n// core stays in lockstep with the app's `Chunk` / `ToolResponses` shapes.\nexport type Chunk = components['schemas']['Chunk']\nexport interface ToolResponses {\n [docId: string]: Chunk[]\n}\n\n/** Reactive citation state the popover reads (injected as a hook by the app). */\nexport interface CitationState {\n activeCitationKey: string | null\n viewingPassageId: string | null\n isOnConversationPage: boolean\n}\n\n/** Payload handed to the app when a chunk card is clicked / a citation opens. */\nexport interface ChunkActivation {\n messageId: string\n citationNum: string\n chunkIds: string[]\n chunk: Chunk\n citationData?: ToolResponses\n}\n\n/** Renders the citation content as markdown — the app supplies its MarkdownRenderer. */\nexport type RenderMarkdown = (args: {\n components: Partial<Components>\n isStreaming: boolean\n children: string\n}) => React.ReactNode\n\nexport interface CitationRendererProps {\n content: string\n citations?: Record<string, string[]>\n citationData?: ToolResponses\n className?: string\n messageId: string\n isStreaming?: boolean\n // ── injected app bindings ──────────────────────────────────────────────────\n renderMarkdown: RenderMarkdown\n ExternalLink: React.ComponentType<React.ComponentPropsWithoutRef<'a'>>\n onOpenCitation: (citationKey: string) => void\n onActivateChunk: (activation: ChunkActivation) => void\n useCitationState: () => CitationState\n onCloseCitation: () => void\n onDismissCitation: () => void\n /** Tells the user a citation was copied (or could not be). Optional: copying is silent without it. */\n notify?: (message: string, kind?: 'success' | 'error' | 'info') => void\n}\n\nconst CitationRendererComponent: React.FC<CitationRendererProps> = ({\n content,\n citations,\n citationData,\n className,\n messageId,\n isStreaming = false,\n renderMarkdown,\n ExternalLink,\n onOpenCitation,\n onActivateChunk,\n useCitationState,\n onCloseCitation,\n onDismissCitation,\n notify,\n}) => {\n const chunkMap = useMemo(() => {\n const map = new Map<string, Chunk>()\n if (citationData) {\n Object.entries(citationData as ToolResponses).forEach(([, docChunks]) => {\n if (docChunks && Array.isArray(docChunks)) {\n docChunks.forEach((chunk: Chunk) => {\n if (chunk.metadata && chunk.metadata.chunk_ext_id) {\n map.set(chunk.metadata.chunk_ext_id, chunk)\n }\n })\n }\n })\n }\n return map\n }, [citationData])\n\n const getChunkDetails = useCallback(\n (chunkIds: string[]): Chunk[] =>\n [...new Set(chunkIds)]\n .map((id) => chunkMap.get(id))\n .filter((c): c is Chunk => c !== undefined),\n [chunkMap]\n )\n\n const handleChunkClick = useCallback(\n (citationNum: string, chunkIds: string[], chunk: Chunk) => {\n onActivateChunk({ messageId, citationNum, chunkIds, chunk, citationData })\n },\n [messageId, citationData, onActivateChunk]\n )\n\n const markdownComponents = useMemo(() => {\n const components: Partial<Components> = {\n a: ({ href, children, ...props }) => {\n if (!href?.startsWith('#cite-')) {\n if (!href || href.startsWith('#')) {\n return (\n <a className=\"text-primary underline underline-offset-2\" href={href} {...props}>\n {children}\n </a>\n )\n }\n return (\n <ExternalLink href={href} {...props}>\n {children}\n </ExternalLink>\n )\n }\n\n const citationNum = href.slice(6)\n const citationKey = `${messageId}-${citationNum}`\n const chunkIds = citations?.[citationNum] || []\n const chunks = getChunkDetails(chunkIds)\n\n return (\n <CitationPopover\n key={citationKey}\n citationNum={citationNum}\n messageId={messageId}\n chunks={chunks}\n isStreaming={isStreaming}\n onOpen={() => onOpenCitation(citationKey)}\n onChunkClick={(chunk) => handleChunkClick(citationNum, chunkIds, chunk)}\n useCitationState={useCitationState}\n onCloseCitation={onCloseCitation}\n onDismissCitation={onDismissCitation}\n notify={notify}\n >\n {children}\n </CitationPopover>\n )\n },\n }\n return components\n }, [\n citations,\n messageId,\n isStreaming,\n getChunkDetails,\n handleChunkClick,\n onOpenCitation,\n ExternalLink,\n useCitationState,\n onCloseCitation,\n onDismissCitation,\n notify,\n ])\n\n // Citation markers `[text](#cite-N)` are already valid markdown link syntax.\n // We let react-markdown parse them natively (the `a` override above keys on the\n // `#cite-` href) instead of pre-converting to raw HTML — so emphasis inside the\n // cited text (**bold**, *italic*, `code`) and literal `*`/`_` characters survive\n // intact, and link boundaries can never split an emphasis span.\n return (\n <div className={cn('citation-container', className)} data-testid=\"citation-renderer\">\n {renderMarkdown({\n components: markdownComponents,\n isStreaming,\n children: normalizeCitationMarkup(content),\n })}\n </div>\n )\n}\n\n// ── CitationPopover ──────────────────────────────────────────────────────────\n\ninterface CitationPopoverProps {\n citationNum: string\n messageId: string\n chunks: Chunk[]\n isStreaming: boolean\n onOpen: () => void\n onChunkClick: (chunk: Chunk) => void\n useCitationState: () => CitationState\n onCloseCitation: () => void\n onDismissCitation: () => void\n notify?: CitationRendererProps['notify']\n children: React.ReactNode\n}\n\nconst CitationPopover: React.FC<CitationPopoverProps> = ({\n citationNum,\n messageId,\n chunks,\n isStreaming,\n onOpen,\n onChunkClick,\n useCitationState,\n onCloseCitation,\n onDismissCitation,\n notify,\n children,\n}) => {\n const { activeCitationKey, viewingPassageId, isOnConversationPage } = useCitationState()\n const isActive = activeCitationKey === `${messageId}-${citationNum}`\n // Gate on the app's navigation state, not useLocation(): in-app navigation\n // rewrites the hash via history.replaceState, which react-router never\n // observes, so its location stays frozen at the page-load value.\n const open = isActive && isOnConversationPage\n\n // The popover belongs to the conversation view. If the user leaves it (another page, or a\n // full-screen panel over it) while it is open, drop the active key so it neither floats over\n // the new view nor reappears when they come back.\n useEffect(() => {\n if (isActive && !isOnConversationPage) onDismissCitation()\n }, [isActive, isOnConversationPage, onDismissCitation])\n\n const triggerRef = useRef<HTMLElement>(null)\n const dialogRef = useRef<HTMLDivElement>(null)\n // Set when the user closes it (Escape / the X): focus then goes back to the citation they came\n // from. A close caused by something else (another citation, leaving the page) leaves focus alone.\n const restoreFocusRef = useRef(false)\n\n const dismiss = useCallback(() => {\n restoreFocusRef.current = true\n onDismissCitation()\n }, [onDismissCitation])\n\n // The popover is portalled to the end of <body>, so a keyboard or screen-reader user who\n // opened it would otherwise have to Tab through the whole page to reach it. Move focus into the\n // dialog on open (taps do not focus a span on iOS, so this is not gated on the trigger) and\n // return it to the citation when the user dismisses.\n useEffect(() => {\n if (!open) return\n dialogRef.current?.focus({ preventScroll: true })\n return () => {\n if (!restoreFocusRef.current) return\n restoreFocusRef.current = false\n triggerRef.current?.focus({ preventScroll: true })\n }\n }, [open])\n\n // Escape closes like the X: the popover goes, the passage stays in the viewer.\n useEffect(() => {\n if (!open) return\n const onKeyDown = (e: KeyboardEvent) => {\n if (e.key === 'Escape') dismiss()\n }\n document.addEventListener('keydown', onKeyDown)\n return () => document.removeEventListener('keydown', onKeyDown)\n }, [open, dismiss])\n\n // The popover docks to the top edge of the composer (full chat width) instead of the cited\n // word, so it never covers the answer paragraph being cited. The edge is measured each time\n // the popover opens.\n const [dock, setDock] = useState({ left: 0, top: 0, width: 0 })\n\n // Measured whenever it opens, however it was opened (click, keyboard, a source chip).\n useLayoutEffect(() => {\n if (!open) return\n // The composer is exactly the chat column (the main element also spans a docked viewer).\n const edge = (\n document.querySelector('[data-testid=\"message-input-container\"]') ??\n document.querySelector('main[data-testid^=\"conversation-\"]') ??\n document.body\n ).getBoundingClientRect()\n setDock({ left: edge.left, top: edge.top, width: edge.width })\n }, [open])\n\n const handleOpen = useCallback(() => {\n onOpen()\n if (chunks.length > 0) {\n onChunkClick(chunks[0])\n }\n }, [onOpen, onChunkClick, chunks])\n\n const byDoc = useMemo(() => {\n const map = new Map<string, { title: string; chunks: Chunk[] }>()\n chunks.forEach((chunk) => {\n const docId = chunk.metadata.doc_ext_id ?? 'unknown'\n const title = chunk.metadata.doc_title ?? docId\n if (!map.has(docId)) map.set(docId, { title, chunks: [] })\n map.get(docId)!.chunks.push(chunk)\n })\n return Array.from(map.entries()).map(([docId, val]) => ({ docId, ...val }))\n }, [chunks])\n\n const first = chunks[0]\n const firstText = first ? first.content.replace(/\\n+/g, ' ').trim() : ''\n const firstTitle = first ? (first.metadata.doc_title ?? first.metadata.doc_ext_id ?? '') : ''\n const firstPage = first?.metadata.page_number\n\n const copyCitation = useCallback(async () => {\n const source = [firstTitle, firstPage != null ? `p.${firstPage}` : null]\n .filter(Boolean)\n .join(', ')\n try {\n await navigator.clipboard.writeText(source ? `“${firstText}” (${source})` : firstText)\n notify?.('Citation copied', 'success')\n } catch {\n notify?.('Could not copy the citation', 'error')\n }\n }, [firstText, firstTitle, firstPage, notify])\n\n const items: MarkMenuItem[] =\n isStreaming || chunks.length === 0\n ? []\n : [\n {\n id: 'open',\n label: 'Open in viewer',\n primary: true,\n onSelect: handleOpen,\n testId: `citation-open-${citationNum}`,\n },\n {\n id: 'copy',\n label: 'Copy citation',\n onSelect: () => void copyCitation(),\n testId: `citation-copy-${citationNum}`,\n },\n ]\n\n // The cited passage itself: quoted text, its source and page, before anything is opened.\n const preview = first ? (\n <div className=\"max-w-xs\" data-testid={`citation-preview-${citationNum}`}>\n <span className=\"block text-xs font-medium text-foreground\">{firstTitle}</span>\n {firstPage != null && (\n <span className=\"block text-xs text-muted-foreground\">Page {firstPage}</span>\n )}\n <span className=\"mt-1 line-clamp-4 block text-xs italic text-muted-foreground\">\n <ReactMarkdown components={INLINE_MD_COMPONENTS}>{firstText}</ReactMarkdown>\n </span>\n {chunks.length > 1 && (\n <span className=\"mt-1 block text-xs text-muted-foreground\">\n +{chunks.length - 1} more passage{chunks.length > 2 ? 's' : ''}\n </span>\n )}\n </div>\n ) : undefined\n\n return (\n <>\n <CitationLink\n triggerRef={triggerRef}\n citationNum={citationNum}\n isActive={isActive}\n isStreaming={isStreaming}\n items={items}\n preview={preview}\n >\n {children}\n </CitationLink>\n {open &&\n createPortal(\n <div\n className=\"pointer-events-none fixed z-[42] flex justify-center px-2\"\n style={{\n left: dock.left,\n width: dock.width,\n bottom: window.innerHeight - dock.top + 8,\n }}\n >\n <div\n ref={dialogRef}\n role=\"dialog\"\n tabIndex={-1}\n aria-label={`Citation ${citationNum}`}\n className=\"pointer-events-auto z-[42] max-h-[45vh] outline-none w-[min(100%,48rem)] min-w-0 overflow-y-auto rounded-md border border-border bg-popover p-0 text-popover-foreground shadow-xl\"\n data-testid={`citation-popover-${citationNum}`}\n >\n <div className=\"px-3 py-2 pointer-coarse:py-0 border-b border-border sticky top-0 bg-popover z-10 flex items-center justify-between gap-2\">\n <span className=\"text-xs font-semibold text-muted-foreground tracking-wide\">\n Citation {citationNum} ({chunks.length} passage{chunks.length !== 1 ? 's' : ''})\n </span>\n <button\n onClick={dismiss}\n // A bare 12px glyph is a tiny target — easy to miss, so closing takes\n // several tries. Pad it out to a comfortable ~28px tap area (negative\n // margin keeps the icon where it sat, so the header layout is\n // unchanged) and give it a hover background so it reads as a button.\n className=\"-m-1.5 flex shrink-0 items-center justify-center rounded p-1.5 text-muted-foreground transition-colors hover:bg-muted hover:text-foreground pointer-coarse:m-0 pointer-coarse:size-11 pointer-coarse:p-0\"\n aria-label=\"Close\"\n data-testid={`citation-popover-close-${citationNum}`}\n >\n <svg\n width=\"14\"\n height=\"14\"\n viewBox=\"0 0 12 12\"\n fill=\"none\"\n xmlns=\"http://www.w3.org/2000/svg\"\n >\n <path\n d=\"M1 1L11 11M11 1L1 11\"\n stroke=\"currentColor\"\n strokeWidth=\"1.5\"\n strokeLinecap=\"round\"\n />\n </svg>\n </button>\n </div>\n {byDoc.map(({ docId, title, chunks: docChunks }) => (\n <div key={docId} className=\"px-3 py-2 border-b border-border last:border-0\">\n <p className=\"text-sm font-semibold text-foreground mb-1 truncate\" title={title}>\n {title}\n </p>\n {docChunks.map((chunk) => {\n const isSelected = viewingPassageId === chunk.metadata.chunk_ext_id\n return (\n <button\n key={chunk.metadata.chunk_ext_id}\n data-testid={`citation-chunk-${chunk.metadata.chunk_ext_id}`}\n onClick={() => onChunkClick(chunk)}\n className={cn(\n 'w-full text-left text-sm rounded-md px-2 py-1.5 pointer-coarse:min-h-11 pointer-coarse:py-3 transition-colors flex items-start gap-2 mb-1 last:mb-0',\n isSelected\n ? 'bg-ai-soft text-foreground ring-1 ring-ai-accent/40'\n : 'text-muted-foreground hover:text-primary hover:bg-muted'\n )}\n >\n <span className=\"min-w-0 flex-1\">\n {chunk.metadata.page_number != null && (\n <span className=\"block text-xs text-muted-foreground\">\n Page {chunk.metadata.page_number}\n </span>\n )}\n <span className=\"line-clamp-3 italic\">\n <ReactMarkdown components={INLINE_MD_COMPONENTS}>\n {chunk.content.replace(/\\n+/g, ' ').trim()}\n </ReactMarkdown>\n </span>\n </span>\n </button>\n )\n })}\n </div>\n ))}\n </div>\n </div>,\n document.body\n )}\n </>\n )\n}\n\n// ── CitationLink ─────────────────────────────────────────────────────────────\n\ninterface CitationLinkProps {\n citationNum: string\n isActive: boolean\n isStreaming: boolean\n items: MarkMenuItem[]\n preview: React.ReactNode\n triggerRef: React.Ref<HTMLElement>\n children: React.ReactNode\n}\n\n/**\n * The cited words with a faint wash and a small superscript number: quiet text, not a badge.\n * Its one menu (preview of the passage, Open in viewer, Copy citation) is the shared `MarkMenu`.\n */\nconst CitationLink: React.FC<CitationLinkProps> = ({\n citationNum,\n isActive,\n isStreaming,\n items,\n preview,\n triggerRef,\n children,\n}) => (\n <MarkMenu\n triggerRef={triggerRef}\n items={items}\n preview={isStreaming ? undefined : preview}\n menuLabel={`Citation ${citationNum}`}\n testId={`citation-link-${citationNum}`}\n tabIndex={isStreaming ? -1 : 0}\n data-mark-kind=\"citation\"\n className={cn(\n 'cited-text relative rounded-sm px-0.5 transition-colors',\n // 44px touch hit area without changing the text layout.\n \"pointer-coarse:after:absolute pointer-coarse:after:content-[''] pointer-coarse:after:-inset-x-3 pointer-coarse:after:-inset-y-4\",\n isStreaming ? 'cursor-default' : 'cursor-pointer',\n isActive ? 'bg-ai-soft text-foreground' : 'bg-ai-soft/30 hover:bg-ai-soft/70'\n )}\n >\n {children}\n <sup className=\"ml-px align-super text-[0.7em] font-semibold leading-none tabular-nums text-ai-ink\">\n {citationNum}\n </sup>\n </MarkMenu>\n)\n\nexport const CitationRenderer = React.memo(CitationRendererComponent)\n","/**\n * DOC Icon Component. Promoted from the ARBI app for SDK reuse.\n * For Word documents (.doc, .docx files) with blue styling.\n */\n\nimport React from 'react'\nimport { FILE_TYPE_COLORS } from './colors'\n\ninterface DocIconProps {\n size?: number\n className?: string\n}\n\nexport const DocIcon: React.FC<DocIconProps> = ({ size = 16, className = '' }) => {\n return (\n <svg\n width={size}\n height={size}\n viewBox=\"0 0 24 24\"\n fill=\"none\"\n xmlns=\"http://www.w3.org/2000/svg\"\n className={className}\n >\n <path\n d=\"M14 2H6a2 2 0 0 0-2 2v16a2 2 0 0 0 2 2h12a2 2 0 0 0 2-2V8l-6-6z\"\n fill={FILE_TYPE_COLORS.doc}\n stroke={FILE_TYPE_COLORS.doc}\n strokeWidth=\"1\"\n strokeLinecap=\"round\"\n strokeLinejoin=\"round\"\n />\n <path\n d=\"M14 2v6h6\"\n fill=\"none\"\n stroke={FILE_TYPE_COLORS.white}\n strokeWidth=\"1\"\n strokeLinecap=\"round\"\n strokeLinejoin=\"round\"\n />\n <text\n x=\"12\"\n y=\"16\"\n fontSize=\"6\"\n fill=\"white\"\n textAnchor=\"middle\"\n fontWeight=\"bold\"\n fontFamily=\"Arial, sans-serif\"\n >\n DOC\n </text>\n </svg>\n )\n}\n","/**\n * HTML Icon Component. Promoted from the ARBI app for SDK reuse.\n * A proper HTML file icon with sky blue styling for web files.\n */\n\nimport React from 'react'\nimport { FILE_TYPE_COLORS } from './colors'\n\ninterface HtmlIconProps {\n size?: number\n className?: string\n}\n\nexport const HtmlIcon: React.FC<HtmlIconProps> = ({ size = 16, className = '' }) => {\n return (\n <svg\n width={size}\n height={size}\n viewBox=\"0 0 24 24\"\n fill=\"none\"\n xmlns=\"http://www.w3.org/2000/svg\"\n className={className}\n >\n <path\n d=\"M14 2H6a2 2 0 0 0-2 2v16a2 2 0 0 0 2 2h12a2 2 0 0 0 2-2V8l-6-6z\"\n fill={FILE_TYPE_COLORS.html}\n stroke={FILE_TYPE_COLORS.html}\n strokeWidth=\"1\"\n strokeLinecap=\"round\"\n strokeLinejoin=\"round\"\n />\n <path\n d=\"M14 2v6h6\"\n fill=\"none\"\n stroke={FILE_TYPE_COLORS.white}\n strokeWidth=\"1\"\n strokeLinecap=\"round\"\n strokeLinejoin=\"round\"\n />\n <text\n x=\"12\"\n y=\"16\"\n fontSize=\"5\"\n fill=\"white\"\n textAnchor=\"middle\"\n fontWeight=\"bold\"\n fontFamily=\"Arial, sans-serif\"\n >\n HTML\n </text>\n </svg>\n )\n}\n","/**\n * TXT Icon Component. Promoted from the ARBI app for SDK reuse.\n * For text files (.txt) with gray styling.\n */\n\nimport React from 'react'\nimport { FILE_TYPE_COLORS } from './colors'\n\ninterface TxtIconProps {\n size?: number\n className?: string\n}\n\nexport const TxtIcon: React.FC<TxtIconProps> = ({ size = 16, className = '' }) => {\n return (\n <svg\n width={size}\n height={size}\n viewBox=\"0 0 24 24\"\n fill=\"none\"\n xmlns=\"http://www.w3.org/2000/svg\"\n className={className}\n >\n <path\n d=\"M14 2H6a2 2 0 0 0-2 2v16a2 2 0 0 0 2 2h12a2 2 0 0 0 2-2V8l-6-6z\"\n fill={FILE_TYPE_COLORS.txt}\n stroke={FILE_TYPE_COLORS.txt}\n strokeWidth=\"1\"\n strokeLinecap=\"round\"\n strokeLinejoin=\"round\"\n />\n <path\n d=\"M14 2v6h6\"\n fill=\"none\"\n stroke={FILE_TYPE_COLORS.white}\n strokeWidth=\"1\"\n strokeLinecap=\"round\"\n strokeLinejoin=\"round\"\n />\n <text\n x=\"12\"\n y=\"16\"\n fontSize=\"6\"\n fill=\"white\"\n textAnchor=\"middle\"\n fontWeight=\"bold\"\n fontFamily=\"Arial, sans-serif\"\n >\n TXT\n </text>\n </svg>\n )\n}\n","/**\n * XLS Icon Component. Promoted from the ARBI app for SDK reuse.\n * For Excel spreadsheets (.xls, .xlsx files) with green styling.\n */\n\nimport React from 'react'\nimport { FILE_TYPE_COLORS } from './colors'\n\ninterface XlsIconProps {\n size?: number\n className?: string\n}\n\nexport const XlsIcon: React.FC<XlsIconProps> = ({ size = 16, className = '' }) => {\n return (\n <svg\n width={size}\n height={size}\n viewBox=\"0 0 24 24\"\n fill=\"none\"\n xmlns=\"http://www.w3.org/2000/svg\"\n className={className}\n >\n <path\n d=\"M14 2H6a2 2 0 0 0-2 2v16a2 2 0 0 0 2 2h12a2 2 0 0 0 2-2V8l-6-6z\"\n fill={FILE_TYPE_COLORS.xls}\n stroke={FILE_TYPE_COLORS.xls}\n strokeWidth=\"1\"\n strokeLinecap=\"round\"\n strokeLinejoin=\"round\"\n />\n <path\n d=\"M14 2v6h6\"\n fill=\"none\"\n stroke={FILE_TYPE_COLORS.white}\n strokeWidth=\"1\"\n strokeLinecap=\"round\"\n strokeLinejoin=\"round\"\n />\n <text\n x=\"12\"\n y=\"16\"\n fontSize=\"6\"\n fill=\"white\"\n textAnchor=\"middle\"\n fontWeight=\"bold\"\n fontFamily=\"Arial, sans-serif\"\n >\n XLS\n </text>\n </svg>\n )\n}\n","/** Generic file icon (gray, question mark). Promoted from the ARBI app. */\n\nimport React from 'react'\nimport { FILE_TYPE_COLORS } from './colors'\n\ninterface IconProps {\n size?: number\n className?: string\n}\n\nexport const FileIcon: React.FC<IconProps> = ({ size = 16, className = '' }) => {\n return (\n <svg\n width={size}\n height={size}\n viewBox=\"0 0 24 24\"\n fill=\"none\"\n xmlns=\"http://www.w3.org/2000/svg\"\n className={className}\n >\n <path\n d=\"M14 2H6a2 2 0 0 0-2 2v16a2 2 0 0 0 2 2h12a2 2 0 0 0 2-2V8l-6-6z\"\n fill={FILE_TYPE_COLORS.generic}\n stroke={FILE_TYPE_COLORS.generic}\n strokeWidth=\"1\"\n strokeLinecap=\"round\"\n strokeLinejoin=\"round\"\n />\n <path\n d=\"M14 2v6h6\"\n fill=\"none\"\n stroke={FILE_TYPE_COLORS.white}\n strokeWidth=\"1\"\n strokeLinecap=\"round\"\n strokeLinejoin=\"round\"\n />\n <text\n x=\"12\"\n y=\"17\"\n fontSize=\"10\"\n fill=\"white\"\n textAnchor=\"middle\"\n fontWeight=\"bold\"\n fontFamily=\"Arial, sans-serif\"\n >\n ?\n </text>\n </svg>\n )\n}\n","/**\n * Apple Icon Component. Promoted from the ARBI app for SDK reuse.\n */\n\nimport React from 'react'\n\ninterface AppleIconProps {\n size?: number\n className?: string\n 'aria-label'?: string\n 'aria-hidden'?: boolean\n}\n\nexport const AppleIcon: React.FC<AppleIconProps> = ({\n size = 20,\n className = '',\n 'aria-label': ariaLabel,\n 'aria-hidden': ariaHidden = true,\n}) => {\n return (\n <svg\n className={className}\n width={size}\n height={size}\n viewBox=\"0 0 24 24\"\n fill=\"currentColor\"\n aria-label={ariaLabel}\n aria-hidden={ariaHidden}\n >\n <path d=\"M17.05 20.28c-.98.95-2.05.8-3.08.35-1.09-.46-2.09-.48-3.24 0-1.44.62-2.2.44-3.06-.35C2.79 15.25 3.51 7.59 9.05 7.31c1.35.07 2.29.74 3.08.8 1.18-.24 2.31-.93 3.57-.84 1.51.12 2.65.72 3.4 1.8-3.12 1.87-2.38 5.98.48 7.13-.57 1.5-1.31 2.99-2.54 4.09l.01-.01zM12.03 7.25c-.15-2.23 1.66-4.07 3.74-4.25.29 2.58-2.34 4.5-3.74 4.25z\" />\n </svg>\n )\n}\n","/**\n * Google Icon Component. Promoted from the ARBI app for SDK reuse.\n */\n\nimport React from 'react'\n\ninterface GoogleIconProps {\n size?: number\n className?: string\n 'aria-label'?: string\n 'aria-hidden'?: boolean\n}\n\nexport const GoogleIcon: React.FC<GoogleIconProps> = ({\n size = 20,\n className = '',\n 'aria-label': ariaLabel,\n 'aria-hidden': ariaHidden = true,\n}) => {\n return (\n <svg\n className={className}\n width={size}\n height={size}\n viewBox=\"0 0 24 24\"\n aria-label={ariaLabel}\n aria-hidden={ariaHidden}\n >\n <path\n fill=\"#4285F4\"\n 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\"\n />\n <path\n fill=\"#34A853\"\n 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\"\n />\n <path\n fill=\"#FBBC05\"\n 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\"\n />\n <path\n fill=\"#EA4335\"\n 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\"\n />\n </svg>\n )\n}\n","/**\n * GitHub Icon Component. Promoted from the ARBI app for SDK reuse.\n */\n\nimport React from 'react'\n\ninterface GitHubIconProps {\n size?: number\n className?: string\n 'aria-label'?: string\n 'aria-hidden'?: boolean\n}\n\nexport const GitHubIcon: React.FC<GitHubIconProps> = ({\n size = 20,\n className = '',\n 'aria-label': ariaLabel,\n 'aria-hidden': ariaHidden = true,\n}) => {\n return (\n <svg\n className={className}\n width={size}\n height={size}\n viewBox=\"0 0 24 24\"\n fill=\"currentColor\"\n aria-label={ariaLabel}\n aria-hidden={ariaHidden}\n >\n <path\n fillRule=\"evenodd\"\n clipRule=\"evenodd\"\n d=\"M12 2C6.477 2 2 6.484 2 12.017c0 4.425 2.865 8.18 6.839 9.504.5.092.682-.217.682-.483 0-.237-.008-.868-.013-1.703-2.782.605-3.369-1.343-3.369-1.343-.454-1.158-1.11-1.466-1.11-1.466-.908-.62.069-.608.069-.608 1.003.07 1.531 1.032 1.531 1.032.892 1.53 2.341 1.088 2.91.832.092-.647.35-1.088.636-1.338-2.22-.253-4.555-1.113-4.555-4.951 0-1.093.39-1.988 1.029-2.688-.103-.253-.446-1.272.098-2.65 0 0 .84-.27 2.75 1.026A9.564 9.564 0 0112 6.844c.85.004 1.705.115 2.504.337 1.909-1.296 2.747-1.027 2.747-1.027.546 1.379.202 2.398.1 2.651.64.7 1.028 1.595 1.028 2.688 0 3.848-2.339 4.695-4.566 4.943.359.309.678.92.678 1.855 0 1.338-.012 2.419-.012 2.747 0 .268.18.58.688.482A10.019 10.019 0 0022 12.017C22 6.484 17.522 2 12 2z\"\n />\n </svg>\n )\n}\n","/**\n * LinkedIn Icon Component. Promoted from the ARBI app for SDK reuse.\n */\n\nimport React from 'react'\n\ninterface LinkedInIconProps {\n size?: number\n className?: string\n 'aria-label'?: string\n 'aria-hidden'?: boolean\n}\n\nexport const LinkedInIcon: React.FC<LinkedInIconProps> = ({\n size = 20,\n className = '',\n 'aria-label': ariaLabel,\n 'aria-hidden': ariaHidden = true,\n}) => {\n return (\n <svg\n className={className}\n width={size}\n height={size}\n viewBox=\"0 0 24 24\"\n fill=\"#0A66C2\"\n aria-label={ariaLabel}\n aria-hidden={ariaHidden}\n >\n <path d=\"M20.447 20.452h-3.554v-5.569c0-1.328-.027-3.037-1.852-3.037-1.853 0-2.136 1.445-2.136 2.939v5.667H9.351V9h3.414v1.561h.046c.477-.9 1.637-1.85 3.37-1.85 3.601 0 4.267 2.37 4.267 5.455v6.286zM5.337 7.433c-1.144 0-2.063-.926-2.063-2.065 0-1.138.92-2.063 2.063-2.063 1.14 0 2.064.925 2.064 2.063 0 1.139-.925 2.065-2.064 2.065zm1.782 13.019H3.555V9h3.564v11.452zM22.225 0H1.771C.792 0 0 .774 0 1.729v20.542C0 23.227.792 24 1.771 24h20.451C23.2 24 24 23.227 24 22.271V1.729C24 .774 23.2 0 22.222 0h.003z\" />\n </svg>\n )\n}\n","import React from 'react'\n\ninterface IconProps {\n size?: number\n className?: string\n 'aria-label'?: string\n 'aria-hidden'?: boolean\n}\n\nexport const OpenAIIcon: React.FC<IconProps> = ({\n size = 16,\n className = '',\n 'aria-label': ariaLabel = 'OpenAI',\n 'aria-hidden': ariaHidden = true,\n}) => (\n <svg\n className={className}\n width={size}\n height={size}\n viewBox=\"0 0 24 24\"\n aria-label={ariaLabel}\n aria-hidden={ariaHidden}\n >\n <path\n fill=\"#10A37F\"\n 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\"\n />\n </svg>\n)\n","import React from 'react'\n\ninterface IconProps {\n size?: number\n className?: string\n 'aria-label'?: string\n 'aria-hidden'?: boolean\n}\n\nexport const ClaudeIcon: React.FC<IconProps> = ({\n size = 16,\n className = '',\n 'aria-label': ariaLabel = 'Claude',\n 'aria-hidden': ariaHidden = true,\n}) => (\n <svg\n className={className}\n width={size}\n height={size}\n viewBox=\"0 0 24 24\"\n aria-label={ariaLabel}\n aria-hidden={ariaHidden}\n >\n <path\n fill=\"#D97757\"\n 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\"\n />\n </svg>\n)\n","import React from 'react'\n\ninterface IconProps {\n size?: number\n className?: string\n 'aria-label'?: string\n 'aria-hidden'?: boolean\n}\n\nexport const GeminiIcon: React.FC<IconProps> = ({\n size = 16,\n className = '',\n 'aria-label': ariaLabel = 'Gemini',\n 'aria-hidden': ariaHidden = true,\n}) => (\n <svg\n className={className}\n width={size}\n height={size}\n viewBox=\"0 0 24 24\"\n aria-label={ariaLabel}\n aria-hidden={ariaHidden}\n >\n <defs>\n <linearGradient id=\"geminiGradient\" x1=\"0%\" y1=\"0%\" x2=\"100%\" y2=\"100%\">\n <stop offset=\"0%\" stopColor=\"#1BA1E3\" />\n <stop offset=\"25%\" stopColor=\"#5489D6\" />\n <stop offset=\"50%\" stopColor=\"#9B72CB\" />\n <stop offset=\"75%\" stopColor=\"#D96570\" />\n <stop offset=\"100%\" stopColor=\"#F49C46\" />\n </linearGradient>\n </defs>\n <path\n fill=\"url(#geminiGradient)\"\n 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\"\n />\n </svg>\n)\n","import React from 'react'\n\ninterface IconProps {\n size?: number\n className?: string\n 'aria-label'?: string\n 'aria-hidden'?: boolean\n}\n\n/** Fireworks AI brand mark — three-stroke burst in their signature purple\n * (#6720FF). Pulled from fireworks.ai/icon0.svg. */\nexport const FireworksIcon: React.FC<IconProps> = ({\n size = 16,\n className = '',\n 'aria-label': ariaLabel = 'Fireworks AI',\n 'aria-hidden': ariaHidden = true,\n}) => (\n <svg\n className={className}\n width={size}\n height={size}\n viewBox=\"-2 6 36 20\"\n preserveAspectRatio=\"xMidYMid meet\"\n fill=\"none\"\n style={{ minWidth: size, minHeight: size }}\n aria-label={ariaLabel}\n aria-hidden={ariaHidden}\n >\n <path\n fill=\"#6720FF\"\n 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\"\n />\n <path\n fill=\"#6720FF\"\n 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\"\n />\n <path\n fill=\"#6720FF\"\n 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\"\n />\n </svg>\n)\n","import { Crown } from 'lucide-react'\nimport { OpenAIIcon } from './OpenAIIcon'\nimport { ClaudeIcon } from './ClaudeIcon'\nimport { GeminiIcon } from './GeminiIcon'\nimport { GoogleIcon } from './GoogleIcon'\nimport { FireworksIcon } from './FireworksIcon'\n\n/** Pick the best brand mark for a model. We prefer the *product* logo\n * (ChatGPT swirl, Gemini sparkle, Claude burst) when the model_name\n * signals a known product line, falling back to the LiteLLM provider\n * string for everything else. Returns Crown as the universal fallback so\n * Premium-tier rows always render an icon. */\nexport function ProviderIcon({\n modelName,\n provider,\n size = 16,\n className = '',\n}: {\n modelName?: string\n provider?: string | null\n size?: number\n className?: string\n}) {\n const m = (modelName ?? '').toLowerCase()\n const p = (provider ?? '').toLowerCase()\n\n if (m.includes('gpt') || p === 'openai') {\n return <OpenAIIcon size={size} className={className} />\n }\n if (m.includes('claude') || p === 'anthropic') {\n return <ClaudeIcon size={size} className={className} />\n }\n if (m.includes('gemini') || p.startsWith('vertex_ai')) {\n return <GeminiIcon size={size} className={className} />\n }\n if (p === 'google') {\n return <GoogleIcon size={size} className={className} />\n }\n if (p === 'fireworks_ai') {\n return <FireworksIcon size={size} className={className} />\n }\n return (\n <Crown\n className={className}\n style={{ width: size, height: size, color: '#EAB308', fill: '#EAB308' }}\n />\n )\n}\n","/**\n * ARBI Icon Component. Promoted from the ARBI app for SDK reuse.\n * Renders the host app's `/favicon.svg` (the consumer serves the asset).\n */\n\nimport React from 'react'\n\ninterface ArbiIconProps {\n size?: number\n className?: string\n 'aria-label'?: string\n 'aria-hidden'?: boolean\n}\n\nexport const ArbiIcon: React.FC<ArbiIconProps> = ({\n size = 20,\n className = '',\n 'aria-label': ariaLabel = 'ARBI Docs',\n 'aria-hidden': ariaHidden = false,\n}) => {\n return (\n <img\n src=\"/favicon.svg\"\n alt={ariaLabel}\n className={`rounded object-contain ${className}`}\n style={{ width: size, height: size }}\n aria-label={ariaLabel}\n aria-hidden={ariaHidden}\n />\n )\n}\n","import React, { useId } from 'react'\n\ninterface ArbiBotIconProps {\n size?: number\n className?: string\n}\n\nexport const ArbiBotIcon: React.FC<ArbiBotIconProps> = ({ size = 24, className = '' }) => {\n const maskId = useId()\n\n return (\n <svg\n xmlns=\"http://www.w3.org/2000/svg\"\n width={size}\n height={size}\n viewBox=\"0 0 250 250\"\n preserveAspectRatio=\"xMidYMid meet\"\n className={className}\n >\n <defs>\n <mask id={maskId}>\n <g transform=\"translate(0,250) scale(0.1,-0.1)\">\n <rect x=\"0\" y=\"0\" width=\"2500\" height=\"2500\" fill=\"white\" />\n {/* Cut out thick rings around the eyes — annulus shape */}\n <circle cx=\"855\" cy=\"1715\" r=\"190\" fill=\"black\" />\n <circle cx=\"855\" cy=\"1715\" r=\"50\" fill=\"white\" />\n <circle cx=\"1665\" cy=\"1700\" r=\"190\" fill=\"black\" />\n <circle cx=\"1665\" cy=\"1700\" r=\"50\" fill=\"white\" />\n </g>\n </mask>\n </defs>\n <g mask={`url(#${maskId})`}>\n <g\n transform=\"translate(0,250) scale(0.1,-0.1)\"\n fill=\"currentColor\"\n stroke=\"currentColor\"\n strokeWidth=\"100\"\n >\n <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\" />\n </g>\n <g transform=\"translate(0,250) scale(0.1,-0.1)\" fill=\"currentColor\" stroke=\"none\">\n <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\" />\n <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\" />\n <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\" />\n <g transform=\"translate(564,0)\">\n <path\n d=\"M515 353 c-49 -136 -91 -253 -93 -261 -3 -10 11 -12 60 -10 l63 3 19 53 19 52 91 0 92 0 18 -55 17 -56 62 3 c76 4 79 -24 -30 275 l-88 243 -70 0 -70 0 -90 -247z m215 -55 c0 -4 -27 -8 -59 -8 l-60 0 31 92 31 93 29 -85 c15 -46 28 -88 28 -92z\"\n stroke=\"currentColor\"\n strokeWidth=\"30\"\n />\n </g>\n </g>\n </g>\n </svg>\n )\n}\n","/**\n * Notification-type presentation primitives — the brand-neutral icon, colour and\n * label maps for every `NotificationType`, plus the workspace-membership phrasing\n * helpers. Kept in their own module (not a component file) so both the monolith's\n * AG-Grid notification centre and lightweight consumers (e.g. clarum's activity\n * feed) share one source of truth for \"what does this notification type mean\",\n * and so component files stay fast-refresh friendly.\n *\n * Deliberately decoupled: no store, no app `@/` imports — just lucide icon\n * components + semantic Tailwind token class names. Callers render the icon\n * themselves (`<Icon className={iconClassName} />`).\n */\n\nimport {\n Activity,\n Gauge,\n Gift,\n Info,\n MessageCircleMore,\n PartyPopper,\n UserCheck,\n} from 'lucide-react'\nimport { getEntityIcon, type EntityIconComponent } from '../entities/registry'\n\n/** Icon component, its colour class, and a short human label for a notification type. */\nexport interface NotificationTypeMeta {\n Icon: EntityIconComponent\n /** Semantic Tailwind colour class for the glyph. */\n iconClassName: string\n /** Short category label (e.g. \"Added\", \"Usage 90%\"). */\n label: string\n}\n\n/**\n * Resolve the icon + colour + short label for a notification type.\n *\n * Workspace-membership events all share the workspace glyph — the specific role\n * lives in the Event sentence (see {@link getWorkspaceSentPhrase}), so the label\n * stays short (\"Added\", not \"Added as collaborator\"). Unknown types fall back to\n * an info glyph and the raw type string.\n */\nexport function getNotificationTypeMeta(type: string | null | undefined): NotificationTypeMeta {\n // Resolve the workspace glyph live (not at module load) so a deployment's\n // configureEntityRegistry() injection is always reflected, regardless of import order.\n const WorkspaceIcon = getEntityIcon('WORKSPACE') as EntityIconComponent\n switch (type) {\n case 'user_message':\n return { Icon: MessageCircleMore, iconClassName: 'text-primary', label: 'Message' }\n case 'workspaceuser_added_owner':\n case 'workspaceuser_added_collaborator':\n case 'workspaceuser_added_guest':\n return { Icon: WorkspaceIcon, iconClassName: 'text-primary', label: 'Added' }\n case 'workspaceuser_removed':\n return { Icon: WorkspaceIcon, iconClassName: 'text-primary', label: 'Removed' }\n case 'workspaceuser_updated_owner':\n case 'workspaceuser_updated_collaborator':\n case 'workspaceuser_updated_guest':\n return { Icon: WorkspaceIcon, iconClassName: 'text-primary', label: 'Role changed' }\n case 'contact_accepted':\n return { Icon: UserCheck, iconClassName: 'text-green-500', label: 'Invitation' }\n case 'signup_reward':\n return { Icon: PartyPopper, iconClassName: 'text-green-600', label: 'Signup bonus' }\n case 'referral_reward':\n return { Icon: Gift, iconClassName: 'text-green-600', label: 'Reward earned' }\n case 'quota_threshold_50':\n return { Icon: Gauge, iconClassName: 'text-blue-500', label: 'Usage 50%' }\n case 'quota_threshold_90':\n return { Icon: Gauge, iconClassName: 'text-orange-500', label: 'Usage 90%' }\n case 'quota_threshold_100':\n return { Icon: Gauge, iconClassName: 'text-red-500', label: 'Usage limit' }\n case 'activity':\n // Durable to-self activity line — the specific event lives in `content`.\n // Callers that have the content should prefer describeActivity() for a\n // precise glyph/label; this is the type-only fallback.\n return { Icon: Activity, iconClassName: 'text-muted-foreground', label: 'Activity' }\n default:\n return { Icon: Info, iconClassName: 'text-blue-500', label: type || 'Notification' }\n }\n}\n\n/** Whether a notification type is a workspace-membership event. */\nexport function isWorkspaceNotificationType(type: string): boolean {\n return type.startsWith('workspaceuser_')\n}\n\n/**\n * Recipient-perspective action text (\"you received\"). Renders after the sender\n * pill: \"[sender] added you as collaborator\". The workspace renders in its own\n * column, so there's no trailing preposition.\n */\nexport function getWorkspaceActionText(type: string): string {\n switch (type) {\n case 'workspaceuser_added_owner':\n return 'added you as owner'\n case 'workspaceuser_added_collaborator':\n return 'added you as collaborator'\n case 'workspaceuser_added_guest':\n return 'added you as guest'\n case 'workspaceuser_removed':\n return 'removed you'\n case 'workspaceuser_updated_owner':\n return 'changed your role to owner'\n case 'workspaceuser_updated_collaborator':\n return 'changed your role to collaborator'\n case 'workspaceuser_updated_guest':\n return 'changed your role to guest'\n default:\n return 'updated your access'\n }\n}\n\n/**\n * Sender-perspective phrasing (\"you did this\"). Renders around the affected\n * member pill — `{before} [member] {after}` — so it reads as an active sentence:\n * \"You added [Jane] as collaborator\" rather than the ambiguous \"Added as\n * collaborator: Jane\".\n */\nexport function getWorkspaceSentPhrase(type: string): { before: string; after: string } {\n switch (type) {\n case 'workspaceuser_added_owner':\n return { before: 'You added', after: 'as owner' }\n case 'workspaceuser_added_collaborator':\n return { before: 'You added', after: 'as collaborator' }\n case 'workspaceuser_added_guest':\n return { before: 'You added', after: 'as guest' }\n case 'workspaceuser_removed':\n return { before: 'You removed', after: '' }\n case 'workspaceuser_updated_owner':\n return { before: 'You set', after: 'as owner' }\n case 'workspaceuser_updated_collaborator':\n return { before: 'You set', after: 'as collaborator' }\n case 'workspaceuser_updated_guest':\n return { before: 'You set', after: 'as guest' }\n default:\n return { before: 'You updated access for', after: '' }\n }\n}\n","/**\n * Activity-event presentation — decodes the compact `{\"event\": ..., ...fields}`\n * JSON payload carried by durable `activity` notifications (recorded backend-side\n * by `log_activity`) into a glyph + human sentence.\n *\n * Distinct from `notification-types.ts`: that maps the notification *type* (a DM,\n * a workspace-membership change, a reward); this maps the *event* recorded on a\n * to-self activity line (\"opened a workspace\", \"processed a document\"). Entity\n * glyphs are sourced from the shared entity registry — one source of truth.\n */\n\nimport {\n Activity,\n FileCheck2,\n FileX2,\n FolderPlus,\n Pencil,\n SquareArrowOutUpRight,\n Trash2,\n} from 'lucide-react'\nimport { getEntityIcon, type EntityIconComponent } from '../entities/registry'\n\n/** Parsed activity payload — always has `event`, plus event-specific fields. */\nexport interface ActivityContent {\n event: string\n [field: string]: unknown\n}\n\n/** Rendered description of an activity line. */\nexport interface ActivityDescription {\n Icon: EntityIconComponent\n /** Semantic Tailwind colour class for the glyph. */\n iconClassName: string\n /** Human-readable one-line summary of what happened. */\n title: string\n}\n\n/** Parse an activity notification's `content` JSON into `{event, ...fields}`, or null. */\nexport function parseActivityContent(content: string | null | undefined): ActivityContent | null {\n if (!content) return null\n try {\n const parsed = JSON.parse(content)\n if (parsed && typeof parsed === 'object' && typeof parsed.event === 'string') {\n return parsed as ActivityContent\n }\n } catch {\n // Not JSON (e.g. a legacy plain-string activity line) — no structured event.\n }\n return null\n}\n\nfunction str(v: unknown): string | undefined {\n return typeof v === 'string' && v ? v : undefined\n}\n\n/**\n * Describe an activity line for display. Accepts either the raw `content` string\n * or an already-parsed {@link ActivityContent}. Unknown/unparseable events fall\n * back to a generic activity glyph and a humanised event name.\n */\nexport function describeActivity(\n content: string | ActivityContent | null | undefined\n): ActivityDescription {\n const parsed =\n typeof content === 'string' || content == null ? parseActivityContent(content) : content\n\n if (!parsed) {\n return { Icon: Activity, iconClassName: 'text-muted-foreground', title: 'Activity' }\n }\n\n const fileName = str(parsed.file_name)\n\n switch (parsed.event) {\n case 'workspace_opened':\n return {\n Icon: SquareArrowOutUpRight,\n iconClassName: 'text-primary',\n title: 'Opened a workspace',\n }\n case 'workspace_created':\n return { Icon: FolderPlus, iconClassName: 'text-green-600', title: 'Created a workspace' }\n case 'workspace_updated':\n return { Icon: Pencil, iconClassName: 'text-primary', title: 'Updated workspace settings' }\n case 'workspace_deleted':\n return { Icon: Trash2, iconClassName: 'text-red-500', title: 'Deleted a workspace' }\n case 'document_processing': {\n const failed = str(parsed.status) === 'failed'\n const noun = fileName ? `“${fileName}”` : 'a document'\n return failed\n ? { Icon: FileX2, iconClassName: 'text-red-500', title: `Failed to process ${noun}` }\n : { Icon: FileCheck2, iconClassName: 'text-green-600', title: `Processed ${noun}` }\n }\n default:\n // Humanise an unrecognised event slug: \"some_new_event\" → \"Some new event\".\n return {\n Icon: parsed.workspace_ext_id\n ? (getEntityIcon('WORKSPACE') as EntityIconComponent)\n : Activity,\n iconClassName: 'text-muted-foreground',\n title: humaniseEvent(parsed.event),\n }\n }\n}\n\n/** \"workspace_opened\" → \"Workspace opened\" — a readable fallback for new events. */\nfunction humaniseEvent(event: string): string {\n const words = event.replace(/[_-]+/g, ' ').trim()\n return words ? words.charAt(0).toUpperCase() + words.slice(1) : 'Activity'\n}\n","/**\n * ActivityFeed — a presentational, self-fetching list of the current user's\n * durable activity (the to-self \"you opened a workspace / processed a document\"\n * log). Renders each line via the shared {@link describeActivity} descriptor, so\n * the glyph/label knowledge stays in one place and any app (clarum's dashboard,\n * a monolith panel) can drop this in.\n *\n * Pure semantic Tailwind tokens; no store, no app `@/` imports. Data comes from\n * the shared {@link useActivity} query.\n */\n\nimport { Activity } from 'lucide-react'\nimport { useActivity } from '../hooks'\nimport { cn } from '../lib/utils'\nimport { describeActivity } from './activity-types'\n\n/** Relative time like \"just now\", \"3m\", \"2h\", \"5d\"; falls back to a date. */\nfunction formatRelative(iso: string): string {\n const then = new Date(iso).getTime()\n if (Number.isNaN(then)) return ''\n const secs = Math.round((Date.now() - then) / 1000)\n if (secs < 45) return 'just now'\n const mins = Math.round(secs / 60)\n if (mins < 60) return `${mins}m`\n const hours = Math.round(mins / 60)\n if (hours < 24) return `${hours}h`\n const days = Math.round(hours / 24)\n if (days < 7) return `${days}d`\n return new Date(iso).toLocaleDateString()\n}\n\nexport interface ActivityFeedProps {\n /** Max entries to fetch/show. Default 20. */\n limit?: number\n /** Extra classes for the outer container. */\n className?: string\n /** Message shown when there's no activity yet. */\n emptyLabel?: string\n /** Whether to fetch — defaults to enabled when logged in. */\n enabled?: boolean\n 'data-testid'?: string\n}\n\n/**\n * Renders the activity feed. Handles its own loading/empty/error states so a\n * consumer can place it directly (e.g. inside a dashboard card).\n */\nexport function ActivityFeed({\n limit = 20,\n className,\n emptyLabel = 'No recent activity',\n enabled,\n 'data-testid': testId = 'activity-feed',\n}: ActivityFeedProps) {\n const { data, isLoading, isError } = useActivity({ limit, enabled })\n\n if (isLoading) {\n return (\n <div className={cn('space-y-2', className)} data-testid={testId} aria-busy=\"true\">\n {Array.from({ length: 3 }).map((_, i) => (\n <div key={i} className=\"flex items-center gap-3 py-1.5\">\n <div className=\"h-4 w-4 shrink-0 animate-pulse rounded-full bg-muted\" />\n <div className=\"h-3 flex-1 animate-pulse rounded bg-muted\" />\n </div>\n ))}\n </div>\n )\n }\n\n if (isError) {\n return (\n <div className={cn('text-sm text-muted-foreground', className)} data-testid={testId}>\n Couldn’t load activity.\n </div>\n )\n }\n\n const items = data ?? []\n if (items.length === 0) {\n return (\n <div\n className={cn('flex items-center gap-2 text-sm text-muted-foreground', className)}\n data-testid={testId}\n >\n <Activity className=\"h-4 w-4 shrink-0\" />\n <span>{emptyLabel}</span>\n </div>\n )\n }\n\n return (\n <ul className={cn('divide-y divide-border', className)} data-testid={testId}>\n {items.map((item) => {\n const desc = describeActivity(item.content)\n return (\n <li\n key={item.external_id}\n className=\"flex items-center gap-3 py-2\"\n data-testid=\"activity-feed-item\"\n >\n <desc.Icon className={cn('h-4 w-4 shrink-0', desc.iconClassName)} />\n <span className=\"min-w-0 flex-1 truncate text-sm text-foreground\">{desc.title}</span>\n <time className=\"shrink-0 text-xs tabular-nums text-muted-foreground\">\n {formatRelative(item.created_at)}\n </time>\n </li>\n )\n })}\n </ul>\n )\n}\n","/** Small presentation helpers for the DM kit. */\n\nimport type { DmUser } from './types'\n\n/** Initials from a user's name (falls back to the email local-part). */\nexport function userInitials(user: Pick<DmUser, 'given_name' | 'family_name' | 'email'>): string {\n const parts = [user.given_name, user.family_name].filter(Boolean) as string[]\n if (parts.length) {\n return parts\n .map((p) => p[0]?.toUpperCase() ?? '')\n .join('')\n .slice(0, 2)\n }\n const local = user.email?.split('@')[0] ?? ''\n return local.slice(0, 2).toUpperCase() || '?'\n}\n\n/** Full display name (falls back to the email local-part). */\nexport function userDisplayName(\n user: Pick<DmUser, 'given_name' | 'family_name' | 'email'>\n): string {\n const name = [user.given_name, user.family_name].filter(Boolean).join(' ').trim()\n return name || user.email?.split('@')[0] || 'Unknown'\n}\n\n/**\n * Whether a peer is an agent rather than a person.\n *\n * Derived from the `agt-` external-id prefix, which is the platform's own\n * convention and already assumed elsewhere in the kit (entity colours are keyed\n * off the same ids). Deriving it once here is what lets every DM surface mark\n * agents without each consumer having to resolve and pass a flag.\n */\nexport function isAgentUser(user: Pick<DmUser, 'external_id'>): boolean {\n return user.external_id.startsWith('agt-')\n}\n\nexport { formatRelativeTime } from '../lib/format-relative-time'\n","/**\n * useDirectMessages — the data layer for the DM block kit.\n *\n * Sits entirely on top of the SDK's encrypted-by-default `arbi.dm` surface:\n * it never touches `/v1/notifications` or crypto directly. It lists decrypted\n * DMs, groups them into per-peer conversations, refreshes live over the shared\n * WebSocket, and exposes send / mark-read mutations.\n *\n * Requires an <ArbiWebSocketProvider> above it for live updates (standard in\n * the ARBI provider stack).\n */\n\nimport { useEffect, useMemo, useState } from 'react'\nimport { useQuery, useMutation, useQueryClient } from '@tanstack/react-query'\nimport type { WsNotificationResponse } from '@arbidocs/client'\nimport { useArbi } from '../useArbi'\nimport { useArbiWsMessage } from '../websocket'\nimport { userDisplayName } from './utils'\nimport type { DmConversation, DmMessage, DmNotification, DmUser } from './types'\n\nconst DM_QUERY_KEY = ['arbi', 'directMessages'] as const\nconst CONTACTS_QUERY_KEY = ['arbi', 'contacts'] as const\n\n/**\n * Merge the user's contacts into the thread list so every colleague appears in\n * the rail — those with history keep their thread, those without show as an\n * empty conversation ready to start. Contacts still pending sign-up (no linked\n * user) are skipped. Threads with a peer who isn't a contact (e.g. an agent you\n * were added to) are preserved.\n */\nfunction mergeContacts(\n threads: DmConversation[],\n contacts: { user?: DmUser | null }[]\n): DmConversation[] {\n const byPeer = new Map<string, DmConversation>()\n for (const t of threads) byPeer.set(t.peer.external_id, t)\n\n for (const c of contacts) {\n const peer = c.user\n if (!peer?.external_id || byPeer.has(peer.external_id)) continue\n byPeer.set(peer.external_id, { peer, messages: [], unreadCount: 0, isContactOnly: true })\n }\n\n // Threads with activity first (most recent), then message-less contacts A→Z.\n return [...byPeer.values()].sort((a, b) => {\n const at = a.lastMessage?.createdAt\n const bt = b.lastMessage?.createdAt\n if (at && bt) return bt.localeCompare(at)\n if (at) return -1\n if (bt) return 1\n return userDisplayName(a.peer).localeCompare(userDisplayName(b.peer))\n })\n}\n\n/** Group a flat, decrypted DM list into per-peer conversations. */\nfunction groupConversations(\n notifications: DmNotification[],\n myExtId: string | null\n): DmConversation[] {\n const messagesByPeer = new Map<string, DmMessage[]>()\n const peers = new Map<string, DmUser>()\n\n for (const n of notifications) {\n if (n.type !== 'user_message') continue\n // Skip self-notifications (sender == recipient == me): not a real thread.\n if (n.sender.external_id === n.recipient.external_id) continue\n\n const isMine = n.sender.external_id === myExtId\n const peer = isMine ? n.recipient : n.sender\n if (!peer?.external_id) continue\n\n const message: DmMessage = {\n externalId: n.external_id,\n body: n.content ?? '',\n createdAt: n.created_at,\n isMine,\n read: n.read,\n sender: n.sender,\n recipient: n.recipient,\n }\n\n if (!messagesByPeer.has(peer.external_id)) {\n messagesByPeer.set(peer.external_id, [])\n peers.set(peer.external_id, peer)\n }\n messagesByPeer.get(peer.external_id)!.push(message)\n }\n\n const conversations: DmConversation[] = []\n for (const [peerId, messages] of messagesByPeer) {\n messages.sort((a, b) => a.createdAt.localeCompare(b.createdAt))\n const unreadCount = messages.filter((m) => !m.isMine && !m.read).length\n conversations.push({\n peer: peers.get(peerId)!,\n messages,\n lastMessage: messages[messages.length - 1],\n unreadCount,\n })\n }\n // Most recently active conversations first.\n // Every conversation built here has messages, so lastMessage is always set.\n conversations.sort((a, b) => b.lastMessage!.createdAt.localeCompare(a.lastMessage!.createdAt))\n return conversations\n}\n\nexport interface UseDirectMessagesResult {\n /** Per-peer conversations, most recently active first. */\n conversations: DmConversation[]\n /** The current user's external_id (for ownership checks), or null if unknown. */\n myExtId: string | null\n isLoading: boolean\n isError: boolean\n error: unknown\n refetch: () => void\n /** Send a message to a known peer (extId + public key from a conversation). */\n sendMessage: (\n recipientExtId: string,\n recipientPublicKey: string,\n text: string\n ) => Promise<unknown>\n /** Send by email / external_id, resolving the recipient's key internally. */\n sendMessageTo: (recipient: string, text: string) => Promise<unknown>\n isSending: boolean\n /** The last send failure, or null. A failed send must never pass silently. */\n sendError: Error | null\n /** Mark the given message ids as read. */\n markRead: (messageIds: string[]) => Promise<unknown>\n}\n\nexport function useDirectMessages(options?: { enabled?: boolean }): UseDirectMessagesResult {\n const arbi = useArbi()\n const queryClient = useQueryClient()\n const enabled = options?.enabled ?? arbi.isLoggedIn\n\n const query = useQuery({\n queryKey: DM_QUERY_KEY,\n queryFn: () => arbi.dm.list(),\n enabled,\n })\n\n // Contacts drive the rail: every colleague shows, with or without history.\n const contactsQuery = useQuery({\n queryKey: CONTACTS_QUERY_KEY,\n queryFn: () => arbi.contacts.list(),\n enabled,\n })\n\n // Live: a new DM arrives as a `user_message` notification over the socket.\n useArbiWsMessage<WsNotificationResponse>('user_message', () => {\n queryClient.invalidateQueries({ queryKey: DM_QUERY_KEY })\n })\n\n // Read straight from the session on every render rather than memoising: it is a\n // cheap synchronous lookup, and a stale `null` here would misfile every message\n // we sent (`isMine` false → the message lands in a thread keyed by ourselves).\n let myExtId: string | null = null\n try {\n myExtId = arbi.user.identity()?.externalId ?? null\n } catch {\n myExtId = null\n }\n\n // Messages this session has sent, held until the server's own list reports\n // them back. Writing them into the query cache instead would not survive the\n // refetch that follows the send: `GET /v1/notifications/` is eventually\n // consistent, so a refetch that lands before the write propagates would\n // overwrite the cache and the message would vanish out of the open thread.\n const [pendingSent, setPendingSent] = useState<DmNotification[]>([])\n\n const serverIds = useMemo(\n () => new Set((query.data ?? []).map((n) => n.external_id)),\n [query.data]\n )\n\n // Drop each pending send the moment the server acknowledges it, so the two\n // copies can never both be rendered.\n useEffect(() => {\n setPendingSent((pending) =>\n pending.some((n) => serverIds.has(n.external_id))\n ? pending.filter((n) => !serverIds.has(n.external_id))\n : pending\n )\n }, [serverIds])\n\n const conversations = useMemo(() => {\n // Newest first, matching the server's ordering.\n const all = [...pendingSent.filter((n) => !serverIds.has(n.external_id)), ...(query.data ?? [])]\n return mergeContacts(groupConversations(all, myExtId), contactsQuery.data ?? [])\n }, [query.data, serverIds, pendingSent, contactsQuery.data, myExtId])\n\n const invalidate = () => queryClient.invalidateQueries({ queryKey: DM_QUERY_KEY })\n\n /**\n * Hold on to the notifications the send just created, then reconcile with the\n * server. The SDK hands them back already decrypted, so a sent message renders\n * immediately and never depends on a second network round-trip (or on\n * re-decrypting our own ciphertext) to become visible.\n */\n const absorbSent = (created: DmNotification[]) => {\n setPendingSent((pending) => [...created, ...pending])\n invalidate()\n }\n\n const sendMutation = useMutation({\n mutationFn: (vars: { recipientExtId: string; recipientPublicKey: string; text: string }) =>\n arbi.dm.sendTo(vars.recipientExtId, vars.recipientPublicKey, vars.text),\n onSuccess: absorbSent,\n })\n\n const sendToMutation = useMutation({\n mutationFn: (vars: { recipient: string; text: string }) =>\n arbi.dm.send(vars.recipient, vars.text),\n onSuccess: absorbSent,\n })\n\n const markReadMutation = useMutation({\n mutationFn: (messageIds: string[]) => arbi.dm.markRead(messageIds),\n onSuccess: invalidate,\n })\n\n return {\n conversations,\n myExtId,\n isLoading: (query.isLoading || contactsQuery.isLoading) && enabled,\n isError: query.isError,\n error: query.error,\n refetch: () => query.refetch(),\n sendMessage: (recipientExtId, recipientPublicKey, text) =>\n sendMutation.mutateAsync({ recipientExtId, recipientPublicKey, text }),\n sendMessageTo: (recipient, text) => sendToMutation.mutateAsync({ recipient, text }),\n isSending: sendMutation.isPending || sendToMutation.isPending,\n sendError: sendMutation.error ?? sendToMutation.error,\n markRead: (messageIds) => markReadMutation.mutateAsync(messageIds),\n }\n}\n","/**\n * A peer avatar in a DM surface.\n *\n * This used to be its own small avatar that knew nothing about agents or\n * presence, which is why the ARBI app replaced it on every row with a\n * hand-rolled variant of its own. It is now a thin adapter over\n * {@link UserEntity} — the one presentational person component — so a DM row, a\n * members table and a document owner all draw a person the same way.\n *\n * The name and props are unchanged: it is exported from the package, and\n * consumers should not have to care that the implementation collapsed.\n */\n\nimport { UserEntity, type PresenceDisplayStatus } from '../entities/UserEntity'\nimport { getEntityColorStyles } from '../entities/colors'\nimport { useArbiWsStore } from '../websocket/store'\nimport type { DmUser } from './types'\nimport { userDisplayName, userInitials, isAgentUser } from './utils'\n\nexport interface DmAvatarProps {\n user: DmUser\n className?: string\n /** Defaults to the 40px row avatar this component has always drawn. */\n size?: 'xs' | 'sm' | 'md' | 'lg'\n}\n\nexport function DmAvatar({ user, className, size = 'lg' }: DmAvatarProps) {\n // Presence comes from the shared WS store, which stays empty until an app\n // mounts ArbiWebSocketProvider. That is deliberate: with no socket we know\n // nothing about who is online, and `undefined` hides the dot rather than\n // asserting that everyone is offline.\n const presence = useArbiWsStore((s) => s.presence[user.external_id])\n const displayStatus: PresenceDisplayStatus | undefined =\n presence === undefined ? undefined : presence === 'online' ? 'connected' : 'disconnected'\n\n return (\n <UserEntity\n variant=\"icon\"\n size={size}\n className={className}\n interactive={false}\n showTooltip={false}\n initials={userInitials(user)}\n displayName={userDisplayName(user)}\n picture={user.picture}\n // Deterministic tint from the user's id so the fallback is stable + distinct.\n avatarStyle={getEntityColorStyles(user.external_id)}\n isAgent={isAgentUser(user)}\n displayStatus={displayStatus}\n />\n )\n}\n","/**\n * The left rail: a scrollable list of 1:1 conversations, each showing the peer\n * avatar, name, last-message preview, relative time, and an unread pill.\n */\n\nimport { Check, CheckCheck } from 'lucide-react'\nimport { Badge } from '../ui/badge'\nimport { cn } from '../lib/utils'\nimport type { DmClassNames, DmConversation } from './types'\nimport { formatRelativeTime, userDisplayName, isAgentUser } from './utils'\nimport { DmAvatar } from './DmAvatar'\nimport { AgentBadge } from '../entities/AgentMarkers'\n\nexport interface ConversationListProps {\n conversations: DmConversation[]\n selectedPeerId: string | null\n onSelect: (peerId: string) => void\n classNames?: Pick<DmClassNames, 'unreadBadge'>\n /** Rendered when there are no conversations. */\n emptyState?: React.ReactNode\n /**\n * Replaces the default \"Conversations / N colleagues\" heading — e.g. with a\n * call to action. Pass `null` for no heading at all.\n */\n header?: React.ReactNode\n /**\n * Overrides the rail's own sizing. The default is a fixed-width column beside\n * a thread; a consumer showing the list on its own needs it to fill instead,\n * and cannot get there by wrapping (a narrower wrapper clips rather than\n * shrinks).\n */\n className?: string\n}\n\nexport function ConversationList({\n conversations,\n selectedPeerId,\n onSelect,\n classNames,\n emptyState,\n header,\n className,\n}: ConversationListProps) {\n return (\n <aside\n className={cn(\n 'flex min-h-0 flex-col border-b border-border md:w-80 md:shrink-0 md:border-b-0 md:border-r',\n className\n )}\n data-testid=\"arbi-dm-list\"\n >\n {header === undefined ? (\n <div className=\"border-b border-border px-4 py-3\">\n <p className=\"text-sm font-semibold text-foreground\">Conversations</p>\n <p className=\"text-xs text-muted-foreground\">\n {conversations.length} {conversations.length === 1 ? 'colleague' : 'colleagues'}\n </p>\n </div>\n ) : (\n header\n )}\n <div className=\"min-h-0 flex-1 overflow-y-auto\">\n {conversations.length === 0 ? (\n <div className=\"px-4 py-6 text-xs text-muted-foreground\">\n {emptyState ?? 'No conversations yet.'}\n </div>\n ) : (\n <ul className=\"w-full\">\n {conversations.map((c, i) => {\n const { peer, lastMessage, unreadCount } = c\n // The heading renders once, above the first row of its group.\n const newSection =\n c.sectionLabel && c.sectionLabel !== conversations[i - 1]?.sectionLabel\n const active = peer.external_id === selectedPeerId\n const preview = lastMessage?.body ?? 'No messages yet — say hello'\n // Unread rows carry weight, which is the signal you catch scanning\n // a list — the count alone is a detail you have to go looking for.\n const unread = unreadCount > 0\n const body = (\n <>\n {c.leading ?? <DmAvatar user={peer} />}\n <div className=\"min-w-0 flex-1\">\n {/* Count sits with the name; the time sits with the message\n it belongs to. They were the other way round, which put\n \"just now\" beside a name it said nothing about. */}\n <div className=\"flex items-center justify-between gap-2\">\n <span className=\"flex min-w-0 items-center gap-1.5\">\n <span\n className={cn(\n 'truncate text-sm text-foreground',\n unread ? 'font-bold' : 'font-semibold'\n )}\n >\n {userDisplayName(peer)}\n </span>\n {/* An agent is marked by default — a consumer only\n supplies `badge` to say something else. */}\n {c.badge ?? (isAgentUser(peer) ? <AgentBadge /> : null)}\n </span>\n {c.statusLabel ? (\n <Badge\n variant=\"outline\"\n className=\"shrink-0 rounded-full px-2 py-0 text-xs font-medium text-muted-foreground\"\n >\n {c.statusLabel}\n </Badge>\n ) : unreadCount > 0 ? (\n // Quiet by default: a filled brand pill with a shadow\n // shouted louder than the message it was counting.\n // Enough to catch the eye scanning the list, no more.\n <Badge\n variant=\"accent\"\n className={cn(\n 'min-w-[1.125rem] justify-center rounded-full px-1 py-0 text-xs font-medium leading-[1.125rem] shadow-none',\n classNames?.unreadBadge\n )}\n >\n {unreadCount}\n </Badge>\n ) : null}\n </div>\n <div className=\"mt-1 flex items-center gap-1.5\">\n {/* Your own last message is marked with the same tick the\n bubble carries — one delivered, two read. It says who\n spoke last AND whether it landed, which a \"You:\" prefix\n cannot, and costs no preview width. */}\n {lastMessage?.isMine ? (\n lastMessage.read ? (\n <CheckCheck\n className=\"size-3.5 shrink-0 text-ai-accent\"\n aria-label=\"Read\"\n />\n ) : (\n <Check\n className=\"size-3.5 shrink-0 text-muted-foreground\"\n aria-label=\"Sent\"\n />\n )\n ) : null}\n <p\n className={cn(\n 'min-w-0 flex-1 truncate text-xs',\n unread ? 'font-medium text-foreground' : 'text-muted-foreground'\n )}\n >\n {c.subtitle ?? preview}\n </p>\n <span className=\"shrink-0 text-xs text-muted-foreground\">\n {lastMessage ? formatRelativeTime(lastMessage.createdAt) : ''}\n </span>\n </div>\n </div>\n </>\n )\n\n // An invitation that nobody has accepted has no thread to open, so\n // it is listed but not offered as something to click.\n const rowClass = cn(\n // Each row is its own opaque surface. Left transparent it takes\n // the panel's colour, and the chips stop reading as cards at all\n // — which is the whole point of them.\n 'flex w-full items-start gap-3 border-b border-border/60 bg-card px-4 py-3 text-left transition-colors',\n c.disabled ? 'cursor-default' : active ? 'bg-ai-accent-soft' : 'hover:bg-accent/40'\n )\n\n return (\n <li key={peer.external_id}>\n {newSection && (\n <p\n className=\"bg-muted/40 px-4 py-1.5 text-xs font-medium uppercase tracking-wide text-muted-foreground\"\n data-testid=\"arbi-dm-section\"\n >\n {c.sectionLabel}\n </p>\n )}\n {c.disabled ? (\n <div\n data-testid={`arbi-dm-conversation-${peer.external_id}`}\n className={rowClass}\n >\n {body}\n {c.trailing}\n </div>\n ) : (\n <button\n type=\"button\"\n onClick={() => onSelect(peer.external_id)}\n data-testid={`arbi-dm-conversation-${peer.external_id}`}\n className={rowClass}\n >\n {body}\n </button>\n )}\n </li>\n )\n })}\n </ul>\n )}\n </div>\n </aside>\n )\n}\n","/**\n * Thread grouping: the two annotations a readable message list needs.\n *\n * A run is a burst from one sender close together in time; only its last\n * message carries the meta row (sender, time, receipt), so ten rapid messages\n * read as one block instead of ten stamped rows. A day boundary gets a\n * separator so a thread spanning weeks stays navigable.\n *\n * Generic over the message shape because the two consumers hold different ones —\n * the block's `DmMessage` and the ARBI app's decrypted notification rows — and\n * duplicating this logic is exactly how they drifted apart before.\n */\n\n/** Two messages belong to the same run when same sender and within this gap. */\nexport const RUN_WINDOW_MS = 2 * 60 * 1000\n\nexport interface ThreadItem<T> {\n message: T\n /** Last of a same-sender run: render the meta row here. */\n isLastOfRun: boolean\n /** First message on its calendar day: render a date separator above it. */\n isFirstOfDay: boolean\n}\n\nexport interface ThreadAccessors<T> {\n senderId: (message: T) => string\n createdAt: (message: T) => string\n}\n\n/**\n * Local calendar day for a timestamp.\n *\n * Deliberately local rather than UTC: a message sent at 23:30 in the reader's\n * zone belongs under that day's separator, not tomorrow's. Falls back to the\n * raw string for an unparseable timestamp so such a message still buckets\n * consistently with itself rather than joining an arbitrary day.\n */\nexport function dayKey(iso: string): string {\n const d = new Date(iso)\n if (Number.isNaN(d.getTime())) return iso\n return `${d.getFullYear()}-${d.getMonth() + 1}-${d.getDate()}`\n}\n\n/** Annotate messages (ascending time order) with run and day boundaries. */\nexport function annotateThread<T>(\n messages: T[],\n accessors: ThreadAccessors<T>,\n runWindowMs: number = RUN_WINDOW_MS\n): ThreadItem<T>[] {\n const { senderId, createdAt } = accessors\n return messages.map((message, i) => {\n const next = messages[i + 1]\n const prev = messages[i - 1]\n const day = dayKey(createdAt(message))\n\n const continuesIntoNext =\n !!next &&\n senderId(next) === senderId(message) &&\n dayKey(createdAt(next)) === day &&\n Date.parse(createdAt(next)) - Date.parse(createdAt(message)) < runWindowMs\n\n return {\n message,\n isLastOfRun: !continuesIntoNext,\n isFirstOfDay: !prev || dayKey(createdAt(prev)) !== day,\n }\n })\n}\n","/**\n * The day divider between message runs in a thread.\n *\n * The label is supplied by the caller rather than formatted here: the ARBI app\n * has a friendly formatter that already says \"Today\" / \"Yesterday\" in the user's\n * locale, and a second date-formatting opinion in the kit would drift from it.\n */\n\nimport type { ReactNode } from 'react'\n\nexport interface DateSeparatorProps {\n children: ReactNode\n}\n\nexport function DateSeparator({ children }: DateSeparatorProps) {\n return (\n <div className=\"my-3 flex justify-center\" data-testid=\"dm-date-separator\">\n <span className=\"rounded-full bg-background/80 px-2 py-0.5 text-xs text-muted-foreground\">\n {children}\n </span>\n </div>\n )\n}\n","/**\n * A single message row in a DM thread.\n *\n * This is an adapter, not a second bubble: it maps a `DmMessage` onto the shared\n * <ChatBubble>, which is the one implementation behind both this block and the\n * ARBI app's thread. The two used to be separate components for the same object\n * and had drifted apart — this one had the softer look and the brand slots, the\n * other had delete, read receipts and same-sender run grouping. Every consumer\n * now gets all of it.\n */\n\nimport { ChatBubble } from '../chat/ChatBubble'\nimport type { DmClassNames, DmMessage } from './types'\nimport { formatRelativeTime, userDisplayName } from './utils'\n\nexport interface MessageBubbleProps {\n message: DmMessage\n classNames?: Pick<DmClassNames, 'ownBubble' | 'peerBubble'>\n /**\n * False when the next message is from the same sender in the same run, which\n * suppresses the meta row so a burst reads as one block. Defaults to true —\n * every message carries its own sender, time and receipt.\n */\n isLastOfRun?: boolean\n /** Deletes this message. Omit to hide the affordance. */\n onDelete?: () => void\n /** Renders the tombstone in place of the body. */\n deleted?: boolean\n}\n\nexport function MessageBubble({\n message,\n classNames,\n isLastOfRun = true,\n onDelete,\n deleted,\n}: MessageBubbleProps) {\n return (\n <ChatBubble\n data-testid=\"arbi-dm-message\"\n message={message.body}\n timestamp={message.createdAt}\n isSent={message.isMine}\n read={message.read}\n deleted={deleted}\n onDelete={onDelete}\n isLastOfRun={isLastOfRun}\n senderName={message.isMine ? 'You' : userDisplayName(message.sender)}\n classNames={classNames}\n formatTimestamp={formatRelativeTime}\n />\n )\n}\n","/**\n * The open conversation: a peer header, a scrolling message list (auto-scrolled\n * to the newest), and — when no peer is selected — an empty state.\n */\n\nimport { Fragment, useEffect, useMemo, useRef } from 'react'\nimport { MessagesSquare } from 'lucide-react'\nimport { ScrollArea } from '../ui/scroll-area'\nimport type { DmClassNames, DmConversation, DmMessage } from './types'\nimport { userDisplayName } from './utils'\nimport { annotateThread } from './grouping'\nimport { DateSeparator } from './DateSeparator'\nimport { DmAvatar } from './DmAvatar'\nimport { MessageBubble } from './MessageBubble'\n\nexport interface MessageThreadProps {\n conversation: DmConversation | null\n classNames?: Pick<DmClassNames, 'ownBubble' | 'peerBubble'>\n emptyState?: React.ReactNode\n /**\n * Label for a day divider. Omit to leave the thread undivided — the kit does\n * not format dates itself (see DateSeparator).\n */\n formatDay?: (iso: string) => string\n /** Deletes a message. Omit to hide the affordance. */\n onDeleteMessage?: (message: DmMessage) => void\n /** External ids of messages already deleted, rendered as tombstones. */\n deletedIds?: ReadonlySet<string>\n}\n\nconst THREAD_ACCESSORS = {\n senderId: (m: DmMessage) => m.sender.external_id,\n createdAt: (m: DmMessage) => m.createdAt,\n}\n\nexport function MessageThread({\n conversation,\n classNames,\n emptyState,\n formatDay,\n onDeleteMessage,\n deletedIds,\n}: MessageThreadProps) {\n const bottomRef = useRef<HTMLDivElement>(null)\n\n const items = useMemo(\n () => annotateThread(conversation?.messages ?? [], THREAD_ACCESSORS),\n [conversation?.messages]\n )\n\n useEffect(() => {\n bottomRef.current?.scrollIntoView({ block: 'end' })\n }, [conversation?.peer.external_id, conversation?.messages.length])\n\n if (!conversation) {\n return (\n <section className=\"flex min-h-0 flex-1 flex-col items-center justify-center gap-3 p-8 text-center\">\n {emptyState ?? (\n <>\n <div className=\"flex size-14 items-center justify-center rounded-full bg-accent\">\n <MessagesSquare className=\"size-6 text-muted-foreground\" />\n </div>\n <div>\n <p className=\"text-sm font-semibold text-foreground\">No conversation selected</p>\n <p className=\"mx-auto mt-1 max-w-xs text-xs text-muted-foreground\">\n Choose a colleague from the list to read the thread and send a direct message.\n </p>\n </div>\n </>\n )}\n </section>\n )\n }\n\n const { peer } = conversation\n\n return (\n <>\n <header className=\"flex items-center gap-3 border-b border-border px-4 py-3\">\n <DmAvatar user={peer} className=\"size-9\" />\n <div className=\"min-w-0\">\n <p className=\"truncate text-sm font-semibold text-foreground\">{userDisplayName(peer)}</p>\n <p className=\"truncate text-xs text-muted-foreground\">{peer.email}</p>\n </div>\n </header>\n\n <ScrollArea className=\"min-h-0 flex-1 bg-background\">\n {/* No `gap` here: spacing is the bubble's job now, so a mid-run message\n can sit tight against the one before it and a run reads as a block. */}\n <div className=\"flex flex-col px-4 py-4\" data-testid=\"arbi-dm-thread\">\n {items.map(({ message: m, isLastOfRun, isFirstOfDay }) => (\n <Fragment key={m.externalId}>\n {isFirstOfDay && formatDay && <DateSeparator>{formatDay(m.createdAt)}</DateSeparator>}\n <MessageBubble\n message={m}\n classNames={classNames}\n isLastOfRun={isLastOfRun}\n deleted={deletedIds?.has(m.externalId)}\n onDelete={onDeleteMessage ? () => onDeleteMessage(m) : undefined}\n />\n </Fragment>\n ))}\n <div ref={bottomRef} />\n </div>\n </ScrollArea>\n </>\n )\n}\n","/**\n * The message composer: an auto-sizing textarea + send button. Enter sends,\n * Shift+Enter inserts a newline.\n */\n\nimport { useRef, useState } from 'react'\nimport { Loader2, Send } from 'lucide-react'\nimport { Button } from '../ui/button'\nimport { Textarea } from '../ui/textarea'\nimport { cn } from '../lib/utils'\nimport type { DmClassNames } from './types'\n\nexport interface DmComposerProps {\n /** Placeholder, e.g. \"Message Eleanor…\". */\n placeholder?: string\n disabled?: boolean\n /**\n * A send is in flight: swaps the icon for a spinner and blocks a second\n * submit, so a slow encrypt-and-post can't be fired twice by an impatient\n * Enter.\n */\n busy?: boolean\n /** Called with the trimmed text when the user sends. May reject if the send fails. */\n onSend: (text: string) => void | Promise<void>\n /** Shown under the box when the last send failed. */\n error?: string | null\n /** Extra content between the box and the border (e.g. a peer-specific action). */\n children?: React.ReactNode\n classNames?: Pick<DmClassNames, 'sendButton'>\n}\n\nexport function DmComposer({\n placeholder,\n disabled,\n busy,\n onSend,\n error,\n children,\n classNames,\n}: DmComposerProps) {\n const [draft, setDraft] = useState('')\n const inputRef = useRef<HTMLTextAreaElement>(null)\n\n const submit = async () => {\n const text = draft.trim()\n if (!text || disabled || busy) return\n setDraft('')\n try {\n await onSend(text)\n // Keep the caret in the box so a reply can follow straight on.\n inputRef.current?.focus()\n } catch {\n // The send failed (the error surfaces via `error`) — give the text back\n // rather than losing what the user typed.\n setDraft(text)\n }\n }\n\n const onKeyDown = (e: React.KeyboardEvent<HTMLTextAreaElement>) => {\n if (e.key === 'Enter' && !e.shiftKey) {\n e.preventDefault()\n void submit()\n }\n }\n\n return (\n <div className=\"border-t border-border p-3\">\n {children}\n <div className=\"flex items-end gap-2\">\n <Textarea\n ref={inputRef}\n value={draft}\n onChange={(e) => setDraft(e.target.value)}\n onKeyDown={onKeyDown}\n placeholder={placeholder}\n rows={1}\n disabled={disabled}\n className=\"max-h-40 min-h-[44px] resize-none\"\n data-testid=\"arbi-dm-input\"\n />\n <Button\n type=\"button\"\n onClick={() => void submit()}\n disabled={disabled || busy || !draft.trim()}\n className={cn(classNames?.sendButton)}\n data-testid=\"arbi-dm-send\"\n aria-label=\"Send message\"\n >\n {busy ? <Loader2 className=\"size-4 animate-spin\" /> : <Send className=\"size-4\" />} Send\n </Button>\n </div>\n {error && (\n <p className=\"mt-2 text-xs text-destructive\" data-testid=\"arbi-dm-error\">\n {error}\n </p>\n )}\n </div>\n )\n}\n","/**\n * DirectMessages — the turnkey DM block.\n *\n * A two-column messenger (conversation rail + open thread + composer) wired to\n * the real, E2E-encrypted DM backend via `useDirectMessages`. Drop it in under\n * an ArbiProvider + ArbiWebSocketProvider and it lists, opens, marks-read and\n * sends real messages. Brand accents are themed via the `classNames` slots.\n */\n\nimport { useEffect, useMemo, useState } from 'react'\nimport { cn } from '../lib/utils'\nimport type { DmClassNames } from './types'\nimport { userDisplayName } from './utils'\nimport { useDirectMessages } from './useDirectMessages'\nimport { ConversationList } from './ConversationList'\nimport { MessageThread } from './MessageThread'\nimport { DmComposer } from './DmComposer'\n\nexport interface DirectMessagesProps {\n /** Extra classes for the outer card (e.g. a page-specific height). */\n className?: string\n /** Per-slot brand overrides (own bubble, unread pill, send button…). */\n classNames?: DmClassNames\n /** Rendered in the thread pane when no conversation is selected. */\n emptyThread?: React.ReactNode\n /** Rendered in the rail when there are no conversations. */\n emptyList?: React.ReactNode\n}\n\nexport function DirectMessages({\n className,\n classNames,\n emptyThread,\n emptyList,\n}: DirectMessagesProps) {\n const {\n conversations,\n isLoading,\n isError,\n error,\n sendMessage,\n sendMessageTo,\n sendError,\n markRead,\n } = useDirectMessages()\n const [selectedPeerId, setSelectedPeerId] = useState<string | null>(null)\n\n // The contacts rail renders even when the message list fails, so without this\n // a failed load looks exactly like an empty inbox.\n const loadError = isError\n ? error instanceof Error\n ? error.message\n : 'Couldn’t load messages.'\n : null\n\n const selected = useMemo(\n () => conversations.find((c) => c.peer.external_id === selectedPeerId) ?? null,\n [conversations, selectedPeerId]\n )\n\n // Mark a conversation's inbound messages read once it's open.\n useEffect(() => {\n if (!selected || selected.unreadCount === 0) return\n const unreadIds = selected.messages.filter((m) => !m.isMine && !m.read).map((m) => m.externalId)\n if (unreadIds.length) void markRead(unreadIds)\n // eslint-disable-next-line react-hooks/exhaustive-deps\n }, [selected?.peer.external_id, selected?.unreadCount])\n\n const handleSend = async (text: string) => {\n if (!selected) return\n // Existing threads carry the peer's public key; a contact opened fresh may\n // not, so fall back to resolve-by-id (the SDK looks the key up internally).\n // A rejection here (e.g. an unresolvable recipient) lands in `sendError`,\n // which the composer surfaces — a send must never fail invisibly.\n if (selected.peer.encryption_public_key) {\n await sendMessage(selected.peer.external_id, selected.peer.encryption_public_key, text)\n } else {\n await sendMessageTo(selected.peer.external_id, text)\n }\n }\n\n return (\n <div\n data-testid=\"arbi-dm\"\n style={{ height: 'calc(100vh - 16rem)', minHeight: '28rem' }}\n className={cn(\n 'relative flex flex-col overflow-hidden rounded-xl border border-border bg-card md:flex-row',\n className\n )}\n >\n {loadError && (\n <p\n data-testid=\"arbi-dm-load-error\"\n className=\"absolute inset-x-0 top-0 z-10 bg-destructive/10 px-3 py-2 text-center text-xs text-destructive\"\n >\n {loadError}\n </p>\n )}\n <ConversationList\n conversations={conversations}\n selectedPeerId={selected?.peer.external_id ?? null}\n onSelect={setSelectedPeerId}\n classNames={classNames}\n emptyState={isLoading ? 'Loading messages…' : emptyList}\n />\n <div className=\"flex min-h-0 min-w-0 flex-1 flex-col\">\n <MessageThread conversation={selected} classNames={classNames} emptyState={emptyThread} />\n {selected ? (\n <DmComposer\n placeholder={`Message ${userDisplayName(selected.peer).split(' ')[0]}…`}\n onSend={handleSend}\n error={sendError?.message ?? null}\n classNames={classNames}\n />\n ) : null}\n </div>\n </div>\n )\n}\n","/**\n * ImageCropper — a themeable pan/zoom crop surface (react-easy-crop) with an\n * optional aspect-ratio picker. Reports the chosen crop rectangle (in source\n * pixels) via `onCropComplete`; pair it with {@link cropImage} to export.\n *\n * react-easy-crop always constrains to a fixed aspect (you move the image under\n * a fixed frame), so \"change the aspect ratio\" is a discrete ratio picker, not\n * free-form rectangle dragging.\n */\n\nimport { useCallback, useEffect, useState } from 'react'\nimport Cropper, { type Area } from 'react-easy-crop'\nimport { Slider } from '../ui/slider'\nimport { cn } from '../lib/utils'\nimport type { CropArea } from './cropImage'\n\n/** A selectable aspect ratio (width / height). */\nexport interface AspectOption {\n label: string\n value: number\n}\n\n/** A sensible default ratio set (square, landscape, portrait, wide, tall). */\nexport const DEFAULT_ASPECT_OPTIONS: AspectOption[] = [\n { label: '1:1', value: 1 },\n { label: '4:3', value: 4 / 3 },\n { label: '3:4', value: 3 / 4 },\n { label: '16:9', value: 16 / 9 },\n { label: '9:16', value: 9 / 16 },\n]\n\nexport interface ImageCropperProps {\n image: string\n /** Fixed aspect ratio (w/h). Default 1. Ignored once the user picks from `aspectOptions`. */\n aspect?: number\n /** Show a ratio picker with these options (first is the initial selection). */\n aspectOptions?: AspectOption[]\n cropShape?: 'rect' | 'round'\n minZoom?: number\n maxZoom?: number\n className?: string\n /** The crop rectangle (source pixels) + the active aspect, on every change. */\n onCropComplete?: (area: CropArea, aspect: number) => void\n}\n\nexport function ImageCropper({\n image,\n aspect = 1,\n aspectOptions,\n cropShape = 'rect',\n minZoom = 1,\n maxZoom = 3,\n className,\n onCropComplete,\n}: ImageCropperProps) {\n const [crop, setCrop] = useState({ x: 0, y: 0 })\n const [zoom, setZoom] = useState(1)\n const [activeAspect, setActiveAspect] = useState(aspectOptions?.[0]?.value ?? aspect)\n\n // Keep the reported aspect in sync when the caller changes the fixed `aspect`.\n useEffect(() => {\n if (!aspectOptions) setActiveAspect(aspect)\n }, [aspect, aspectOptions])\n\n const handleComplete = useCallback(\n (_: Area, areaPixels: Area) => {\n onCropComplete?.(areaPixels, activeAspect)\n },\n [onCropComplete, activeAspect]\n )\n\n return (\n <div className={cn('flex flex-col gap-3', className)}>\n <div className=\"relative h-72 w-full overflow-hidden rounded-md bg-foreground/95\">\n <Cropper\n image={image}\n crop={crop}\n zoom={zoom}\n aspect={activeAspect}\n cropShape={cropShape}\n showGrid={cropShape === 'rect'}\n onCropChange={setCrop}\n onZoomChange={setZoom}\n onCropComplete={handleComplete}\n objectFit=\"contain\"\n />\n </div>\n\n {aspectOptions && aspectOptions.length > 1 ? (\n <div className=\"flex flex-wrap items-center gap-1\" data-testid=\"image-cropper-aspects\">\n <span className=\"mr-1 text-xs font-semibold uppercase tracking-wider text-muted-foreground\">\n Ratio\n </span>\n {aspectOptions.map((opt) => {\n const on = opt.value === activeAspect\n return (\n <button\n key={opt.label}\n type=\"button\"\n onClick={() => setActiveAspect(opt.value)}\n data-testid={`image-cropper-aspect-${opt.label}`}\n className={cn(\n 'rounded-md px-2 py-1 text-xs font-medium transition-colors',\n on\n ? 'bg-primary text-primary-foreground'\n : 'text-muted-foreground hover:bg-accent hover:text-foreground'\n )}\n >\n {opt.label}\n </button>\n )\n })}\n </div>\n ) : null}\n\n <div className=\"space-y-1.5\">\n <label className=\"text-xs font-semibold uppercase tracking-wider text-muted-foreground\">\n Zoom\n </label>\n <Slider\n value={[zoom]}\n onValueChange={([v]) => setZoom(v ?? 1)}\n min={minZoom}\n max={maxZoom}\n step={0.01}\n />\n </div>\n </div>\n )\n}\n","/**\n * Crop a region of an image to a canvas and export it — the shared engine\n * behind every \"frame this image\" surface (avatars, builder image fields, …).\n *\n * `area` is the pixel rectangle react-easy-crop reports (`onCropComplete`'s\n * second arg). Output is rectangular (a round crop is a UI overlay only — JPEG\n * has no alpha), optionally downscaled so the longest edge fits `maxSize`.\n */\n\n/** Pixel crop rectangle in the source image's natural coordinates. */\nexport interface CropArea {\n x: number\n y: number\n width: number\n height: number\n}\n\nexport interface CropOutput {\n /** Cap the longest output edge to this many px (preserves aspect). Omit = native crop size. */\n maxSize?: number\n /** Output MIME type. Default `image/jpeg`. */\n mimeType?: string\n /** Quality for lossy formats, 0..1. Default 0.9. */\n quality?: number\n /** Background painted before the crop (JPEG has no alpha). Default `#ffffff`. */\n background?: string\n}\n\nexport interface CropResult {\n dataUrl: string\n blob: Blob\n width: number\n height: number\n}\n\nfunction loadImage(src: string): Promise<HTMLImageElement> {\n return new Promise((resolve, reject) => {\n const img = new Image()\n // Allow exporting cross-origin images the server marks CORS-safe; harmless for data/blob URLs.\n img.crossOrigin = 'anonymous'\n img.onload = () => resolve(img)\n img.onerror = () => reject(new Error('Failed to load image for cropping'))\n img.src = src\n })\n}\n\nexport async function cropImage(\n imageSrc: string,\n area: CropArea,\n output: CropOutput = {}\n): Promise<CropResult> {\n const { maxSize, mimeType = 'image/jpeg', quality = 0.9, background = '#ffffff' } = output\n const img = await loadImage(imageSrc)\n\n let outW = Math.max(1, Math.round(area.width))\n let outH = Math.max(1, Math.round(area.height))\n if (maxSize && Math.max(outW, outH) > maxSize) {\n const scale = maxSize / Math.max(outW, outH)\n outW = Math.max(1, Math.round(outW * scale))\n outH = Math.max(1, Math.round(outH * scale))\n }\n\n const canvas = document.createElement('canvas')\n canvas.width = outW\n canvas.height = outH\n const ctx = canvas.getContext('2d')\n if (!ctx) throw new Error('canvas 2d context unavailable')\n\n if (mimeType === 'image/jpeg') {\n ctx.fillStyle = background\n ctx.fillRect(0, 0, outW, outH)\n }\n ctx.drawImage(img, area.x, area.y, area.width, area.height, 0, 0, outW, outH)\n\n const dataUrl = canvas.toDataURL(mimeType, quality)\n const blob = await new Promise<Blob>((resolve, reject) =>\n canvas.toBlob(\n (b) => (b ? resolve(b) : reject(new Error('canvas toBlob returned null'))),\n mimeType,\n quality\n )\n )\n return { dataUrl, blob, width: outW, height: outH }\n}\n","/**\n * ImageCropModal — a turnkey crop dialog. Wraps {@link ImageCropper} with\n * Save/Cancel and runs {@link cropImage} on save, handing the caller the full\n * result (both a `dataUrl` and a `blob`, plus dimensions) so it can inline a\n * small avatar or upload a larger asset as it sees fit.\n */\n\nimport { useState } from 'react'\nimport { Loader2 } from 'lucide-react'\nimport { Button } from '../ui/button'\nimport { Dialog, DialogContent, DialogFooter, DialogHeader, DialogTitle } from '../ui/dialog'\nimport { cropImage, type CropArea, type CropOutput, type CropResult } from './cropImage'\nimport { ImageCropper, type AspectOption } from './ImageCropper'\n\nexport interface ImageCropModalProps {\n open: boolean\n image: string | null\n title?: string\n saveLabel?: string\n aspect?: number\n aspectOptions?: AspectOption[]\n cropShape?: 'rect' | 'round'\n /** Export options (max size, mime, quality). */\n output?: CropOutput\n /** Called with the exported crop on save. */\n onComplete: (result: CropResult) => void | Promise<void>\n onCancel: () => void\n}\n\nexport function ImageCropModal({\n open,\n image,\n title = 'Crop image',\n saveLabel = 'Save',\n aspect,\n aspectOptions,\n cropShape = 'rect',\n output,\n onComplete,\n onCancel,\n}: ImageCropModalProps) {\n const [area, setArea] = useState<CropArea | null>(null)\n const [busy, setBusy] = useState(false)\n\n const handleSave = async () => {\n if (!image || !area) return\n setBusy(true)\n try {\n const result = await cropImage(image, area, output)\n await onComplete(result)\n } finally {\n setBusy(false)\n }\n }\n\n return (\n <Dialog open={open} onOpenChange={(next) => (!next ? onCancel() : undefined)}>\n <DialogContent className=\"sm:max-w-md\" data-testid=\"image-crop-modal\">\n <DialogHeader>\n <DialogTitle>{title}</DialogTitle>\n </DialogHeader>\n\n {image ? (\n <ImageCropper\n image={image}\n aspect={aspect}\n aspectOptions={aspectOptions}\n cropShape={cropShape}\n onCropComplete={setArea}\n />\n ) : null}\n\n <DialogFooter className=\"gap-2 sm:gap-2\">\n <Button variant=\"ghost\" onClick={onCancel} disabled={busy}>\n Cancel\n </Button>\n <Button onClick={handleSave} disabled={!area || busy} data-testid=\"image-crop-save\">\n {busy ? <Loader2 className=\"mr-1 size-4 animate-spin\" /> : null}\n {saveLabel}\n </Button>\n </DialogFooter>\n </DialogContent>\n </Dialog>\n )\n}\n","import { useEffect, useMemo, useRef, useState } from 'react'\nimport { Sparkles, CornerDownLeft, ArrowRight, FileText } from 'lucide-react'\nimport { Dialog, DialogContent, DialogTitle } from '../ui/dialog'\nimport { Button } from '../ui/button'\nimport { cn } from '../lib/utils'\nimport { useAiTask, useSemanticSearch, AiAnswer } from '../ai'\nimport type { PaletteNavItem, CommandPaletteClassNames } from './types'\n\nexport interface CommandPaletteProps {\n open: boolean\n onOpenChange: (open: boolean) => void\n /** Destinations the palette can filter and jump to. */\n navItems: PaletteNavItem[]\n /** Invoked with an item's `to` when a nav result is chosen. */\n onNavigate: (to: string) => void\n /** Turn the raw query into the grounded AI prompt (default: identity). */\n buildAskPrompt?: (query: string) => string\n /** Document ids the AI answer is grounded on. */\n askDocIds?: string[]\n model?: string\n /** Document ids to semantic-search as the user types (omit to disable search). */\n searchDocIds?: string[]\n /** Invoked with a document id when a search hit is chosen. */\n onOpenDoc?: (docId: string) => void\n placeholder?: string\n /** Footnote under the \"Ask AI\" action (e.g. what it's grounded in). */\n askHint?: string\n classNames?: CommandPaletteClassNames\n testId?: string\n}\n\nconst MAX_NAV = 5\nconst MAX_DOCS = 4\n\n/**\n * The single pane of glass: one ⌘K spotlight that navigates the app, runs a\n * grounded cited AI query, and (optionally) semantic-searches the workspace — all\n * from one input. Firm-agnostic: navigation, prompt and grounding arrive as props;\n * styling tracks the shadcn + AI-accent semantic tokens.\n */\nexport function CommandPalette({\n open,\n onOpenChange,\n navItems,\n onNavigate,\n buildAskPrompt = (q) => q,\n askDocIds = [],\n model,\n searchDocIds,\n onOpenDoc,\n placeholder = 'Ask AI, or jump to a page…',\n askHint = 'Grounded in the live workspace',\n classNames,\n testId = 'command-palette',\n}: CommandPaletteProps) {\n const task = useAiTask()\n const searchable = !!searchDocIds && searchDocIds.length > 0\n const { results, search, status: searchStatus } = useSemanticSearch(searchDocIds ?? [])\n const [query, setQuery] = useState('')\n const inputRef = useRef<HTMLInputElement>(null)\n\n // Reset each time the palette opens.\n useEffect(() => {\n if (open) {\n setQuery('')\n task.reset()\n const t = setTimeout(() => inputRef.current?.focus(), 40)\n return () => clearTimeout(t)\n }\n // eslint-disable-next-line react-hooks/exhaustive-deps\n }, [open])\n\n const showingAnswer = task.status !== 'idle'\n\n // Debounced semantic search as the user types (only when grounding docs exist).\n useEffect(() => {\n if (!searchable || showingAnswer) return\n const q = query.trim()\n if (q.length < 2) return\n const t = setTimeout(() => void search(q, 'hybrid'), 300)\n return () => clearTimeout(t)\n }, [query, searchable, showingAnswer, search])\n\n const navMatches = useMemo(() => {\n const q = query.trim().toLowerCase()\n if (!q) return navItems.slice(0, MAX_NAV)\n return navItems\n .filter(\n (i) =>\n i.label.toLowerCase().includes(q) ||\n (i.keywords ? i.keywords.toLowerCase().includes(q) : false)\n )\n .slice(0, MAX_NAV)\n }, [query, navItems])\n\n const docHits = useMemo(() => results.slice(0, MAX_DOCS), [results])\n\n const go = (to: string) => {\n onOpenChange(false)\n onNavigate(to)\n }\n\n const openDoc = (docId: string) => {\n onOpenChange(false)\n onOpenDoc?.(docId)\n }\n\n const ask = () => {\n const q = query.trim()\n if (!q || task.isRunning) return\n void task.run(buildAskPrompt(q), askDocIds, { model })\n }\n\n return (\n <Dialog open={open} onOpenChange={onOpenChange}>\n <DialogContent\n className={cn(\n 'top-[12%] max-w-2xl translate-y-0 gap-0 overflow-hidden p-0',\n classNames?.dialog\n )}\n data-testid={testId}\n >\n <DialogTitle className=\"sr-only\">Command palette</DialogTitle>\n\n {/* Input row */}\n <div className=\"flex items-center gap-3 border-b border-border px-4\">\n <Sparkles className={cn('size-4 shrink-0 text-ai-accent', classNames?.leadingIcon)} />\n <input\n ref={inputRef}\n value={query}\n onChange={(e) => setQuery(e.target.value)}\n onKeyDown={(e) => {\n if (e.key === 'Enter') {\n e.preventDefault()\n ask()\n }\n }}\n placeholder={placeholder}\n className={cn(\n 'h-14 flex-1 bg-transparent text-base outline-none placeholder:text-muted-foreground',\n classNames?.input\n )}\n data-testid={`${testId}-input`}\n />\n <kbd className=\"hidden rounded border border-border px-1.5 py-0.5 text-xs text-muted-foreground sm:inline\">\n ⌘K\n </kbd>\n </div>\n\n <div className=\"max-h-[60vh] overflow-y-auto p-2\">\n {/* Ask AI primary action */}\n {query.trim() && !showingAnswer && (\n <button\n type=\"button\"\n onClick={ask}\n className={cn(\n 'mb-1 flex w-full items-center gap-3 rounded-lg px-3 py-2.5 text-left hover:bg-accent',\n classNames?.askAction\n )}\n data-testid={`${testId}-ask`}\n >\n <span\n className={cn(\n 'flex size-8 items-center justify-center rounded-md bg-ai-surface text-ai-accent',\n classNames?.askChip\n )}\n >\n <Sparkles className=\"size-4\" />\n </span>\n <span className=\"min-w-0 flex-1\">\n <span className=\"block truncate text-sm font-medium text-foreground\">\n Ask AI: “{query.trim()}”\n </span>\n <span className=\"block text-xs text-muted-foreground\">{askHint}</span>\n </span>\n <CornerDownLeft className=\"size-4 text-muted-foreground\" />\n </button>\n )}\n\n {/* Streaming answer */}\n {showingAnswer && (\n <div className=\"px-3 py-2\" data-testid={`${testId}-answer`}>\n <AiAnswer\n status={task.status}\n text={task.text}\n stepCount={task.stepCount}\n error={task.error}\n testId={`${testId}-ai`}\n />\n {task.isDone && (\n <div className=\"mt-3 flex justify-end\">\n <Button\n variant=\"outline\"\n size=\"sm\"\n onClick={() => task.reset()}\n data-testid={`${testId}-clear`}\n >\n Ask another\n </Button>\n </div>\n )}\n </div>\n )}\n\n {/* Navigation + document search */}\n {!showingAnswer && (\n <>\n <p className=\"px-3 pb-1 pt-2 text-xs font-semibold uppercase tracking-wide text-muted-foreground\">\n {query.trim() ? 'Jump to' : 'Go to'}\n </p>\n {navMatches.length === 0 && (\n <p className=\"px-3 py-2 text-sm text-muted-foreground\">\n No pages match — press Enter to ask AI.\n </p>\n )}\n {navMatches.map((item) => (\n <button\n key={item.id}\n type=\"button\"\n onClick={() => go(item.to)}\n className={cn(\n 'flex w-full items-center gap-3 rounded-lg px-3 py-2 text-left hover:bg-accent',\n classNames?.navItem\n )}\n data-testid={`${testId}-nav-${item.id}`}\n >\n {item.icon && <item.icon className=\"size-4 text-muted-foreground\" />}\n <span className=\"flex-1 text-sm text-foreground\">{item.label}</span>\n <ArrowRight className=\"size-3.5 text-muted-foreground\" />\n </button>\n ))}\n\n {searchable && query.trim().length >= 2 && (\n <>\n <p className=\"px-3 pb-1 pt-3 text-xs font-semibold uppercase tracking-wide text-muted-foreground\">\n Documents\n </p>\n {searchStatus === 'done' && docHits.length === 0 && (\n <p className=\"px-3 py-2 text-sm text-muted-foreground\">No passages matched.</p>\n )}\n {docHits.map((hit, i) => (\n <button\n key={`${hit.docId}-${hit.page}-${i}`}\n type=\"button\"\n onClick={() => hit.docId && openDoc(hit.docId)}\n className=\"flex w-full items-start gap-3 rounded-lg px-3 py-2 text-left hover:bg-accent\"\n data-testid={`${testId}-doc-${i}`}\n >\n <FileText className=\"mt-0.5 size-4 shrink-0 text-ai-accent\" />\n <span className=\"min-w-0 flex-1\">\n <span className=\"block truncate text-sm text-foreground\">\n {hit.docTitle ?? 'Document'}\n {hit.page != null && (\n <span className=\"text-muted-foreground\"> · p.{hit.page}</span>\n )}\n </span>\n <span className=\"line-clamp-1 text-xs text-muted-foreground\">\n {hit.content}\n </span>\n </span>\n </button>\n ))}\n </>\n )}\n </>\n )}\n </div>\n </DialogContent>\n </Dialog>\n )\n}\n","import { createContext, useContext } from 'react'\n\n/** Imperative handle to the command palette, exposed to any descendant. */\nexport interface CommandPaletteValue {\n open: () => void\n close: () => void\n toggle: () => void\n isOpen: boolean\n}\n\nexport const CommandPaletteCtx = createContext<CommandPaletteValue | null>(null)\n\n/**\n * Access the palette from anywhere under {@link CommandPaletteProvider} — e.g. a\n * topbar search button calls `useCommandPalette().open()`.\n */\nexport function useCommandPalette(): CommandPaletteValue {\n const v = useContext(CommandPaletteCtx)\n if (!v) throw new Error('useCommandPalette must be used within a CommandPaletteProvider')\n return v\n}\n","import { useCallback, useEffect, useMemo, useState, type ReactNode } from 'react'\nimport { CommandPaletteCtx } from './commandPaletteContext'\nimport { CommandPalette, type CommandPaletteProps } from './CommandPalette'\n\nexport interface CommandPaletteProviderProps extends Omit<\n CommandPaletteProps,\n 'open' | 'onOpenChange'\n> {\n children: ReactNode\n /** Disable the global ⌘K / Ctrl+K binding (default enabled). */\n hotkey?: boolean\n}\n\n/**\n * Wraps the app once with the palette's data (nav items, grounding, prompt) and\n * provides an imperative handle via {@link useCommandPalette}. Binds ⌘K/Ctrl+K\n * globally so any surface — a topbar search button, a menu item — can open it.\n */\nexport function CommandPaletteProvider({\n children,\n hotkey = true,\n ...paletteProps\n}: CommandPaletteProviderProps) {\n const [isOpen, setIsOpen] = useState(false)\n const open = useCallback(() => setIsOpen(true), [])\n const close = useCallback(() => setIsOpen(false), [])\n const toggle = useCallback(() => setIsOpen((o) => !o), [])\n\n useEffect(() => {\n if (!hotkey) return\n const onKey = (e: KeyboardEvent) => {\n if ((e.metaKey || e.ctrlKey) && e.key.toLowerCase() === 'k') {\n e.preventDefault()\n toggle()\n }\n }\n window.addEventListener('keydown', onKey)\n return () => window.removeEventListener('keydown', onKey)\n }, [hotkey, toggle])\n\n const value = useMemo(() => ({ open, close, toggle, isOpen }), [open, close, toggle, isOpen])\n\n return (\n <CommandPaletteCtx.Provider value={value}>\n {children}\n <CommandPalette open={isOpen} onOpenChange={setIsOpen} {...paletteProps} />\n </CommandPaletteCtx.Provider>\n )\n}\n","/**\n * SDK-owned UI store for cross-block coordination.\n *\n * This is a SMALL, decoupled zustand store (NOT the ARBI app's multi-slice\n * store). Blocks such as `DocumentTable` use it as a fallback for selection /\n * \"viewing\" state when the consumer does not drive that state via props.\n */\n\nimport { create } from 'zustand'\n\nexport interface ArbiUiState {\n /** External ids of the currently selected documents. */\n selectedDocIds: string[]\n setSelectedDocIds: (ids: string[]) => void\n /** External id of the document currently being viewed/opened, if any. */\n viewingDocId: string | null\n setViewingDocId: (id: string | null) => void\n}\n\nexport const useArbiUiStore = create<ArbiUiState>((set) => ({\n selectedDocIds: [],\n setSelectedDocIds: (ids) => set({ selectedDocIds: ids }),\n viewingDocId: null,\n setViewingDocId: (id) => set({ viewingDocId: id }),\n}))\n","/**\n * DocumentTable — a reusable AG Grid (community) block that renders a\n * workspace's documents using the promoted entity pills.\n *\n * REUSE-FIRST: this composes AG Grid + `DocumentEntity`/`TagEntity` + the shadcn\n * `Badge`; it is not a bespoke table. Data comes from the SDK `useDocuments`\n * hook (or an explicit `documents` prop). Selection is controlled via\n * `selectedIds`/`onSelectionChange`, falling back to the SDK-owned\n * `useArbiUiStore` when those props are omitted.\n */\n\nimport React from 'react'\nimport { AgGridReact } from 'ag-grid-react'\nimport {\n ModuleRegistry,\n AllCommunityModule,\n type ColDef,\n type ICellRendererParams,\n type RowClickedEvent,\n type SelectionChangedEvent,\n type GridReadyEvent,\n} from 'ag-grid-community'\nimport type { components } from '@arbidocs/client'\n\nimport { useDocuments, useTags } from '../hooks'\nimport { useArbiUiStore } from '../store'\nimport { DocumentEntity } from '../entities/DocumentEntity'\nimport { TagEntity } from '../entities/TagEntity'\nimport { Badge } from '../ui/badge'\n\n// Register the community modules once, at import time (matches the app's usage).\nModuleRegistry.registerModules([AllCommunityModule])\n\ntype DocResponse = components['schemas']['DocResponse']\n\nexport interface DocumentTableProps {\n /** Workspace to load documents from (used when `documents` is not supplied). */\n workspaceId?: string\n /** Explicit rows. When provided, `useDocuments` is not called. */\n documents?: DocResponse[]\n /** Called when a row (document) is opened — row click or name-pill click. */\n onOpenDocument?: (id: string) => void\n /**\n * Whether clicking anywhere in a row opens the document. Default true.\n *\n * Set false when the grid is used for bulk work: a reviewer building a\n * selection to code together will inevitably click a row, and navigating away\n * mid-selection loses it. With this off, the name pill stays the way to open\n * a document and the row is purely a selection target.\n */\n openOnRowClick?: boolean\n /** Controlled selection (external ids). Falls back to the SDK ui store. */\n selectedIds?: string[]\n /** Called with the new selection (external ids). Falls back to the SDK ui store. */\n onSelectionChange?: (ids: string[]) => void\n /** Grid height. Number → pixels; string passed through. Default 480. */\n height?: number | string\n /**\n * Extra columns appended after the built-ins — e.g. one per coding field in a\n * review protocol, so a grid can be coded across rather than document by\n * document. Standard AG Grid `ColDef`s; give each an explicit `colId`, since\n * AG Grid persists column state and auto-generated ids reorder unexpectedly.\n */\n extraColumns?: ColDef<DocResponse>[]\n className?: string\n}\n\n/** Format a byte count as a compact human-readable size. */\nfunction formatBytes(bytes?: number | null): string {\n if (bytes == null || Number.isNaN(bytes)) return '—'\n if (bytes < 1024) return `${bytes} B`\n const units = ['KB', 'MB', 'GB', 'TB']\n let value = bytes / 1024\n let i = 0\n while (value >= 1024 && i < units.length - 1) {\n value /= 1024\n i++\n }\n return `${value.toFixed(value >= 10 || i === 0 ? 0 : 1)} ${units[i]}`\n}\n\nconst STATUS_VARIANTS: Record<string, 'default' | 'secondary' | 'destructive' | 'outline'> = {\n completed: 'default',\n empty: 'secondary',\n 'low-content': 'secondary',\n processing: 'outline',\n queued: 'outline',\n failed: 'destructive',\n skipped: 'destructive',\n}\n\nexport function DocumentTable({\n workspaceId,\n documents,\n onOpenDocument,\n openOnRowClick = true,\n selectedIds,\n onSelectionChange,\n height = 480,\n extraColumns,\n className,\n}: DocumentTableProps) {\n // Server data via the SDK hook, unless rows are supplied directly.\n const query = useDocuments(workspaceId, { enabled: !documents })\n const rows = documents ?? query.data ?? []\n const isLoading = !documents && query.isLoading\n\n // Resolve tag ids → human names so the \"Labels\" column shows real AI tags\n // (e.g. \"Issue\", \"Relevance\") rather than opaque id prefixes.\n const tagsQuery = useTags(workspaceId)\n const tagNameById = React.useMemo(() => {\n const map = new Map<string, string>()\n for (const t of tagsQuery.data ?? []) {\n if (t.external_id) map.set(t.external_id, t.name ?? t.external_id.slice(0, 8))\n }\n return map\n }, [tagsQuery.data])\n\n // Selection: controlled via props, else the SDK-owned ui store.\n const storeSelected = useArbiUiStore((s) => s.selectedDocIds)\n const storeSetSelected = useArbiUiStore((s) => s.setSelectedDocIds)\n const viewingDocId = useArbiUiStore((s) => s.viewingDocId)\n const setViewingDocId = useArbiUiStore((s) => s.setViewingDocId)\n\n const effectiveSelected = selectedIds ?? storeSelected\n const emitSelection = onSelectionChange ?? storeSetSelected\n\n const gridApiRef = React.useRef<GridReadyEvent['api'] | null>(null)\n\n const openDocument = React.useCallback(\n (id: string) => {\n setViewingDocId(id)\n onOpenDocument?.(id)\n },\n [onOpenDocument, setViewingDocId]\n )\n\n // Sync the incoming `effectiveSelected` down into the grid's node selection.\n const applySelection = React.useCallback(() => {\n const api = gridApiRef.current\n if (!api) return\n const wanted = new Set(effectiveSelected)\n api.forEachNode((node) => {\n const id = (node.data as DocResponse | undefined)?.external_id\n const shouldSelect = !!id && wanted.has(id)\n if (node.isSelected() !== shouldSelect) node.setSelected(shouldSelect)\n })\n }, [effectiveSelected])\n\n React.useEffect(() => {\n applySelection()\n }, [applySelection])\n\n const columnDefs = React.useMemo<ColDef<DocResponse>[]>(\n () => [\n {\n colId: 'select',\n headerName: '',\n width: 44,\n pinned: 'left',\n checkboxSelection: true,\n headerCheckboxSelection: true,\n sortable: false,\n filter: false,\n resizable: false,\n suppressMovable: true,\n },\n {\n colId: 'title',\n headerName: 'Document Name',\n flex: 3,\n minWidth: 240,\n sortable: true,\n valueGetter: (p) => p.data?.doc_metadata?.title || p.data?.file_name || '',\n cellRenderer: (p: ICellRendererParams<DocResponse>) => {\n const doc = p.data\n if (!doc) return null\n return (\n <DocumentEntity\n doc={doc}\n size=\"base\"\n fullWidth\n viewing={viewingDocId === doc.external_id}\n onClick={(e) => {\n e.stopPropagation()\n if (doc.external_id) openDocument(doc.external_id)\n }}\n />\n )\n },\n },\n {\n colId: 'status',\n headerName: 'Status',\n width: 140,\n sortable: true,\n field: 'status',\n cellRenderer: (p: ICellRendererParams<DocResponse>) => {\n const status = p.data?.status\n if (!status) return null\n return (\n <Badge variant={STATUS_VARIANTS[status.toLowerCase()] ?? 'secondary'}>{status}</Badge>\n )\n },\n },\n {\n colId: 'all_tags',\n headerName: 'Labels',\n flex: 1,\n minWidth: 160,\n sortable: false,\n filter: false,\n cellRenderer: (p: ICellRendererParams<DocResponse>) => {\n const doctags = p.data?.doctags ?? []\n if (doctags.length === 0) return null\n return (\n <div className=\"flex flex-wrap items-center gap-1 py-1\">\n {doctags.map((dt) => (\n <TagEntity\n key={dt.tag_ext_id}\n size=\"sm\"\n tag={{\n external_id: dt.tag_ext_id,\n name: tagNameById.get(dt.tag_ext_id) ?? dt.tag_ext_id.slice(0, 8),\n }}\n />\n ))}\n </div>\n )\n },\n },\n {\n colId: 'file_size',\n headerName: 'Size',\n width: 110,\n sortable: true,\n field: 'file_size',\n valueFormatter: (p) => formatBytes(p.value as number | null | undefined),\n },\n {\n colId: 'folder',\n headerName: 'Folder',\n flex: 1,\n minWidth: 140,\n sortable: true,\n field: 'folder',\n valueFormatter: (p) => (p.value as string | null | undefined) || '—',\n },\n ...(extraColumns ?? []),\n ],\n [openDocument, viewingDocId, tagNameById, extraColumns]\n )\n\n const handleGridReady = (e: GridReadyEvent) => {\n gridApiRef.current = e.api\n applySelection()\n }\n\n const handleSelectionChanged = (e: SelectionChangedEvent) => {\n const ids = e.api\n .getSelectedRows()\n .map((r) => (r as DocResponse).external_id)\n .filter((id): id is string => !!id)\n emitSelection(ids)\n }\n\n const handleRowClicked = (e: RowClickedEvent) => {\n if (!openOnRowClick) return\n const id = (e.data as DocResponse | undefined)?.external_id\n if (id) openDocument(id)\n }\n\n const getRowId = React.useCallback((params: { data: DocResponse }) => params.data.external_id, [])\n\n const autoHeight = height === 'auto'\n const style: React.CSSProperties = autoHeight\n ? {}\n : { height: typeof height === 'number' ? `${height}px` : height, width: '100%' }\n\n if (isLoading) {\n return (\n <div className={className} style={style}>\n <div className=\"flex h-full w-full items-center justify-center p-8 text-sm text-muted-foreground\">\n Loading documents…\n </div>\n </div>\n )\n }\n\n if (rows.length === 0) {\n return (\n <div className={className} style={style}>\n <div className=\"flex h-full w-full items-center justify-center p-8 text-sm text-muted-foreground\">\n No documents\n </div>\n </div>\n )\n }\n\n return (\n <div className={className} style={style}>\n <AgGridReact<DocResponse>\n columnDefs={columnDefs}\n rowData={rows}\n getRowId={getRowId}\n rowSelection=\"multiple\"\n suppressRowClickSelection\n domLayout={autoHeight ? 'autoHeight' : 'normal'}\n rowHeight={44}\n onGridReady={handleGridReady}\n onSelectionChanged={handleSelectionChanged}\n onRowClicked={handleRowClicked}\n />\n </div>\n )\n}\n","/**\n * The ⋯ actions menu that sits in a document tile's top-right corner.\n *\n * Every item maps to a real SDK operation, so any app that renders a document\n * grid gets the same verbs without re-implementing them. `onOpen` and `onRename`\n * are delegated upward (opening and inline renaming are the grid's concern);\n * download and delete are performed here.\n */\n\nimport React from 'react'\nimport { useMutation, useQueryClient } from '@tanstack/react-query'\nimport { Download, MoreHorizontal, Pencil, SquarePen, Trash2 } from 'lucide-react'\n\nimport { useArbi } from '../useArbi'\nimport { arbiQueryKeys } from '../hooks'\nimport {\n DropdownMenu,\n DropdownMenuContent,\n DropdownMenuItem,\n DropdownMenuSeparator,\n DropdownMenuTrigger,\n} from '../ui/dropdown-menu'\n\nexport interface DocumentCardMenuProps {\n docId: string\n /** Used as the download filename. */\n fileName: string\n onOpen?: () => void\n onRename?: () => void\n /** Omit to hide the delete item (e.g. the user lacks permission). */\n canDelete?: boolean\n testId?: string\n}\n\nexport function DocumentCardMenu({\n docId,\n fileName,\n onOpen,\n onRename,\n canDelete = true,\n testId = 'document-card-menu',\n}: DocumentCardMenuProps) {\n const arbi = useArbi()\n const queryClient = useQueryClient()\n\n const invalidateDocuments = () => {\n const workspaceId = arbi.getWorkspaceId()\n if (workspaceId) {\n void queryClient.invalidateQueries({ queryKey: arbiQueryKeys.documents(workspaceId) })\n }\n }\n\n const download = useMutation({\n mutationFn: async () => {\n const response = await arbi.documents.download(docId)\n if (!response.ok) throw new Error(`Failed to download ${fileName}`)\n return response.blob()\n },\n onSuccess: (blob) => {\n // Hand the bytes to the browser, then release the object URL.\n const url = URL.createObjectURL(blob)\n const anchor = document.createElement('a')\n anchor.href = url\n anchor.download = fileName\n anchor.click()\n URL.revokeObjectURL(url)\n },\n })\n\n const remove = useMutation({\n mutationFn: () => arbi.documents.delete([docId]),\n onSuccess: invalidateDocuments,\n })\n\n return (\n <DropdownMenu>\n <DropdownMenuTrigger asChild>\n <button\n type=\"button\"\n aria-label=\"More actions\"\n data-testid={testId}\n onClick={(e) => e.stopPropagation()}\n className=\"flex size-6 items-center justify-center rounded-md bg-background/90 text-muted-foreground shadow-sm backdrop-blur-sm transition hover:bg-background hover:text-foreground data-[state=open]:bg-background data-[state=open]:text-foreground\"\n >\n <MoreHorizontal className=\"size-4\" />\n </button>\n </DropdownMenuTrigger>\n <DropdownMenuContent align=\"start\" onClick={(e) => e.stopPropagation()} className=\"w-44\">\n {onOpen && (\n <DropdownMenuItem onSelect={onOpen} data-testid={`${testId}-open`}>\n <SquarePen className=\"mr-2 size-4\" />\n Open\n </DropdownMenuItem>\n )}\n {onRename && (\n <DropdownMenuItem onSelect={onRename} data-testid={`${testId}-rename`}>\n <Pencil className=\"mr-2 size-4\" />\n Rename\n </DropdownMenuItem>\n )}\n <DropdownMenuItem\n onSelect={() => download.mutate()}\n disabled={download.isPending}\n data-testid={`${testId}-download`}\n >\n <Download className=\"mr-2 size-4\" />\n Download\n </DropdownMenuItem>\n {canDelete && (\n <>\n <DropdownMenuSeparator />\n <DropdownMenuItem\n onSelect={() => remove.mutate()}\n disabled={remove.isPending}\n className=\"text-destructive focus:text-destructive\"\n data-testid={`${testId}-delete`}\n >\n <Trash2 className=\"mr-2 size-4\" />\n Delete\n </DropdownMenuItem>\n </>\n )}\n </DropdownMenuContent>\n </DropdownMenu>\n )\n}\n","/**\n * DocumentGallery — a reusable thumbnail-grid view of a workspace's documents.\n *\n * REUSE-FIRST: a sibling of `DocumentTable` sharing the exact same data sources\n * (`useDocuments` + `useTags` + the SDK-owned `useArbiUiStore` selection state).\n * The only extra dependency is `useThumbnails`, which batch-loads real first-page\n * previews. Each tile is a `DocumentCard`; this component only binds it to data.\n */\n\nimport React from 'react'\nimport { useMutation, useQueryClient } from '@tanstack/react-query'\nimport type { components } from '@arbidocs/client'\n\nimport { useArbi } from '../useArbi'\nimport { arbiQueryKeys, useDocuments, useTags, useThumbnails } from '../hooks'\nimport { useArbiUiStore } from '../store'\nimport { DocumentCard } from './DocumentCard'\nimport { DocumentCardMenu } from './DocumentCardMenu'\nimport { cn } from '../lib/utils'\n\ntype DocResponse = components['schemas']['DocResponse']\n\nexport interface DocumentGalleryProps {\n /** Workspace to load documents from (used when `documents` is not supplied). */\n workspaceId?: string\n /** Explicit rows. When provided, `useDocuments` is not called. */\n documents?: DocResponse[]\n /** Called when a card (document) is opened. */\n onOpenDocument?: (id: string) => void\n /** Controlled selection (external ids). Falls back to the SDK ui store. */\n selectedIds?: string[]\n /** Called with the new selection (external ids). Falls back to the SDK ui store. */\n onSelectionChange?: (ids: string[]) => void\n /** Min tile width in px — the grid auto-fills as many columns as fit. Default 148. */\n minTileWidth?: number\n className?: string\n}\n\nfunction docTitle(doc: DocResponse): string {\n return doc.doc_metadata?.title || doc.file_name || 'Untitled'\n}\n\n/** The tile's hover card: the full (unclamped) title, then the document's labels. */\nfunction TileTooltip({ title, labels }: { title: string; labels: string[] }) {\n return (\n <div className=\"max-w-xs space-y-2\">\n <div className=\"break-words text-xs font-semibold leading-snug\">{title}</div>\n {labels.length > 0 && (\n <div className=\"flex flex-wrap gap-1 border-t border-border/60 pt-1.5\">\n {labels.map((label) => (\n <span\n key={label}\n className=\"rounded bg-muted px-1.5 py-0.5 text-xs font-medium text-foreground/80\"\n >\n {label}\n </span>\n ))}\n </div>\n )}\n </div>\n )\n}\n\nexport function DocumentGallery({\n workspaceId,\n documents,\n onOpenDocument,\n selectedIds,\n onSelectionChange,\n minTileWidth = 148,\n className,\n}: DocumentGalleryProps) {\n const query = useDocuments(workspaceId, { enabled: !documents })\n const rows = documents ?? query.data ?? []\n const isLoading = !documents && query.isLoading\n\n const tagsQuery = useTags(workspaceId)\n const tagNameById = React.useMemo(() => {\n const map = new Map<string, string>()\n for (const t of tagsQuery.data ?? []) {\n if (t.external_id) map.set(t.external_id, t.name ?? t.external_id.slice(0, 8))\n }\n return map\n }, [tagsQuery.data])\n\n const docIds = React.useMemo(\n () => rows.map((d) => d.external_id).filter((id): id is string => !!id),\n [rows]\n )\n const thumbsQuery = useThumbnails(docIds)\n const thumbs = thumbsQuery.data ?? {}\n\n // Selection: controlled via props, else the SDK-owned ui store.\n const storeSelected = useArbiUiStore((s) => s.selectedDocIds)\n const storeSetSelected = useArbiUiStore((s) => s.setSelectedDocIds)\n const viewingDocId = useArbiUiStore((s) => s.viewingDocId)\n const setViewingDocId = useArbiUiStore((s) => s.setViewingDocId)\n\n const effectiveSelected = selectedIds ?? storeSelected\n const emitSelection = onSelectionChange ?? storeSetSelected\n const selectedSet = React.useMemo(() => new Set(effectiveSelected), [effectiveSelected])\n\n const toggleSelected = React.useCallback(\n (id: string) => {\n const next = new Set(effectiveSelected)\n if (next.has(id)) next.delete(id)\n else next.add(id)\n emitSelection([...next])\n },\n [effectiveSelected, emitSelection]\n )\n\n const openDocument = React.useCallback(\n (id: string) => {\n setViewingDocId(id)\n onOpenDocument?.(id)\n },\n [onOpenDocument, setViewingDocId]\n )\n\n // Inline rename lives here rather than in the tile: only one document at a\n // time can be renamed, and the mutation belongs with the other data wiring.\n const arbi = useArbi()\n const queryClient = useQueryClient()\n const [renamingId, setRenamingId] = React.useState<string | null>(null)\n\n const rename = useMutation({\n mutationFn: ({ doc, title }: { doc: DocResponse; title: string }) =>\n arbi.documents.update([\n { external_id: doc.external_id, doc_metadata: { ...doc.doc_metadata, title } },\n ]),\n onSettled: () => {\n setRenamingId(null)\n const activeWorkspace = workspaceId ?? arbi.getWorkspaceId()\n if (activeWorkspace) {\n void queryClient.invalidateQueries({ queryKey: arbiQueryKeys.documents(activeWorkspace) })\n }\n },\n })\n\n if (isLoading) {\n return (\n <div\n className={cn(\n 'flex items-center justify-center p-8 text-sm text-muted-foreground',\n className\n )}\n >\n Loading documents…\n </div>\n )\n }\n\n if (rows.length === 0) {\n return (\n <div\n className={cn(\n 'flex items-center justify-center p-8 text-sm text-muted-foreground',\n className\n )}\n >\n No documents\n </div>\n )\n }\n\n return (\n <div\n data-testid=\"document-gallery\"\n className={cn('grid gap-3', className)}\n style={{ gridTemplateColumns: `repeat(auto-fill, minmax(${minTileWidth}px, 1fr))` }}\n >\n {rows.map((doc) => {\n const id = doc.external_id\n if (!id) return null\n const title = docTitle(doc)\n const labels = (doc.doctags ?? []).map(\n (dt) => tagNameById.get(dt.tag_ext_id) ?? dt.tag_ext_id.slice(0, 8)\n )\n\n return (\n <div key={id} data-doc-id={id} data-testid=\"document-gallery-card\">\n <DocumentCard\n doc={doc}\n thumbnailUrl={thumbs[id]}\n status={doc.status}\n selected={selectedSet.has(id)}\n onToggleSelect={() => toggleSelected(id)}\n viewing={viewingDocId === id}\n onOpen={() => openDocument(id)}\n renaming={renamingId === id}\n onCommitRename={(newTitle) => rename.mutate({ doc, title: newTitle })}\n onCancelRename={() => setRenamingId(null)}\n actions={\n <DocumentCardMenu\n docId={id}\n fileName={doc.file_name ?? title}\n onOpen={() => openDocument(id)}\n onRename={() => setRenamingId(id)}\n testId={`document-card-menu-${id}`}\n />\n }\n tooltipContent={<TileTooltip title={title} labels={labels} />}\n />\n </div>\n )\n })}\n </div>\n )\n}\n","/**\n * VoiceNoteRecorder\n *\n * A toggle-style recorder (press to start, pause/resume, stop, review, then\n * save or discard) as opposed to a press-and-hold mic. Shares its\n * capture/metering engine (useAudioRecorder) and its REC-badge/timer/waveform\n * visual (MicWaveformIndicator) with any other recorder a host app builds.\n *\n * REUSE-FIRST: no app coupling. The host supplies `onSave`/`onDiscard` (and\n * optionally `onError`) — this component owns only the recording UI and\n * in-memory blob, never persistence. Nothing is uploaded until the host's\n * `onSave` is called and resolves.\n */\n\nimport { useEffect, useState } from 'react'\nimport { Mic, Pause, Play, Square, Trash2, Check, Loader2, RotateCcw } from 'lucide-react'\nimport { Button } from '../ui/button'\nimport { AudioViewer } from '../viewers/AudioViewer'\nimport { useAudioRecorder } from './useAudioRecorder'\nimport { MicWaveformIndicator } from './MicWaveformIndicator'\n\nexport interface VoiceNoteRecorderProps {\n /** Called with the reviewed recording when the user hits Save. Resolve to\n * let the host close/replace this recorder; the recorder shows a saving\n * spinner while the promise is pending. */\n onSave: (blob: Blob, mimeType: string | null) => Promise<void> | void\n /** Called when the user discards the draft. */\n onDiscard: () => void\n /** Surfaces recorder failures (e.g. denied mic permission) — wire this to\n * the host's own notification system. Without it, failures are silent. */\n onError?: (message: string) => void\n /** Title passed through to the playback preview. */\n title?: string\n /** External saving state, e.g. while the host's onSave promise is\n * pending — disables actions and shows a spinner on Save. */\n isSaving?: boolean\n /**\n * Optional: called once with the finished recording as soon as it stops,\n * to produce a quick rough transcript shown inline during review. Purely\n * client-side and ephemeral — it's never uploaded and has no bearing on\n * what onSave receives; a host with real (e.g. diarized) transcription as\n * part of its normal document processing can skip this prop entirely.\n */\n transcribe?: (blob: Blob) => Promise<string>\n}\n\nexport function VoiceNoteRecorder({\n onSave,\n onDiscard,\n onError,\n title = 'Voice Memo',\n isSaving = false,\n transcribe,\n}: VoiceNoteRecorderProps) {\n const recorder = useAudioRecorder()\n const [transcript, setTranscript] = useState<string | null>(null)\n const [isTranscribing, setIsTranscribing] = useState(false)\n\n useEffect(() => {\n if (recorder.error) onError?.(recorder.error)\n // eslint-disable-next-line react-hooks/exhaustive-deps\n }, [recorder.error])\n\n // Kick off the rough transcript the moment a recording is ready to review,\n // so it's usually done by the time the user has looked at the playback\n // controls. Reset on any state other than 'stopped' (re-record, discard)\n // so a stale transcript from a previous take never lingers.\n useEffect(() => {\n if (recorder.state !== 'stopped' || !recorder.blob) {\n setTranscript(null)\n setIsTranscribing(false)\n return\n }\n if (!transcribe) return\n let cancelled = false\n setIsTranscribing(true)\n transcribe(recorder.blob)\n .then((text) => {\n if (!cancelled) setTranscript(text)\n })\n .catch(() => {\n // Best-effort: a failed rough transcript just means the review UI\n // shows nothing extra — the real transcript still arrives later.\n })\n .finally(() => {\n if (!cancelled) setIsTranscribing(false)\n })\n return () => {\n cancelled = true\n }\n // eslint-disable-next-line react-hooks/exhaustive-deps\n }, [recorder.state, recorder.blob])\n\n const handleSave = () => {\n if (!recorder.blob) return\n void onSave(recorder.blob, recorder.mimeType)\n }\n\n return (\n <div className=\"flex h-full flex-col items-center justify-center gap-6 p-8\">\n {recorder.state === 'idle' && (\n <>\n <Button\n type=\"button\"\n size=\"lg\"\n className=\"h-16 w-16 rounded-full p-0\"\n onClick={() => void recorder.start()}\n data-testid=\"voice-note-record-button\"\n >\n <Mic className=\"h-6 w-6\" />\n </Button>\n <p className=\"text-sm text-muted-foreground\">Press to start recording</p>\n </>\n )}\n\n {(recorder.state === 'recording' || recorder.state === 'paused') && (\n <>\n <MicWaveformIndicator\n level={recorder.level}\n elapsedMs={recorder.elapsedMs}\n paused={recorder.state === 'paused'}\n />\n <div className=\"flex items-center gap-3\">\n {recorder.state === 'recording' ? (\n <Button\n type=\"button\"\n variant=\"outline\"\n onClick={recorder.pause}\n data-testid=\"voice-note-pause-button\"\n >\n <Pause className=\"mr-1.5 h-4 w-4\" />\n Pause\n </Button>\n ) : (\n <Button\n type=\"button\"\n variant=\"outline\"\n onClick={recorder.resume}\n data-testid=\"voice-note-resume-button\"\n >\n <Play className=\"mr-1.5 h-4 w-4\" />\n Resume\n </Button>\n )}\n <Button type=\"button\" onClick={recorder.stop} data-testid=\"voice-note-stop-button\">\n <Square className=\"mr-1.5 h-3.5 w-3.5 fill-current\" />\n Stop\n </Button>\n </div>\n </>\n )}\n\n {recorder.state === 'stopped' && recorder.blob && (\n <>\n <div className=\"w-full max-w-md\">\n <AudioViewer blob={recorder.blob} title={title} />\n </div>\n {(isTranscribing || transcript) && (\n <div\n className=\"w-full max-w-md rounded-md border border-border bg-muted/30 p-3 text-sm text-muted-foreground\"\n data-testid=\"voice-note-rough-transcript\"\n >\n {isTranscribing ? (\n <span className=\"flex items-center gap-1.5\">\n <Loader2 className=\"h-3.5 w-3.5 animate-spin\" />\n Transcribing…\n </span>\n ) : (\n <>\n <p className=\"mb-1 text-xs font-semibold uppercase tracking-wide\">\n Rough transcript\n </p>\n <p>{transcript}</p>\n </>\n )}\n </div>\n )}\n <div className=\"flex items-center gap-3\">\n <Button\n type=\"button\"\n variant=\"outline\"\n onClick={onDiscard}\n disabled={isSaving}\n data-testid=\"voice-note-discard-button\"\n >\n <Trash2 className=\"mr-1.5 h-4 w-4\" />\n Discard\n </Button>\n <Button\n type=\"button\"\n variant=\"outline\"\n onClick={recorder.reset}\n disabled={isSaving}\n data-testid=\"voice-note-record-again-button\"\n >\n <RotateCcw className=\"mr-1.5 h-4 w-4\" />\n Record again\n </Button>\n <Button\n type=\"button\"\n onClick={handleSave}\n disabled={isSaving}\n data-testid=\"voice-note-save-button\"\n >\n {isSaving ? (\n <Loader2 className=\"mr-1.5 h-4 w-4 animate-spin\" />\n ) : (\n <Check className=\"mr-1.5 h-4 w-4\" />\n )}\n {isSaving ? 'Saving…' : 'Save'}\n </Button>\n </div>\n </>\n )}\n </div>\n )\n}\n","/**\n * DraftTitleControls\n *\n * A title field + an auto-name toggle for an unsaved draft (blank document,\n * voice note, or anything else a host app drafts before it exists on the\n * backend) — so picking a name or leaving AI generation on doesn't require a\n * separate settings surface.\n *\n * REUSE-FIRST: props/callbacks in, no store or config-API coupling. The host\n * owns where `title` is stored and what `autoRename` actually controls (in\n * ARBI-frontend, the same `DoctagLLM.AUTO_RENAME` config field the Upload\n * modal's toggle already writes).\n */\n\nimport { Sparkles } from 'lucide-react'\nimport { IconToggle } from '../ui/IconToggle'\n\nconst AUTO_RENAME_COLORS = { text: 'text-amber-700', bg: 'bg-amber-500' }\n\nexport interface DraftTitleControlsProps {\n title: string\n onTitleChange: (title: string) => void\n placeholder: string\n autoRename: boolean\n onAutoRenameChange: (value: boolean) => void\n}\n\nexport function DraftTitleControls({\n title,\n onTitleChange,\n placeholder,\n autoRename,\n onAutoRenameChange,\n}: DraftTitleControlsProps) {\n return (\n <div className=\"flex min-w-0 flex-shrink-0 items-center gap-1.5\">\n <input\n type=\"text\"\n value={title}\n onChange={(e) => onTitleChange(e.target.value)}\n placeholder={placeholder}\n className=\"min-w-0 max-w-[220px] rounded-md bg-muted px-2 py-1 text-sm font-medium outline-none focus-visible:ring-1 focus-visible:ring-primary\"\n data-testid=\"draft-title-input\"\n />\n <IconToggle\n icon={Sparkles}\n isActive={autoRename}\n onToggle={onAutoRenameChange}\n colors={AUTO_RENAME_COLORS}\n tooltipActive=\"Auto-name from content is on — generates a title once saved\"\n tooltipInactive=\"Auto-name from content is off — uses the name typed above\"\n data-testid=\"draft-auto-rename-toggle\"\n />\n </div>\n )\n}\n","/**\n * useCameraStream\n *\n * Shared camera-acquisition engine for photo and video capture — requests\n * `getUserMedia`, hands back the live `MediaStream` for a host to bind to a\n * `<video>` element, and tears the tracks down on stop()/unmount. Mirrors\n * `useAudioRecorder`'s permission/error handling (same DOMException\n * classification, via `classifyMediaError`) but stays a separate hook rather\n * than folding into it: audio's state machine centers on an AnalyserNode\n * level meter with no visual preview, while camera capture centers on a live\n * video preview with no metering — sharing \"here is a device stream and an\n * error string\" is the useful overlap, not the recording state machine\n * itself. `useVideoRecorder` layers MediaRecorder on top of the stream this\n * returns; photo capture reads a frame off it directly (see capture-frame.ts).\n *\n * REUSE-FIRST: no app coupling, failures surface via `error` rather than a\n * toast call — same contract as useAudioRecorder.\n */\n\nimport { useCallback, useEffect, useRef, useState } from 'react'\nimport { classifyMediaError } from './media-error'\n\nexport interface UseCameraStreamResult {\n /** The live camera stream, or null before start()/after stop(). */\n stream: MediaStream | null\n /** True while the getUserMedia() prompt/negotiation is in flight. */\n isStarting: boolean\n /** A human-readable message from the last failed start() attempt. */\n error: string | null\n start: () => Promise<void>\n /** Stops all tracks and clears the stream. Safe to call repeatedly. */\n stop: () => void\n}\n\n/**\n * @param constraints The `video`/`audio` constraints passed to getUserMedia.\n * Defaults to video-only (photo capture never needs a mic); video capture\n * passes `{ video: true, audio: true }` to record sound with the picture.\n */\nexport function useCameraStream(\n constraints: MediaStreamConstraints = { video: true, audio: false }\n): UseCameraStreamResult {\n const [stream, setStream] = useState<MediaStream | null>(null)\n const [isStarting, setIsStarting] = useState(false)\n const [error, setError] = useState<string | null>(null)\n const streamRef = useRef<MediaStream | null>(null)\n\n const stop = useCallback(() => {\n streamRef.current?.getTracks().forEach((t) => t.stop())\n streamRef.current = null\n setStream(null)\n }, [])\n\n // Constraints are read fresh each start() call rather than becoming a hook\n // dependency: a host re-rendering with a new (but equivalent) constraints\n // object shouldn't force callers to memoize it just to avoid an effect loop.\n const constraintsRef = useRef(constraints)\n constraintsRef.current = constraints\n\n const start = useCallback(async () => {\n if (streamRef.current) return\n setError(null)\n setIsStarting(true)\n try {\n const media = await navigator.mediaDevices.getUserMedia(constraintsRef.current)\n streamRef.current = media\n setStream(media)\n } catch (err) {\n setError(classifyMediaError(err, 'camera'))\n } finally {\n setIsStarting(false)\n }\n }, [])\n\n useEffect(() => () => stop(), [stop])\n\n return { stream, isStarting, error, start, stop }\n}\n","/**\n * useVideoRecorder\n *\n * MediaRecorder lifecycle for video capture, layered on top of an\n * already-live camera `MediaStream` (see useCameraStream — this hook does\n * NOT call getUserMedia itself, so the same stream stays open across a\n * stop()/reset() \"record again\" without re-prompting for permission).\n *\n * Deliberately simpler than useAudioRecorder: no pause/resume (tap-to-start,\n * tap-to-stop is the whole interaction — see MediaCaptureRecorder) and no\n * level meter (there's a live video preview instead; a bar-graph loudness\n * meter would be redundant chrome on top of it).\n */\n\nimport { useCallback, useEffect, useRef, useState } from 'react'\n\nexport type VideoRecorderState = 'idle' | 'recording' | 'stopped'\n\nexport interface UseVideoRecorderResult {\n state: VideoRecorderState\n /** Recorded duration so far (ms). Frozen at its final value once stopped. */\n elapsedMs: number\n /** The finished recording. Only set once state === 'stopped'. */\n blob: Blob | null\n /** The MediaRecorder MIME type used (e.g. 'video/webm'). */\n mimeType: string | null\n start: () => void\n stop: () => void\n /** Back to idle: clears blob/elapsedMs, ready to record again on the same stream. */\n reset: () => void\n}\n\nconst ELAPSED_TICK_MS = 200\n\n/** @param stream The live camera stream to record — null while the camera\n * hasn't started yet; start() is a no-op until it's set. */\nexport function useVideoRecorder(stream: MediaStream | null): UseVideoRecorderResult {\n const [state, setState] = useState<VideoRecorderState>('idle')\n const [elapsedMs, setElapsedMs] = useState(0)\n const [blob, setBlob] = useState<Blob | null>(null)\n const [mimeType, setMimeType] = useState<string | null>(null)\n\n const mediaRecorderRef = useRef<MediaRecorder | null>(null)\n const chunksRef = useRef<Blob[]>([])\n const startedAtRef = useRef(0)\n const tickRef = useRef<ReturnType<typeof setInterval> | null>(null)\n const stateRef = useRef<VideoRecorderState>('idle')\n stateRef.current = state\n\n const stopTicking = useCallback(() => {\n if (tickRef.current !== null) clearInterval(tickRef.current)\n tickRef.current = null\n }, [])\n\n useEffect(() => stopTicking, [stopTicking])\n\n const start = useCallback(() => {\n if (!stream || stateRef.current === 'recording') return\n const mt = MediaRecorder.isTypeSupported('video/webm') ? 'video/webm' : 'video/mp4'\n const recorder = new MediaRecorder(stream, { mimeType: mt })\n chunksRef.current = []\n recorder.ondataavailable = (e) => {\n if (e.data.size > 0) chunksRef.current.push(e.data)\n }\n mediaRecorderRef.current = recorder\n setMimeType(mt)\n setBlob(null)\n startedAtRef.current = performance.now()\n setElapsedMs(0)\n recorder.start()\n setState('recording')\n tickRef.current = setInterval(() => {\n setElapsedMs(performance.now() - startedAtRef.current)\n }, ELAPSED_TICK_MS)\n }, [stream])\n\n const stop = useCallback(() => {\n const recorder = mediaRecorderRef.current\n if (!recorder || recorder.state === 'inactive') return\n const finalElapsed = performance.now() - startedAtRef.current\n stopTicking()\n recorder.onstop = () => {\n const finalBlob = chunksRef.current.length\n ? new Blob(chunksRef.current, { type: recorder.mimeType })\n : null\n setBlob(finalBlob)\n setElapsedMs(finalElapsed)\n setState('stopped')\n }\n recorder.stop()\n }, [stopTicking])\n\n const reset = useCallback(() => {\n setState('idle')\n setBlob(null)\n setElapsedMs(0)\n setMimeType(null)\n }, [])\n\n return { state, elapsedMs, blob, mimeType, start, stop, reset }\n}\n","/**\n * Captures the current frame of a live `<video>` element (bound to a camera\n * `MediaStream`, e.g. via useCameraStream) as an image Blob — the shutter\n * action for photo capture. Draws to an off-screen canvas rather than reading\n * pixels any other way, since `HTMLCanvasElement.toBlob` is the one\n * cross-browser path from \"a decoded video frame\" to \"an encoded image file\".\n */\nexport function captureFrameAsBlob(video: HTMLVideoElement, mimeType = 'image/png'): Promise<Blob> {\n return new Promise((resolve, reject) => {\n const canvas = document.createElement('canvas')\n canvas.width = video.videoWidth\n canvas.height = video.videoHeight\n const ctx = canvas.getContext('2d')\n if (!ctx) {\n reject(new Error('Canvas 2D context is not available'))\n return\n }\n ctx.drawImage(video, 0, 0, canvas.width, canvas.height)\n canvas.toBlob((blob) => {\n if (blob) resolve(blob)\n else reject(new Error('Failed to capture the photo'))\n }, mimeType)\n })\n}\n","/**\n * PhotoCapture\n *\n * Camera capture UI: live preview → shutter → review (retake or save).\n * Shares its shape (onSave/onDiscard/onError/isSaving) with VoiceNoteRecorder\n * so a host app wires them identically — see MediaCaptureRecorder.tsx (the\n * ARBI-frontend wrapper) for how the three capture modes plug into the same\n * draft/save contract.\n *\n * REUSE-FIRST: no app coupling. This component owns only the capture UI and\n * in-memory blob, never persistence — nothing is uploaded until the host's\n * `onSave` is called.\n */\n\nimport { useEffect, useRef, useState } from 'react'\nimport { Camera, Check, Loader2, RotateCcw, Trash2 } from 'lucide-react'\nimport { Button } from '../ui/button'\nimport { ImageViewer } from '../viewers/ImageViewer'\nimport { useCameraStream } from './useCameraStream'\nimport { captureFrameAsBlob } from './capture-frame'\n\nexport interface PhotoCaptureProps {\n /** Called with the captured photo when the user hits Save. Resolve to let\n * the host close/replace this capture UI; shows a saving spinner while\n * the promise is pending. */\n onSave: (blob: Blob, mimeType: string | null) => Promise<void> | void\n /** Called when the user discards the draft. */\n onDiscard: () => void\n /** Surfaces camera failures (e.g. denied permission) — wire this to the\n * host's own notification system. Without it, failures are silent. */\n onError?: (message: string) => void\n isSaving?: boolean\n}\n\nexport function PhotoCapture({ onSave, onDiscard, onError, isSaving = false }: PhotoCaptureProps) {\n const camera = useCameraStream({ video: true, audio: false })\n const videoRef = useRef<HTMLVideoElement>(null)\n const [capturedBlob, setCapturedBlob] = useState<Blob | null>(null)\n const [captureError, setCaptureError] = useState<string | null>(null)\n\n useEffect(() => {\n void camera.start()\n // Start the camera once on mount — camera.start is stable (useCallback\n // with no deps), so this intentionally doesn't re-run per render.\n // eslint-disable-next-line react-hooks/exhaustive-deps\n }, [])\n\n useEffect(() => {\n if (camera.error) onError?.(camera.error)\n // eslint-disable-next-line react-hooks/exhaustive-deps\n }, [camera.error])\n\n useEffect(() => {\n const video = videoRef.current\n if (!video) return\n video.srcObject = camera.stream\n if (camera.stream) void video.play().catch(() => {})\n }, [camera.stream])\n\n const handleShutter = () => {\n const video = videoRef.current\n if (!video) return\n setCaptureError(null)\n captureFrameAsBlob(video)\n .then(setCapturedBlob)\n .catch((err) => {\n const message = err instanceof Error ? err.message : 'Failed to capture the photo'\n setCaptureError(message)\n onError?.(message)\n })\n }\n\n const handleRetake = () => setCapturedBlob(null)\n\n const handleSave = () => {\n if (!capturedBlob) return\n void onSave(capturedBlob, 'image/png')\n }\n\n return (\n <div className=\"flex h-full flex-col items-center justify-center gap-6 p-8\">\n {!capturedBlob && (\n <>\n <div className=\"w-full max-w-md overflow-hidden rounded-lg bg-muted/30\">\n <video\n ref={videoRef}\n autoPlay\n muted\n playsInline\n className=\"w-full max-h-[60vh] object-contain\"\n data-testid=\"photo-capture-preview\"\n />\n </div>\n <Button\n type=\"button\"\n size=\"lg\"\n className=\"h-16 w-16 rounded-full p-0\"\n onClick={handleShutter}\n disabled={!camera.stream}\n data-testid=\"photo-capture-shutter-button\"\n >\n <Camera className=\"h-6 w-6\" />\n </Button>\n <p className=\"text-sm text-muted-foreground\">\n {camera.isStarting\n ? 'Starting camera…'\n : camera.stream\n ? 'Press to take a photo'\n : 'Waiting for camera access…'}\n </p>\n {captureError && <p className=\"text-sm text-red-text\">{captureError}</p>}\n </>\n )}\n\n {capturedBlob && (\n <>\n <div className=\"w-full max-w-md\">\n <ImageViewer blob={capturedBlob} alt=\"Captured photo\" />\n </div>\n <div className=\"flex items-center gap-3\">\n <Button\n type=\"button\"\n variant=\"outline\"\n onClick={onDiscard}\n disabled={isSaving}\n data-testid=\"photo-capture-discard-button\"\n >\n <Trash2 className=\"mr-1.5 h-4 w-4\" />\n Discard\n </Button>\n <Button\n type=\"button\"\n variant=\"outline\"\n onClick={handleRetake}\n disabled={isSaving}\n data-testid=\"photo-capture-retake-button\"\n >\n <RotateCcw className=\"mr-1.5 h-4 w-4\" />\n Retake\n </Button>\n <Button\n type=\"button\"\n onClick={handleSave}\n disabled={isSaving}\n data-testid=\"photo-capture-save-button\"\n >\n {isSaving ? (\n <Loader2 className=\"mr-1.5 h-4 w-4 animate-spin\" />\n ) : (\n <Check className=\"mr-1.5 h-4 w-4\" />\n )}\n {isSaving ? 'Saving…' : 'Save'}\n </Button>\n </div>\n </>\n )}\n </div>\n )\n}\n","/**\n * VideoCapture\n *\n * Camera capture UI: live preview → tap to record / tap to stop → review\n * (playback, retake, or save). Shares its shape (onSave/onDiscard/onError/\n * isSaving) with VoiceNoteRecorder and PhotoCapture — see\n * MediaCaptureRecorder.tsx (the ARBI-frontend wrapper) for how the three\n * capture modes plug into the same draft/save contract.\n *\n * Deliberately a simple tap-to-start/tap-to-stop toggle rather than a\n * press-and-hold gesture — matches VoiceNoteRecorder's toggle interaction\n * and needs no extra gesture handling for a first cut of camera video.\n *\n * REUSE-FIRST: no app coupling. This component owns only the capture UI and\n * in-memory blob, never persistence — nothing is uploaded until the host's\n * `onSave` is called.\n */\n\nimport { useEffect, useRef } from 'react'\nimport { Check, Circle, Loader2, RotateCcw, Square, Trash2 } from 'lucide-react'\nimport { Button } from '../ui/button'\nimport { VideoViewer } from '../viewers/VideoViewer'\nimport { useCameraStream } from './useCameraStream'\nimport { useVideoRecorder } from './useVideoRecorder'\nimport { formatElapsed } from './format-elapsed'\n\nexport interface VideoCaptureProps {\n /** Called with the recorded clip when the user hits Save. Resolve to let\n * the host close/replace this capture UI; shows a saving spinner while\n * the promise is pending. */\n onSave: (blob: Blob, mimeType: string | null) => Promise<void> | void\n /** Called when the user discards the draft. */\n onDiscard: () => void\n /** Surfaces camera failures (e.g. denied permission) — wire this to the\n * host's own notification system. Without it, failures are silent. */\n onError?: (message: string) => void\n isSaving?: boolean\n}\n\nexport function VideoCapture({ onSave, onDiscard, onError, isSaving = false }: VideoCaptureProps) {\n // Camera audio too, not just video — a silent clip would surprise anyone\n // used to phone camera video capture.\n const camera = useCameraStream({ video: true, audio: true })\n const recorder = useVideoRecorder(camera.stream)\n const videoRef = useRef<HTMLVideoElement>(null)\n\n useEffect(() => {\n void camera.start()\n // Start the camera once on mount — see PhotoCapture's identical effect.\n // eslint-disable-next-line react-hooks/exhaustive-deps\n }, [])\n\n useEffect(() => {\n if (camera.error) onError?.(camera.error)\n // eslint-disable-next-line react-hooks/exhaustive-deps\n }, [camera.error])\n\n // Live preview binds to the camera stream while previewing/recording; once\n // stopped, the video element is replaced by VideoViewer playing the\n // recorded blob (below), so this effect only matters pre-stop.\n useEffect(() => {\n const video = videoRef.current\n if (!video || recorder.state === 'stopped') return\n video.srcObject = camera.stream\n if (camera.stream) void video.play().catch(() => {})\n }, [camera.stream, recorder.state])\n\n const handleRetake = () => {\n recorder.reset()\n }\n\n const handleSave = () => {\n if (!recorder.blob) return\n void onSave(recorder.blob, recorder.mimeType)\n }\n\n return (\n <div className=\"flex h-full flex-col items-center justify-center gap-6 p-8\">\n {recorder.state !== 'stopped' && (\n <>\n <div className=\"w-full max-w-md overflow-hidden rounded-lg bg-muted/30\">\n <video\n ref={videoRef}\n autoPlay\n muted\n playsInline\n className=\"w-full max-h-[60vh] object-contain\"\n data-testid=\"video-capture-preview\"\n />\n </div>\n {recorder.state === 'recording' && (\n <div className=\"flex items-center gap-2\" data-testid=\"video-capture-rec-indicator\">\n <span className=\"relative flex h-2 w-2\">\n <span className=\"absolute inline-flex h-full w-full animate-ping rounded-full bg-red-500 opacity-75\" />\n <span className=\"relative inline-flex h-2 w-2 rounded-full bg-red-500\" />\n </span>\n <span className=\"text-xs font-semibold uppercase tracking-wide text-red-500\">\n Rec\n </span>\n <span className=\"font-mono text-xs tabular-nums text-muted-foreground\">\n {formatElapsed(recorder.elapsedMs)}\n </span>\n </div>\n )}\n {recorder.state === 'recording' ? (\n <Button\n type=\"button\"\n size=\"lg\"\n className=\"h-16 w-16 rounded-full p-0\"\n onClick={recorder.stop}\n data-testid=\"video-capture-stop-button\"\n >\n <Square className=\"h-5 w-5 fill-current\" />\n </Button>\n ) : (\n <Button\n type=\"button\"\n size=\"lg\"\n className=\"h-16 w-16 rounded-full p-0\"\n onClick={recorder.start}\n disabled={!camera.stream}\n data-testid=\"video-capture-record-button\"\n >\n <Circle className=\"h-6 w-6 fill-current\" />\n </Button>\n )}\n <p className=\"text-sm text-muted-foreground\">\n {recorder.state === 'recording'\n ? 'Tap to stop recording'\n : camera.isStarting\n ? 'Starting camera…'\n : camera.stream\n ? 'Tap to start recording'\n : 'Waiting for camera access…'}\n </p>\n </>\n )}\n\n {recorder.state === 'stopped' && recorder.blob && (\n <>\n <div className=\"w-full max-w-md\">\n <VideoViewer blob={recorder.blob} title=\"Captured video\" />\n </div>\n <div className=\"flex items-center gap-3\">\n <Button\n type=\"button\"\n variant=\"outline\"\n onClick={onDiscard}\n disabled={isSaving}\n data-testid=\"video-capture-discard-button\"\n >\n <Trash2 className=\"mr-1.5 h-4 w-4\" />\n Discard\n </Button>\n <Button\n type=\"button\"\n variant=\"outline\"\n onClick={handleRetake}\n disabled={isSaving}\n data-testid=\"video-capture-retake-button\"\n >\n <RotateCcw className=\"mr-1.5 h-4 w-4\" />\n Record again\n </Button>\n <Button\n type=\"button\"\n onClick={handleSave}\n disabled={isSaving}\n data-testid=\"video-capture-save-button\"\n >\n {isSaving ? (\n <Loader2 className=\"mr-1.5 h-4 w-4 animate-spin\" />\n ) : (\n <Check className=\"mr-1.5 h-4 w-4\" />\n )}\n {isSaving ? 'Saving…' : 'Save'}\n </Button>\n </div>\n </>\n )}\n </div>\n )\n}\n","/**\n * Content-based audio-vs-video detection for containers that don't tell you\n * from the extension alone. WebM in particular can hold audio-only, video-only,\n * or both, and a host app bucketing purely by file extension will get an\n * audio-only recording (e.g. a voice note) wrong, since `.webm` is what\n * MediaRecorder produces either way.\n *\n * No backend involvement needed: most document APIs don't expose a\n * content-type field to check post-upload (only a file name), but loading the\n * bytes into a hidden <video> element and reading its decoded metadata does\n * the job entirely client-side — videoWidth/videoHeight report 0x0 when\n * there's no video track, even though duration/audio still work fine.\n */\nexport function hasVideoTrack(blob: Blob): Promise<boolean> {\n return new Promise((resolve) => {\n const url = URL.createObjectURL(blob)\n const video = document.createElement('video')\n video.preload = 'metadata'\n video.muted = true\n\n const cleanup = () => {\n video.removeAttribute('src')\n video.load()\n URL.revokeObjectURL(url)\n }\n\n video.onloadedmetadata = () => {\n resolve(video.videoWidth > 0 && video.videoHeight > 0)\n cleanup()\n }\n // Couldn't even decode it as a video container — treat conservatively as\n // \"no video track\" rather than leaving the caller hanging.\n video.onerror = () => {\n resolve(false)\n cleanup()\n }\n\n video.src = url\n })\n}\n"]}