@arbidocs/react 0.4.38 → 0.4.40

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/workforce.ts","../src/chat/citations.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/contacts.ts","../src/account/profile.ts","../src/account/email.ts","../src/account/password.ts","../src/account/notifications.ts","../src/account/sessions.ts","../src/account/delete.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/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/notifications/useWorkNotifications.ts","../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/StartByEmail.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","useQueryClient","useMutation","arbiQueryKeys","useQuery","resolveCitations","summarizeCitations","useDocuments","useConversations","useMemo","useAssistantQuery","useState","useRef","useEffect","useConversationThreads","useCallback","error","lastMessage","stored","options","memo","TypingIndicator","jsx","jsxs","ChatBubble","cn","Link","Trash2","CheckCheck","Check","create","createContext","useContext","isMessageType","connectWithReconnect","useWorkspaces","passwordChangeErrorMessage","diffWords","Loader2","AlertTriangle","Fragment","AiMarkdown","ShieldCheck","Copy","Sparkles","Card","Button","FileText","Badge","GitCompareArrows","Download","AnimatePresence","motion","ImageIcon","Search","CornerDownLeft","useParsedDocument","useTags","React","X","TagEntity","MarkdownRenderer","PassageCard","ArrowLeft","Input","Send","Tags","notify","normalizeCitationMarkup","useLayoutEffect","ReactMarkdown","createPortal","MarkMenu","FILE_TYPE_COLORS","Crown","useId","getEntityIcon","MessageCircleMore","AtSign","UserCheck","PartyPopper","Gift","Gauge","Activity","Info","SquareArrowOutUpRight","FolderPlus","Pencil","FileX2","FileCheck2","useActivity","UserEntity","getEntityColorStyles","AgentBadge","formatRelativeTime","MessagesSquare","ScrollArea","Textarea","Label","emptyThread","Cropper","Slider","Dialog","DialogContent","DialogHeader","DialogTitle","DialogFooter","ArrowRight","ModuleRegistry","AllCommunityModule","DocumentEntity","AgGridReact","DropdownMenu","DropdownMenuTrigger","MoreHorizontal","DropdownMenuContent","DropdownMenuItem","SquarePen","DropdownMenuSeparator","useThumbnails","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 * Work, workflows, agents and skills: the mutation and read hooks behind an \"AI workforce\" screen.\n *\n * A conversation with a `status` is a task: it is listed by `useConversations` and changed through\n * `useUpdateConversation` and friends. A workflow is the automation that creates them. Everything\n * sits on the SDK (`arbi.conversations`, `arbi.workflows`, `arbi.agents`, `arbi.agentConfig`,\n * `arbi.workspaces`, `arbi.assistant.listSkills`) and invalidates through {@link arbiQueryKeys}, so\n * `useConversations`, `useWorkflows`, `useAgents` and `useConfigs` refresh on their own after a\n * write. Mapping a form onto these requests (`TaskComposerValues` to a create-work or create-workflow\n * request, an agent form to a persona) is the pure part and lives next to the forms in\n * `@arbidocs/blocks/agents`.\n *\n * Requires an `ArbiProvider` and a React Query client above it.\n */\n\nimport { useMutation, useQuery, useQueryClient } from '@tanstack/react-query'\nimport type {\n ActivityResponse,\n ConversationResponse,\n CreateWorkRequest,\n CreateWorkflowRequest,\n PlanWorkRequest,\n RequestApprovalRequest,\n ReviewWorkRequest,\n UpdateConversationRequest,\n UpdateWorkflowRequest,\n WorkflowResponse,\n WorkflowRunResponse,\n} from '@arbidocs/sdk/browser'\nimport { useArbi } from './useArbi'\nimport { arbiQueryKeys } from './hooks'\n\n/** An agent or deployment config: section name (`Agents`, `QueryLLM`, ...) to its parameters. */\nexport type AgentConfigSections = Record<string, Record<string, unknown>>\n\n// ── Conversations as work ───────────────────────────────────────────────────\n\n/**\n * Patch a conversation: rename it, share it or make it private (`shared`, owner only), or change\n * its work fields (description, due date, sign-off person, parent, `status` `todo | done`, plan).\n * The one write behind title edits, the share toggle and marking a task done.\n */\nexport function useUpdateConversation() {\n const arbi = useArbi()\n const qc = useQueryClient()\n return useMutation({\n mutationFn: ({\n conversationId,\n patch,\n }: {\n conversationId: string\n patch: UpdateConversationRequest\n }): Promise<ConversationResponse> => arbi.conversations.update(conversationId, patch),\n onSuccess: () => qc.invalidateQueries({ queryKey: arbiQueryKeys.allConversations() }),\n })\n}\n\n/**\n * Create a work item from a `CreateWorkRequest`: a plain to-do, or (with a prompt or skill) agent\n * work that starts at once. Resolves with the created conversation.\n */\nexport function useCreateWork() {\n const arbi = useArbi()\n const qc = useQueryClient()\n return useMutation({\n mutationFn: (body: CreateWorkRequest): Promise<ConversationResponse> =>\n arbi.conversations.createWork(body),\n onSuccess: () => qc.invalidateQueries({ queryKey: arbiQueryKeys.allConversations() }),\n })\n}\n\n/**\n * Run a work item now, or retry it. A run parked waiting for workspace access (a temporary\n * authorization tier) is granted a temporary, session-scoped key and run again, so the person\n * clicking Run is the approval. Resolves with the updated conversation.\n */\nexport function useRunConversation() {\n const arbi = useArbi()\n const qc = useQueryClient()\n return useMutation({\n mutationFn: (conversationId: string): Promise<ConversationResponse> =>\n arbi.conversations.runWithAuth(conversationId),\n onSuccess: () => qc.invalidateQueries({ queryKey: arbiQueryKeys.allConversations() }),\n })\n}\n\n/**\n * The sign-off person's verdict on work that is ready for review: approve it (done) or send it\n * back with feedback so the agent revises it in the same thread. Resolves with the conversation.\n */\nexport function useReviewConversation() {\n const arbi = useArbi()\n const qc = useQueryClient()\n return useMutation({\n mutationFn: ({\n conversationId,\n review,\n }: {\n conversationId: string\n review: ReviewWorkRequest\n }): Promise<ConversationResponse> => arbi.conversations.review(conversationId, review),\n onSuccess: () => qc.invalidateQueries({ queryKey: arbiQueryKeys.allConversations() }),\n })\n}\n\n/**\n * Ask another person to approve a work item (a real request: they are notified and become its\n * sign-off person). Resolves with the updated conversation.\n */\nexport function useRequestConversationApproval() {\n const arbi = useArbi()\n const qc = useQueryClient()\n return useMutation({\n mutationFn: ({\n conversationId,\n request,\n }: {\n conversationId: string\n request: RequestApprovalRequest\n }): Promise<ConversationResponse> =>\n arbi.conversations.requestApproval(conversationId, request),\n onSuccess: () => qc.invalidateQueries({ queryKey: arbiQueryKeys.allConversations() }),\n })\n}\n\n/** Draft a reviewable plan (goal and acceptance checklist) from an objective. */\nexport function usePlanWork() {\n const arbi = useArbi()\n return useMutation({\n mutationFn: (body: PlanWorkRequest) => arbi.conversations.plan(body),\n })\n}\n\n/**\n * The agent run-session key a parked run waits for the owner to allow (public key and email,\n * non-secret). Enabled only while the run is waiting; 404 otherwise.\n */\nexport function useConversationPendingAuth(\n conversationId: string | undefined,\n options?: { enabled?: boolean }\n) {\n const arbi = useArbi()\n return useQuery({\n queryKey: [...arbiQueryKeys.allConversations(), conversationId ?? '', 'pending-auth'],\n queryFn: () => arbi.conversations.pendingAuth(conversationId as string),\n enabled: (options?.enabled ?? true) && !!conversationId && arbi.isLoggedIn,\n retry: false,\n })\n}\n\n/**\n * A task's history, oldest first (created, run started, handed off, sent back, done, ...). Cached\n * under the conversations prefix, so every task write that invalidates the list refreshes it too.\n * Pass `live` while a run is generating to re-read it every few seconds.\n */\nexport function useConversationActivity(\n conversationId: string | undefined,\n options?: { enabled?: boolean; live?: boolean }\n) {\n const arbi = useArbi()\n return useQuery({\n queryKey: [...arbiQueryKeys.allConversations(), conversationId ?? '', 'activity'],\n queryFn: (): Promise<ActivityResponse[]> =>\n arbi.conversations.activity(conversationId as string),\n enabled: (options?.enabled ?? true) && !!conversationId && arbi.isLoggedIn,\n refetchInterval: options?.live ? 2500 : false,\n })\n}\n\n// ── Workflows ───────────────────────────────────────────────────────────────\n\n/** The caller's workflows (their own, and the ones shared with the open workspace). */\nexport function useWorkflows(options?: { enabled?: boolean; live?: boolean }) {\n const arbi = useArbi()\n return useQuery({\n queryKey: arbiQueryKeys.workflows(),\n queryFn: (): Promise<WorkflowResponse[]> => arbi.workflows.list(),\n refetchInterval: options?.live ? 15_000 : false,\n enabled: options?.enabled ?? arbi.isLoggedIn,\n })\n}\n\n/** Create a workflow from a `CreateWorkflowRequest`. Resolves with the created workflow. */\nexport function useCreateWorkflow() {\n const arbi = useArbi()\n const qc = useQueryClient()\n return useMutation({\n mutationFn: (body: CreateWorkflowRequest): Promise<WorkflowResponse> =>\n arbi.workflows.create(body),\n onSuccess: () => qc.invalidateQueries({ queryKey: arbiQueryKeys.workflows() }),\n })\n}\n\n/** Patch a workflow: pause or resume it (`active`), share it, or change its trigger or action. */\nexport function useUpdateWorkflow() {\n const arbi = useArbi()\n const qc = useQueryClient()\n return useMutation({\n mutationFn: ({\n workflowId,\n patch,\n }: {\n workflowId: string\n patch: UpdateWorkflowRequest\n }): Promise<WorkflowResponse> => arbi.workflows.update(workflowId, patch),\n onSuccess: () => qc.invalidateQueries({ queryKey: arbiQueryKeys.workflows() }),\n })\n}\n\nexport function useDeleteWorkflow() {\n const arbi = useArbi()\n const qc = useQueryClient()\n return useMutation({\n mutationFn: (workflowId: string) => arbi.workflows.delete(workflowId),\n onSuccess: () => qc.invalidateQueries({ queryKey: arbiQueryKeys.workflows() }),\n })\n}\n\n/**\n * Run a workflow now. Resolves with the conversation it created\n * (`conversation_ext_id`), which joins the conversation list.\n */\nexport function useRunWorkflow() {\n const arbi = useArbi()\n const qc = useQueryClient()\n return useMutation({\n mutationFn: (workflowId: string): Promise<WorkflowRunResponse> =>\n arbi.workflows.run(workflowId),\n onSuccess: () =>\n Promise.all([\n qc.invalidateQueries({ queryKey: arbiQueryKeys.workflows() }),\n qc.invalidateQueries({ queryKey: arbiQueryKeys.allConversations() }),\n ]),\n })\n}\n\n// ── Agents ──────────────────────────────────────────────────────────────────\n\n/** Create an agent by name. The one-time `signing_private_key` is in the result. */\nexport function useCreateAgent() {\n const arbi = useArbi()\n const qc = useQueryClient()\n return useMutation({\n mutationFn: (name: string) => arbi.agents.create(name),\n onSuccess: () => qc.invalidateQueries({ queryKey: arbiQueryKeys.agents() }),\n })\n}\n\n/**\n * An agent's pinned config (persona, model, tool switches), or the library default config when\n * `agentExtId` is omitted: edit forms seed from the first, create forms from the second.\n */\nexport function useAgentConfig(agentExtId?: string, options?: { enabled?: boolean }) {\n const arbi = useArbi()\n return useQuery({\n queryKey: arbiQueryKeys.agentConfig(agentExtId),\n queryFn: async () =>\n (agentExtId\n ? await arbi.agents.getConfig(agentExtId)\n : await arbi.agentConfig.get('default')) as AgentConfigSections | null,\n enabled: (options?.enabled ?? true) && arbi.isLoggedIn,\n })\n}\n\n/** The model names an agent may be pinned to. */\nexport function useAgentModels(options?: { enabled?: boolean }) {\n const arbi = useArbi()\n return useQuery({\n queryKey: arbiQueryKeys.models(),\n queryFn: async () => (await arbi.agentConfig.getModels()).models.map((m) => m.model_name),\n enabled: (options?.enabled ?? true) && arbi.isLoggedIn,\n })\n}\n\nexport interface SaveAgentConfigVars {\n agentExtId: string\n /** Config title; defaults to `agent-<agentExtId>`. */\n title?: string\n /**\n * Parameters to set, per section, e.g. `{ Agents: { PERSONA: '...', WEB_SEARCH_ENABLED: true } }`.\n * Merged key by key over the agent's current config (or the default one for a new agent).\n */\n sections: AgentConfigSections\n}\n\n/** Pin a behaviour config to an agent: read its current config, merge `sections` over it, save. */\nexport function useSaveAgentConfig() {\n const arbi = useArbi()\n const qc = useQueryClient()\n return useMutation({\n mutationFn: async ({ agentExtId, title, sections }: SaveAgentConfigVars) => {\n const pinned = (await arbi.agents.getConfig(agentExtId)) as AgentConfigSections | null\n const base = pinned ?? ((await arbi.agentConfig.get('default')) as AgentConfigSections)\n const merged: AgentConfigSections = structuredClone(base)\n for (const [section, params] of Object.entries(sections)) {\n merged[section] = { ...(merged[section] ?? {}), ...params }\n }\n return arbi.agentConfig.save({\n ...merged,\n agent_ext_id: agentExtId,\n title: title ?? `agent-${agentExtId}`,\n } as never)\n },\n onSuccess: (_saved, { agentExtId }) =>\n Promise.all([\n qc.invalidateQueries({ queryKey: arbiQueryKeys.configs() }),\n qc.invalidateQueries({ queryKey: arbiQueryKeys.agentConfig(agentExtId) }),\n // The agent list shows the pinned persona/model, so it refreshes too.\n qc.invalidateQueries({ queryKey: arbiQueryKeys.agents() }),\n ]),\n })\n}\n\n/** The workspaces an agent can currently open (`permanent` tells standing from temporary). */\nexport function useAgentWorkspaces(\n agentExtId: string | undefined,\n options?: { enabled?: boolean }\n) {\n const arbi = useArbi()\n return useQuery({\n queryKey: arbiQueryKeys.agentWorkspaces(agentExtId ?? ''),\n queryFn: () => arbi.agents.listWorkspaces(agentExtId as string),\n enabled: (options?.enabled ?? true) && !!agentExtId && arbi.isLoggedIn,\n })\n}\n\n/** How an agent is given a workspace. */\nexport type AgentAccessMode =\n /** A standing member: the agent can open the workspace while the owner is away. */\n | { kind: 'standing' }\n /** A TTL'd, session-scoped key: gone when the run session ends. `ttlSeconds` omitted = default. */\n | { kind: 'temporary'; ttlSeconds?: number }\n\nexport interface GrantAgentAccessVars {\n agentExtId: string\n workspaceId: string\n /** Default `{ kind: 'standing' }`. */\n mode?: AgentAccessMode\n}\n\n/**\n * Give an agent access to a workspace you own. Standing access adds the agent as a member without\n * switching the open workspace; temporary access mints the agent's run session and deposits a\n * session-scoped key on it (the `session_pubkey_b64` path).\n */\nexport function useGrantAgentAccess() {\n const arbi = useArbi()\n const qc = useQueryClient()\n return useMutation({\n mutationFn: async ({\n agentExtId,\n workspaceId,\n mode = { kind: 'standing' },\n }: GrantAgentAccessVars) => {\n if (mode.kind === 'temporary') {\n return arbi.agents.grantTemporaryAccess(agentExtId, workspaceId, mode.ttlSeconds)\n }\n const agent = (await arbi.agents.list()).find((a) => a.external_id === agentExtId)\n if (!agent?.email) throw new Error(\"The agent's address is unknown.\")\n return arbi.workspaces.grantAccess({ workspaceId, emails: [agent.email] })\n },\n onSuccess: (_res, { agentExtId }) =>\n qc.invalidateQueries({ queryKey: arbiQueryKeys.agentWorkspaces(agentExtId) }),\n })\n}\n\n/** Take an agent out of a workspace (owner only). Restores the previously open workspace. */\nexport function useRevokeAgentAccess() {\n const arbi = useArbi()\n const qc = useQueryClient()\n return useMutation({\n mutationFn: async ({\n agentExtId,\n workspaceId,\n }: {\n agentExtId: string\n workspaceId: string\n }) => {\n const previous = arbi.hasWorkspace ? arbi.getWorkspaceId() : null\n await arbi.selectWorkspace(workspaceId)\n try {\n await arbi.workspaces.removeUsers([agentExtId])\n } finally {\n if (previous && previous !== workspaceId) await arbi.selectWorkspace(previous)\n }\n },\n onSuccess: (_res, { agentExtId }) =>\n qc.invalidateQueries({ queryKey: arbiQueryKeys.agentWorkspaces(agentExtId) }),\n })\n}\n\n// ── Skills ──────────────────────────────────────────────────────────────────\n\n/**\n * The skills the user can run (own plus the shared marketplace), metadata only. Skills live in the\n * deployment marketplace, so the list does not depend on the open workspace.\n */\nexport function useSkills(options?: {\n enabled?: boolean\n includeHidden?: boolean\n live?: boolean\n}) {\n const arbi = useArbi()\n return useQuery({\n queryKey: [...arbiQueryKeys.skills(), options?.includeHidden ?? false] as const,\n queryFn: () => arbi.assistant.listSkills({ includeHidden: options?.includeHidden }),\n refetchInterval: options?.live ? 5000 : false,\n enabled: (options?.enabled ?? true) && arbi.isLoggedIn,\n staleTime: 30_000,\n })\n}\n\n/** Upload skill files through the same document path as the main application. */\nexport function useUploadSkillFiles() {\n const arbi = useArbi()\n const qc = useQueryClient()\n return useMutation({\n mutationFn: async (\n entries: { folder: string; fileName: string; content: Blob }[]\n ): Promise<{ doc_ext_ids?: string[] }[]> => {\n if (!entries.length) throw new Error('Choose at least one skill file.')\n for (const entry of entries) {\n if (\n !/^skills\\/[a-z0-9][a-z0-9_-]*(?:\\/[^/]+)*$/.test(entry.folder) ||\n entry.folder.split('/').some((segment) => segment === '..' || segment === '.')\n )\n throw new Error('Skill files need a folder under skills/<name>.')\n }\n const results = []\n for (const entry of entries) {\n const result = await arbi.documents.uploadFile(entry.content, entry.fileName, {\n folder: entry.folder,\n wpType: 'skill',\n })\n if (result.skipped?.length)\n throw new Error(\n result.skipped.map((file) => `${file.file_name}: ${file.reason}`).join('; ')\n )\n results.push(result)\n }\n return results\n },\n onSuccess: () => qc.invalidateQueries({ queryKey: arbiQueryKeys.skills() }),\n })\n}\n\n/** Start the person's assistant as reviewable work, then resolve its persisted thread. */\nexport function useStartWorkQuery() {\n const arbi = useArbi()\n const qc = useQueryClient()\n return useMutation({\n mutationFn: async ({\n question,\n ...options\n }: Parameters<typeof arbi.assistant.submit>[1] & { question: string }) => {\n const response = await arbi.assistant.submit(question, options)\n for (let attempt = 0; attempt < 30; attempt++) {\n if (attempt) await new Promise((resolve) => setTimeout(resolve, 500))\n try {\n const message = await arbi.conversations.getMessage(response.id)\n if (message.conversation_ext_id)\n return { conversationId: message.conversation_ext_id, responseId: response.id }\n } catch (error) {\n if (!(error && typeof error === 'object' && 'status' in error && error.status === 404))\n throw error\n }\n }\n throw new Error(\n `The run ${response.id} started, but its thread is not available yet. Do not submit it again.`\n )\n },\n onSuccess: () => qc.invalidateQueries({ queryKey: arbiQueryKeys.allConversations() }),\n })\n}\n\n/** Independent agent login status, polled while its controls are visible. */\nexport function useAgentSession(agentId: string | undefined, options?: { enabled?: boolean }) {\n const arbi = useArbi()\n return useQuery({\n queryKey: ['arbi', 'agent-session', agentId],\n queryFn: () => arbi.agents.getSession(agentId!),\n enabled: !!agentId && arbi.isLoggedIn && (options?.enabled ?? true),\n refetchInterval: 5000,\n })\n}\nexport function useAgentChats(agentId: string | undefined) {\n const arbi = useArbi()\n return useQuery({\n queryKey: ['arbi', 'agent-chats', agentId],\n queryFn: () => arbi.agents.listChats(agentId!),\n enabled: !!agentId && arbi.isLoggedIn,\n refetchInterval: 5000,\n })\n}\nexport function useStartAgentSession() {\n const arbi = useArbi()\n const cache = useQueryClient()\n return useMutation({\n mutationFn: ({ agentId, workspaceId }: { agentId: string; workspaceId?: string }) =>\n arbi.agents.startSession(agentId, workspaceId),\n onSuccess: () => cache.invalidateQueries({ queryKey: ['arbi', 'agent-session'] }),\n })\n}\nexport function useCloseAgentSession() {\n const arbi = useArbi()\n const cache = useQueryClient()\n return useMutation({\n mutationFn: (agentId: string) => arbi.agents.closeSession(agentId),\n onSuccess: () => cache.invalidateQueries({ queryKey: ['arbi', 'agent-session'] }),\n })\n}\n","/**\n * Citation data for a chat answer: the SDK's `resolveCitations` / `summarizeCitations` joined into\n * one plain, serialisable shape per citation number, so a surface can show the source document,\n * page and passage for `[statement](#cite-N)` without touching SDK types.\n */\nimport {\n resolveCitations,\n summarizeCitations,\n type MessageMetadataPayload,\n} from '@arbidocs/sdk/browser'\n\nexport interface ArbiChatPassage {\n id: string\n /** The source document's id, when the backend reports it (what \"open document\" needs). */\n documentId: string | null\n documentTitle: string\n page: number | null\n text: string\n}\n\nexport interface ArbiChatCitation {\n /** The number in `(#cite-N)`. */\n num: string\n /** The statement the model cited. */\n statement: string\n /** Title of the first source document. */\n documentTitle: string\n /** Page of the first passage. */\n page: number | null\n passages: ArbiChatPassage[]\n}\n\n/** A passage as one readable line: whitespace folded, leading markdown list/heading marks dropped. */\nfunction previewText(content: string): string {\n return content\n .replace(/\\s+/g, ' ')\n .trim()\n .replace(/^(?:(?:[-*•>]|#{1,6})\\s+)+/, '')\n}\n\n/** The citations of a message's `tools` (stored history) or of streamed metadata. */\nexport function toChatCitations(\n source: { tools?: object | null } | null | undefined\n): ArbiChatCitation[] {\n if (!source?.tools) return []\n // Stored messages and streamed metadata carry the same `tools` map.\n const resolved = resolveCitations(source as MessageMetadataPayload)\n const summaries = summarizeCitations(resolved)\n return resolved.map((r, i) => {\n const summary = summaries[i]\n return {\n num: r.citationNum,\n statement: summary.statement,\n documentTitle: summary.docTitle,\n page: summary.pageNumber,\n passages: r.chunks.map((chunk) => ({\n id: chunk.metadata.chunk_ext_id,\n documentId: chunk.metadata.doc_ext_id ?? null,\n documentTitle: chunk.metadata.doc_title ?? summary.docTitle,\n page: chunk.metadata.page_number ?? null,\n text: previewText(chunk.content),\n })),\n }\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 are the workspace's stored conversations (backend titles, newest first) plus the new\n * chat being written: opening an old one loads its messages (citations included), the first\n * question of a new chat creates its conversation on the backend, follow-ups chain through the\n * previous response id so each thread keeps its context. Everything resets when `workspaceId`\n * changes. `stop()` aborts the running answer.\n */\nimport { useCallback, useEffect, useMemo, useRef, useState } from 'react'\nimport { useArbi } from '../useArbi'\nimport { useAgentChats } from '../workforce'\nimport { useAssistantQuery, useConversations, useConversationThreads, useDocuments } from '../hooks'\nimport { toChatCitations, type ArbiChatCitation } from './citations'\nimport type { QueryOptions } from '@arbidocs/sdk/browser'\n\nexport type { ArbiChatCitation, ArbiChatPassage } from './citations'\n\nexport type ArbiChatRole = 'user' | 'assistant'\nexport type ArbiChatMessageStatus = 'streaming' | 'complete' | 'error'\n\nexport interface ArbiChatMessage {\n mentions?: QueryOptions['mentions']\n authorId?: string\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 /** The sources behind `[statement](#cite-N)` marks in `content`. */\n citations?: ArbiChatCitation[]\n /** The reader stopped the answer; `content` is what had streamed. */\n stopped?: boolean\n /** The backend id of a finished assistant answer: what a follow-up chains from. */\n responseId?: string\n}\n\nexport interface ArbiChatThread {\n id: string\n /** The backend title, else 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 /** Use an owned agent's independent session, history and sandbox files. */\n agentId?: string\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 (used until the backend has titled the conversation). Default 48. */\n titleLength?: number\n /**\n * When the answer stream ends without the terminal `response.completed` event (a dropped\n * connection, a stalled run), the stored message is polled this often (ms) and for at most\n * `timeoutMs` before the turn is shown as failed with a Retry. Default 3000 / 120000.\n */\n streamRecovery?: { intervalMs?: number; timeoutMs?: number }\n}\n\nexport interface ArbiChat {\n assistantMode: 'always' | 'mentioned'\n isUpdatingAssistantMode: boolean\n isPostingComment: boolean\n setAssistantMode: (mode: 'always' | 'mentioned') => Promise<void>\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 /** A stored conversation's messages are loading. */\n isLoadingThread: boolean\n /** The conversation list is loading. */\n isLoadingThreads: boolean\n /** Loading or deleting a stored conversation failed. */\n historyError: string | null\n documents: ArbiChatDocument[]\n isLoadingDocuments: boolean\n isUploading: boolean\n uploadError: string | null\n send: (text: string, options?: { mentions?: QueryOptions['mentions'] }) => Promise<void>\n /** Re-ask the question whose answer failed. */\n retry: () => Promise<void>\n /** Abort the running answer; what streamed so far stays, marked stopped. */\n stop: () => void\n selectThread: (id: string) => void\n newThread: () => void\n /** Deletes the conversation on the backend too. */\n deleteThread: (id: string) => void\n toggleDocument: (id: string) => void\n selectAllDocuments: () => void\n upload: (files: File[]) => Promise<void>\n}\n\ninterface LocalChatMessage extends ArbiChatMessage {\n pendingHistory?: boolean\n storedId?: string\n questionId?: string\n}\n\ninterface ThreadState {\n assistantMode?: 'always' | 'mentioned'\n /** Stable local key: never changes, even when the backend conversation appears. */\n key: string\n /** The backend conversation, once there is one. The public thread id is this, else `key`. */\n conversationId: string | null\n /** Local title (the first question) until the backend has one. */\n title: string\n messages: LocalChatMessage[]\n responseId: string | null\n /** False for a stored conversation whose messages have not been fetched yet. */\n isLoaded: boolean\n}\n\nlet counter = 0\nconst nextId = (prefix: string) =>\n `${prefix}-${Date.now().toString(36)}-${(counter++).toString(36)}`\n\nconst emptyThread = (): ThreadState => ({\n key: nextId('thread'),\n conversationId: null,\n title: '',\n messages: [],\n responseId: null,\n isLoaded: true,\n})\n\nconst storedThread = (conversationId: string): ThreadState => ({\n key: conversationId,\n conversationId,\n title: '',\n messages: [],\n responseId: null,\n isLoaded: false,\n})\n\nconst publicId = (t: ThreadState) => t.conversationId ?? t.key\n\ntype StoredMessage = {\n mentions?: QueryOptions['mentions']\n created_by_ext_id?: string | null\n external_id: string\n role: 'user' | 'assistant' | 'system'\n content: string\n status: string\n tools?: object\n}\n\nconst UNFINISHED_STATUSES: ReadonlySet<string> = new Set(['failed', 'in_progress', 'queued'])\nconst FAILED_MESSAGE = 'The assistant request failed.'\nconst UNFINISHED_MESSAGE = 'The answer did not finish. Try again.'\n\n/** A stored assistant message that never reached `completed` (failed, or still `in_progress`/`queued`). */\nconst isUnfinished = (m: StoredMessage) => UNFINISHED_STATUSES.has(m.status)\n\n/**\n * A stored conversation's primary thread (the longest) as chat messages. An assistant answer that\n * never finished is kept as a failed message (with Retry) — never dropped or shown as an empty bubble.\n */\nfunction messagesFromHistory(\n history: ReadonlyArray<StoredMessage>,\n live = false\n): ArbiChatMessage[] {\n return history\n .filter(\n (m) =>\n m.role !== 'system' &&\n (m.content.trim() !== '' ||\n (m.role === 'assistant' && (isUnfinished(m) || m.status === 'cancelled')))\n )\n .map((m) => {\n if (m.role === 'user') {\n return {\n id: m.external_id,\n role: 'user',\n content: m.content,\n status: 'complete',\n ...(m.created_by_ext_id ? { authorId: m.created_by_ext_id } : {}),\n ...(m.mentions?.length ? { mentions: m.mentions } : {}),\n }\n }\n const citations = toChatCitations({ tools: m.tools })\n const unfinished = isUnfinished(m)\n const runningElsewhere = live && (m.status === 'in_progress' || m.status === 'queued')\n return {\n id: m.external_id,\n role: 'assistant',\n content: m.content,\n status: runningElsewhere ? 'streaming' : unfinished ? 'error' : 'complete',\n ...(m.status === 'cancelled' ? { stopped: true } : {}),\n ...(unfinished && !runningElsewhere\n ? { error: m.status === 'failed' ? FAILED_MESSAGE : UNFINISHED_MESSAGE }\n : {}),\n ...(unfinished ? {} : { responseId: m.external_id }),\n ...(citations.length > 0 ? { citations } : {}),\n }\n })\n}\n\n/** Accept shared history without dropping local turns the server has not acknowledged yet. */\nfunction mergeHistory(history: ArbiChatMessage[], local: LocalChatMessage[]): LocalChatMessage[] {\n const merged: LocalChatMessage[] = [...history]\n for (const message of local) {\n if (!message.pendingHistory) continue\n const question = local.find((candidate) => candidate.id === message.questionId)\n const pending =\n question?.storedId && history.some((stored) => stored.id === question.storedId)\n ? { ...message, questionId: question.storedId }\n : message\n const storedId = message.storedId ?? message.responseId ?? message.id\n const index = merged.findIndex((stored) => stored.id === storedId)\n if (index < 0) merged.push(pending)\n else if (message.role === 'assistant' && merged[index].status === 'streaming') {\n // An older snapshot must not erase a finished or failed local answer.\n merged[index] = pending\n }\n }\n return merged\n}\n\n/** Failed or stalled answers must never become the parent of the next question. */\nfunction chainId(messages: ReadonlyArray<ArbiChatMessage>): string | null {\n for (let i = messages.length - 1; i >= 0; i--) {\n const m = messages[i]\n if (m.role === 'assistant' && m.status === 'complete' && m.responseId) return m.responseId\n }\n return null\n}\n\nconst sleep = (ms: number) => new Promise<void>((resolve) => setTimeout(resolve, ms))\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)\nconst isAbort = (e: unknown) => e instanceof DOMException && e.name === 'AbortError'\n\n/** The backend titles a conversation a moment after its first answer: look again a few times. */\nconst TITLE_REFRESH_DELAYS_MS = [2500, 6000, 12000]\n\nexport function useArbiChat(options: UseArbiChatOptions = {}): ArbiChat {\n const { workspaceId, agentId, model, titleLength = 48, streamRecovery } = options\n const recoveryIntervalMs = streamRecovery?.intervalMs ?? 3000\n const recoveryTimeoutMs = streamRecovery?.timeoutMs ?? 120000\n const arbi = useArbi()\n const { data: docs = [], isLoading: isLoadingDocuments, refetch } = useDocuments(workspaceId)\n const ordinaryHistory = useConversations(workspaceId, { enabled: !agentId, live: true })\n const agentHistory = useAgentChats(agentId)\n const stored = useMemo(\n () =>\n agentId\n ? (agentHistory.data ?? [])\n .filter((chat) => chat.workspace_ext_id === workspaceId)\n .map((chat) => ({\n external_id: chat.conversation_ext_id,\n title: chat.title,\n updated_at: chat.updated_at,\n message_count: 1,\n status: null,\n assistant_mode: 'always' as const,\n }))\n : (ordinaryHistory.data ?? []),\n [agentId, agentHistory.data, ordinaryHistory.data, workspaceId]\n )\n const isLoadingThreads = agentId ? agentHistory.isLoading : ordinaryHistory.isLoading\n const refetchConversations = agentId ? agentHistory.refetch : ordinaryHistory.refetch\n const query = useAssistantQuery()\n const { mutateAsync } = query\n\n const [stagedFiles, setStagedFiles] = useState<Array<{ id: string; name: string }>>([])\n const [threads, setThreads] = useState<ThreadState[]>(() => [emptyThread()])\n const [activeKey, setActiveKey] = useState(() => threads[0].key)\n const [deselected, setDeselected] = useState<ReadonlySet<string>>(new Set())\n const [isRunning, setIsRunning] = useState(false)\n const [isPostingComment, setIsPostingComment] = useState(false)\n const [isUpdatingAssistantMode, setIsUpdatingAssistantMode] = useState(false)\n const [isUploading, setIsUploading] = useState(false)\n const [uploadError, setUploadError] = useState<string | null>(null)\n const [historyError, setHistoryError] = useState<string | null>(null)\n const abortRef = useRef<AbortController | null>(null)\n const runIdRef = useRef<string | null>(null)\n const stopRequestedRef = useRef(false)\n const timersRef = useRef<ReturnType<typeof setTimeout>[]>([])\n\n useEffect(() => {\n const timers = timersRef.current\n return () => timers.forEach(clearTimeout)\n }, [])\n\n // Everything is scoped to one workspace: start clean when it changes.\n const chatScope = `${workspaceId ?? ''}:${agentId ?? ''}`\n const scopeRef = useRef(chatScope)\n useEffect(() => {\n if (scopeRef.current === chatScope) return\n scopeRef.current = chatScope\n setStagedFiles([])\n const fresh = emptyThread()\n setThreads([fresh])\n setActiveKey(fresh.key)\n setDeselected(new Set())\n setUploadError(null)\n setHistoryError(null)\n }, [chatScope])\n\n const active = threads.find((t) => t.key === activeKey) ?? threads[0]\n const assistantMode =\n active.assistantMode ??\n stored.find((c) => c.external_id === active.conversationId)?.assistant_mode ??\n 'always'\n\n // The list: the chat being written, then the workspace's stored conversations, newest first\n // (a stored conversation we hold messages for is shown from our copy, with the backend title).\n const threadEntries = useMemo(() => {\n const storedIds = new Set(stored.map((c) => c.external_id))\n const byConversation = new Map(\n threads.filter((t) => t.conversationId).map((t) => [t.conversationId as string, t])\n )\n const fresh = threads.filter((t) => !t.conversationId)\n const justSaved = threads.filter((t) => t.conversationId && !storedIds.has(t.conversationId))\n const persisted = [...stored]\n .filter((c) => c.status != null || c.message_count > 0 || byConversation.has(c.external_id))\n .sort((a, b) => b.updated_at.localeCompare(a.updated_at))\n .map((c) => {\n const local = byConversation.get(c.external_id)\n return {\n key: local?.key ?? c.external_id,\n id: c.external_id,\n title: c.title || local?.title || '',\n }\n })\n return [\n ...fresh.map((t) => ({ key: t.key, id: publicId(t), title: t.title })),\n ...justSaved.map((t) => ({ key: t.key, id: publicId(t), title: t.title })),\n ...persisted,\n ]\n }, [threads, stored])\n\n const liveHistory =\n assistantMode === 'mentioned' ||\n stored.some(\n (conversation) =>\n conversation.external_id === active.conversationId && conversation.status === 'generating'\n ) ||\n active.messages.some((message) => message.status === 'streaming')\n const needsLoad = !!active.conversationId && !active.isLoaded\n const loaded = useConversationThreads(workspaceId, active.conversationId ?? undefined, {\n enabled: needsLoad || (liveHistory && !isRunning && !isPostingComment),\n live: liveHistory,\n })\n const refetchThread = loaded.refetch\n const selectedStored = stored.find(\n (conversation) => conversation.external_id === active.conversationId\n )\n const historyRevision = selectedStored\n ? `${selectedStored.external_id}:${selectedStored.updated_at}:${selectedStored.message_count}:${selectedStored.status}`\n : undefined\n const observedHistoryRevision = useRef<string | undefined>(undefined)\n useEffect(() => {\n const previous = observedHistoryRevision.current\n observedHistoryRevision.current = historyRevision\n // Completion can reach the list after an initial history containing only the question.\n // Fetch again when stored metadata advances, even if the run has already become ready.\n if (\n previous &&\n previous !== historyRevision &&\n active.isLoaded &&\n !isRunning &&\n !isPostingComment\n )\n void refetchThread()\n }, [historyRevision, active.isLoaded, isRunning, isPostingComment, refetchThread])\n useEffect(() => {\n const data = loaded.data\n if (\n isRunning ||\n isPostingComment ||\n !data ||\n data.conversation_ext_id !== active.conversationId\n )\n return\n const primary = [...data.threads].sort((a, b) => b.history.length - a.history.length)[0]\n const messages = messagesFromHistory(primary?.history ?? [], liveHistory)\n setThreads((all) =>\n all.map((t) =>\n t.key === active.key\n ? (() => {\n const merged = mergeHistory(messages, t.messages)\n return {\n ...t,\n isLoaded: true,\n assistantMode: data.assistant_mode,\n messages: merged,\n responseId: chainId(merged),\n }\n })()\n : t\n )\n )\n }, [\n loaded.data,\n liveHistory,\n needsLoad,\n active.conversationId,\n active.key,\n assistantMode,\n isRunning,\n isPostingComment,\n ])\n useEffect(() => {\n if (loaded.error)\n setHistoryError(messageOf(loaded.error, 'The conversation could not be loaded.'))\n }, [loaded.error])\n\n const selectedIds = useMemo(\n () =>\n (agentId ? [] : docs)\n .map((d) => d.external_id)\n .filter((id): id is string => !!id && !deselected.has(id)),\n [docs, deselected, agentId]\n )\n const documents = useMemo<ArbiChatDocument[]>(\n () =>\n agentId\n ? stagedFiles.map((file) => ({ ...file, isSelected: !deselected.has(file.id) }))\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, agentId, stagedFiles]\n )\n\n const patchThread = useCallback(\n (key: string, patch: (t: ThreadState) => ThreadState) =>\n setThreads((all) => all.map((t) => (t.key === key ? patch(t) : t))),\n []\n )\n const patchMessage = useCallback(\n (threadKey: string, messageId: string, patch: Partial<LocalChatMessage>) =>\n patchThread(threadKey, (t) => ({\n ...t,\n messages: t.messages.map((m) => (m.id === messageId ? { ...m, ...patch } : m)),\n })),\n [patchThread]\n )\n\n const refreshTitles = useCallback(() => {\n void refetchConversations()\n timersRef.current.forEach(clearTimeout)\n timersRef.current = TITLE_REFRESH_DELAYS_MS.map((delay) =>\n setTimeout(() => void refetchConversations(), delay)\n )\n }, [refetchConversations])\n\n /**\n * Poll the stored assistant message until it settles. `completed` carries the stored answer,\n * `failed` a run the backend gave up on, `null` one still unfinished when the time is up (or\n * unknowable: no conversation yet, or the read keeps failing).\n */\n const recoverStoredAnswer = useCallback(\n async (\n conversationId: string | null,\n messageId: string | null,\n signal: AbortSignal\n ): Promise<{ kind: 'completed'; message: StoredMessage } | { kind: 'failed' } | null> => {\n if (!conversationId || !messageId) return null\n const deadline = Date.now() + recoveryTimeoutMs\n let failedReads = 0\n for (;;) {\n try {\n const { threads: all } = await arbi.conversations.getThreads(conversationId)\n const found = all\n .flatMap((t) => t.history as ReadonlyArray<StoredMessage>)\n .find((m) => m.external_id === messageId)\n if (found?.status === 'completed' && found.content.trim() !== '') {\n return { kind: 'completed', message: found }\n }\n if (found?.status === 'failed') return { kind: 'failed' }\n failedReads = 0\n } catch {\n // One failed read is not a verdict; a stored message that stays unreadable is.\n if (++failedReads >= 3) return null\n }\n if (signal.aborted || Date.now() + recoveryIntervalMs > deadline) return null\n await sleep(recoveryIntervalMs)\n }\n },\n [arbi, recoveryIntervalMs, recoveryTimeoutMs]\n )\n\n const cancelNativeRun = useCallback(\n async (responseId: string, controller: AbortController) => {\n try {\n await arbi.assistant.cancelRun(responseId)\n if (abortRef.current === controller) controller.abort()\n } catch (error) {\n stopRequestedRef.current = false\n setHistoryError(messageOf(error, 'The agent run could not be stopped.'))\n }\n },\n [arbi]\n )\n\n const ask = useCallback(\n async (thread: ThreadState, text: string, mentions?: QueryOptions['mentions']) => {\n const userMessage: LocalChatMessage = {\n pendingHistory: true,\n ...(mentions?.length ? { mentions } : {}),\n id: nextId('msg'),\n role: 'user',\n content: text,\n status: 'complete',\n }\n const answer: LocalChatMessage = {\n pendingHistory: true,\n questionId: userMessage.id,\n id: nextId('msg'),\n role: 'assistant',\n content: '',\n status: 'streaming',\n }\n patchThread(thread.key, (t) => ({\n ...t,\n title: t.title || titleFromQuestion(text, titleLength),\n messages: [...t.messages, userMessage, answer],\n }))\n const controller = new AbortController()\n abortRef.current = controller\n runIdRef.current = null\n stopRequestedRef.current = false\n setIsRunning(true)\n let buffer = ''\n let steps = 0\n let streamError: string | null = null\n let conversationId = thread.conversationId\n let backendMessageId: string | null = null\n // A turn that does not finish must not become the parent of the next question.\n const revertChain = () =>\n patchThread(thread.key, (t) => ({ ...t, responseId: chainId(t.messages) }))\n const fail = (error: string, content?: string) => {\n patchMessage(thread.key, answer.id, {\n status: 'error',\n error,\n ...(content !== undefined ? { content } : {}),\n })\n revertChain()\n }\n try {\n const lastMessage = thread.messages[thread.messages.length - 1]\n const parentId =\n lastMessage?.role === 'user' && (lastMessage.storedId || !lastMessage.pendingHistory)\n ? (lastMessage.storedId ?? lastMessage.id)\n : thread.responseId\n const result = await mutateAsync({\n question:\n agentId && stagedFiles.some((file) => !deselected.has(file.id))\n ? text +\n '\\n\\nSource files staged in your sandbox:\\n' +\n stagedFiles\n .filter((file) => !deselected.has(file.id))\n .map((file) => `${file.name}: ${file.id}`)\n .join('\\n')\n : text,\n ...(agentId ? { agentId, workspaceId } : {}),\n docIds: selectedIds,\n previousResponseId: parentId,\n ...(thread.conversationId ? { conversationId: thread.conversationId } : {}),\n ...(!thread.conversationId && thread.assistantMode === 'mentioned'\n ? { assistantMode: 'mentioned' as const }\n : {}),\n ...(mentions?.length ? { mentions } : {}),\n model,\n signal: controller.signal,\n onStreamStart: (data) => {\n // Chain follow-ups even when this answer is stopped before it completes.\n if (data.assistant_message_ext_id) {\n backendMessageId = data.assistant_message_ext_id\n runIdRef.current = backendMessageId\n if (agentId && stopRequestedRef.current)\n void cancelNativeRun(backendMessageId, controller)\n patchMessage(thread.key, answer.id, { storedId: backendMessageId })\n patchThread(thread.key, (t) => ({\n ...t,\n responseId: data.assistant_message_ext_id ?? t.responseId,\n }))\n }\n },\n onUserMessage: (ev) => {\n conversationId = conversationId ?? ev.conversation_ext_id\n patchMessage(thread.key, userMessage.id, { storedId: ev.external_id })\n // The first question of a new chat creates its conversation on the backend.\n patchThread(thread.key, (t) => ({\n ...t,\n conversationId: t.conversationId ?? ev.conversation_ext_id,\n }))\n },\n onMetadata: (meta) => {\n const citations = toChatCitations(meta)\n if (citations.length > 0) patchMessage(thread.key, answer.id, { citations })\n },\n onToken: (token) => {\n buffer += token\n patchMessage(thread.key, 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.key, 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 const messageId = result.assistantMessageExtId ?? backendMessageId\n if (failure && !finalText) {\n fail(failure)\n } else if (!result.completed && !failure) {\n // The stream ended without a terminal event: the run may have finished (or still be\n // running) server-side. Ask the stored message instead of calling an empty bubble done.\n const stored = await recoverStoredAnswer(conversationId, messageId, controller.signal)\n if (stored?.kind === 'completed') {\n const citations = toChatCitations({ tools: stored.message.tools })\n patchMessage(thread.key, answer.id, {\n status: 'complete',\n content: stored.message.content,\n stepCount: result.agentSteps.length || steps || undefined,\n responseId: stored.message.external_id,\n ...(citations.length > 0 ? { citations } : {}),\n })\n patchThread(thread.key, (t) => ({ ...t, responseId: stored.message.external_id }))\n } else if (controller.signal.aborted) {\n patchMessage(thread.key, answer.id, {\n status: 'complete',\n content: finalText,\n stopped: true,\n })\n } else {\n fail(\n stored?.kind === 'failed' ? FAILED_MESSAGE : UNFINISHED_MESSAGE,\n finalText || undefined\n )\n }\n } else {\n const citations = toChatCitations(result.metadata)\n patchMessage(thread.key, answer.id, {\n status: 'complete',\n content: finalText,\n stepCount: result.agentSteps.length || steps || undefined,\n ...(messageId ? { responseId: messageId } : {}),\n ...(citations.length > 0 ? { citations } : {}),\n })\n patchThread(thread.key, (t) => ({ ...t, responseId: messageId ?? t.responseId }))\n }\n } catch (e) {\n if (controller.signal.aborted || isAbort(e)) {\n patchMessage(thread.key, answer.id, {\n status: 'complete',\n content: buffer,\n stopped: true,\n })\n } else {\n fail(messageOf(e, FAILED_MESSAGE))\n }\n } finally {\n if (abortRef.current === controller) abortRef.current = null\n setIsRunning(false)\n refreshTitles()\n }\n },\n [\n mutateAsync,\n patchMessage,\n patchThread,\n refreshTitles,\n recoverStoredAnswer,\n selectedIds,\n model,\n titleLength,\n agentId,\n cancelNativeRun,\n workspaceId,\n stagedFiles,\n deselected,\n ]\n )\n\n const send = useCallback(\n async (text: string, options?: { mentions?: QueryOptions['mentions'] }) => {\n const trimmed = text.trim()\n if (!trimmed || isRunning || isPostingComment || isUpdatingAssistantMode || !active.isLoaded)\n return\n setHistoryError(null)\n if (\n assistantMode === 'mentioned' &&\n !options?.mentions?.some((m) => m.type === 'assistant')\n ) {\n setIsPostingComment(true)\n setHistoryError(null)\n try {\n const saved = await arbi.conversations.postMessage({\n content: trimmed,\n assistant_mode: 'mentioned',\n mentions: options?.mentions ?? [],\n ...(active.conversationId ? { conversation_ext_id: active.conversationId } : {}),\n })\n patchThread(active.key, (t) => ({\n ...t,\n conversationId: saved.conversation_ext_id,\n title: t.title || titleFromQuestion(trimmed, titleLength),\n assistantMode: 'mentioned',\n responseId: saved.external_id,\n messages: [\n ...t.messages,\n {\n pendingHistory: true,\n id: saved.external_id,\n role: 'user',\n content: saved.content,\n status: 'complete',\n ...(saved.created_by_ext_id ? { authorId: saved.created_by_ext_id } : {}),\n },\n ],\n }))\n await refetchConversations()\n if (active.conversationId) await refetchThread()\n } catch (e) {\n setHistoryError(messageOf(e, 'The comment could not be posted.'))\n throw e\n } finally {\n setIsPostingComment(false)\n }\n return\n }\n if (active.messages.some((message) => message.status === 'streaming')) {\n const message =\n 'An assistant reply is already running in this thread. You can still post a comment.'\n setHistoryError(message)\n throw new Error(message)\n }\n await ask(active, trimmed, options?.mentions)\n },\n [\n active,\n ask,\n isRunning,\n isPostingComment,\n isUpdatingAssistantMode,\n assistantMode,\n arbi,\n patchThread,\n titleLength,\n refetchConversations,\n refetchThread,\n ]\n )\n\n const setAssistantMode = useCallback(\n async (mode: 'always' | 'mentioned') => {\n if (isRunning || isPostingComment || isUpdatingAssistantMode) return\n setIsUpdatingAssistantMode(true)\n setHistoryError(null)\n try {\n if (active.conversationId) {\n await arbi.conversations.setAssistantMode(active.conversationId, mode)\n await refetchThread()\n }\n patchThread(active.key, (t) => ({ ...t, assistantMode: mode }))\n await refetchConversations()\n } catch (e) {\n setHistoryError(messageOf(e, 'The assistant mode could not be changed.'))\n } finally {\n setIsUpdatingAssistantMode(false)\n }\n },\n [\n active,\n arbi,\n patchThread,\n refetchConversations,\n refetchThread,\n isRunning,\n isPostingComment,\n isUpdatingAssistantMode,\n ]\n )\n\n const stop = useCallback(() => {\n const controller = abortRef.current\n if (!controller) return\n if (!agentId) {\n controller.abort()\n return\n }\n stopRequestedRef.current = true\n if (runIdRef.current) void cancelNativeRun(runIdRef.current, controller)\n }, [agentId, cancelNativeRun])\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 = failed?.questionId\n ? messages.find((message) => message.id === failed.questionId)\n : messages[messages.length - 2]\n if (failed?.status !== 'error' || question?.role !== 'user') return\n const rest = messages.filter(\n (message) => message.id !== failed.id && message.id !== question.id\n )\n const trimmed: ThreadState = { ...active, messages: rest, responseId: chainId(rest) }\n patchThread(active.key, () => trimmed)\n await ask(trimmed, question.content, question.mentions)\n }, [active, ask, isRunning, patchThread])\n\n const newThread = useCallback(() => {\n setHistoryError(null)\n // One blank chat at most: reuse it instead of piling up empty ones.\n const blank = threads.find((t) => !t.conversationId && t.messages.length === 0)\n if (blank) {\n setActiveKey(blank.key)\n return\n }\n const fresh = emptyThread()\n setThreads((all) => [fresh, ...all])\n setActiveKey(fresh.key)\n }, [threads])\n\n const selectThread = useCallback(\n (id: string) => {\n const entry = threadEntries.find((e) => e.id === id)\n if (!entry) return\n setHistoryError(null)\n setThreads((all) => (all.some((t) => t.key === entry.key) ? all : [...all, storedThread(id)]))\n setActiveKey(entry.key)\n },\n [threadEntries]\n )\n\n const deleteThread = useCallback(\n (id: string) => {\n const entry = threadEntries.find((e) => e.id === id)\n if (!entry) return\n const remove = () => {\n const rest = threads.filter((t) => t.key !== entry.key)\n const next = rest.length > 0 ? rest : [emptyThread()]\n setThreads(next)\n if (entry.key === active.key) setActiveKey(next[0].key)\n }\n const local = threads.find((t) => t.key === entry.key)\n const conversationId = local ? local.conversationId : id\n if (!conversationId) return remove()\n void (async () => {\n try {\n await arbi.conversations.delete(conversationId)\n remove()\n await refetchConversations()\n } catch (e) {\n setHistoryError(messageOf(e, 'The conversation could not be deleted.'))\n }\n })()\n },\n [threadEntries, threads, active.key, arbi, refetchConversations]\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) {\n if (agentId) {\n const staged = await arbi.agents.stageFile(agentId, file, file.name)\n setStagedFiles((all) => [\n ...all.filter((existing) => existing.id !== staged.path),\n { id: staged.path, name: staged.name },\n ])\n } else await arbi.documents.uploadFile(file, file.name)\n }\n // New documents are not in `deselected`, so they join the selection by default.\n if (!agentId) await refetch()\n } catch (e) {\n setUploadError(messageOf(e, 'The upload failed.'))\n } finally {\n setIsUploading(false)\n }\n },\n [arbi, refetch, agentId]\n )\n\n return {\n assistantMode,\n isUpdatingAssistantMode,\n isPostingComment,\n setAssistantMode,\n threads: threadEntries.map(({ id, title }) => ({ id, title })),\n activeThreadId: publicId(active),\n messages: active.messages,\n isRunning,\n error,\n isLoadingThread: needsLoad && !historyError,\n isLoadingThreads,\n historyError,\n documents,\n isLoadingDocuments,\n isUploading,\n uploadError,\n send,\n retry,\n stop,\n selectThread,\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 * Contacts: the user's colleagues and pending invitations.\n *\n * Shares `arbiQueryKeys.contacts()` with `useDirectMessages`, so a change made here refreshes the\n * conversation rail on its own. The parts that turn an email list into a request and the backend\n * outcome into a sentence live in `@arbidocs/blocks/collaboration` (`AddContactsForm`).\n */\n\nimport { useMemo } from 'react'\nimport { useMutation, useQuery, useQueryClient } from '@tanstack/react-query'\nimport { useArbi } from './useArbi'\nimport { arbiQueryKeys } from './hooks'\n\n/** The user's contacts, registered and pending. */\nexport function useContacts(options?: { enabled?: boolean }) {\n const arbi = useArbi()\n return useQuery({\n queryKey: arbiQueryKeys.contacts(),\n queryFn: () => arbi.contacts.list(),\n enabled: (options?.enabled ?? true) && arbi.isLoggedIn,\n })\n}\n\n/** Contacts still waiting to join (an invitation sent or expired); `Invite again` re-adds them. */\nexport function usePendingContacts(options?: { enabled?: boolean }) {\n const contacts = useContacts(options)\n const pending = useMemo(\n () =>\n (contacts.data ?? []).filter(\n (c) => c.status === 'invitation_pending' || c.status === 'invitation_expired'\n ),\n [contacts.data]\n )\n return { ...contacts, pending }\n}\n\n/**\n * Add contacts by email. An address not yet on ARBI is invited. Resolves with one row per\n * address (`outcome`, `status`); map it with `toAddContactsRows` from `@arbidocs/blocks/collaboration`.\n */\nexport function useAddContacts() {\n const arbi = useArbi()\n const qc = useQueryClient()\n return useMutation({\n mutationFn: (emails: string[]) => arbi.contacts.add(emails),\n onSuccess: () => qc.invalidateQueries({ queryKey: arbiQueryKeys.contacts() }),\n })\n}\n\n/** Remove contacts, or withdraw invitations, by contact id. */\nexport function useRemoveContacts() {\n const arbi = useArbi()\n const qc = useQueryClient()\n return useMutation({\n mutationFn: (contactIds: string[]) => arbi.contacts.remove(contactIds),\n onSuccess: () => qc.invalidateQueries({ queryKey: arbiQueryKeys.contacts() }),\n })\n}\n","/**\n * Profile: the signed-in user's name and picture.\n *\n * Two layers, like the rest of the package. The SDK-bound hooks (`useProfile`, `useUpdateProfile`)\n * need an `ArbiProvider`. The controllers (`useNameEditor`, `useAvatarCrop`) own only the form\n * state and take the save as a function, so an app that has its own API layer (ARBI-frontend)\n * binds the same `ProfileCard` / `AvatarPicker` parts without a provider.\n */\n\nimport { useCallback, useState } from 'react'\nimport { useMutation, useQuery, useQueryClient } from '@tanstack/react-query'\nimport type { LoginProfile } from '@arbidocs/sdk/browser'\nimport { useArbi } from '../useArbi'\nimport { arbiQueryKeys } from '../hooks'\n\n// ── View model ──────────────────────────────────────────────────────────────\n\nexport interface ProfileView {\n givenName: string\n familyName: string | null\n picture: string | null\n email: string\n /** The sign-in provider manages the email (it cannot be changed here). */\n isSso: boolean\n /** Given and family name joined; empty while the profile has no name. */\n fullName: string\n}\n\n/** The profile as the UI reads it. `fullName` is the profile name, never the email. */\nexport function toProfileView(profile: LoginProfile): ProfileView {\n return {\n ...profile,\n fullName: [profile.givenName, profile.familyName]\n .map((part) => part?.trim())\n .filter(Boolean)\n .join(' '),\n }\n}\n\n// ── SDK-bound hooks ─────────────────────────────────────────────────────────\n\n/** The signed-in user's profile; `null` when the session has none (restored without a login). */\nexport function useProfile(options?: { enabled?: boolean }) {\n const arbi = useArbi()\n return useQuery({\n queryKey: arbiQueryKeys.profile(),\n queryFn: (): ProfileView | null => {\n const profile = arbi.user.profile()\n return profile ? toProfileView(profile) : null\n },\n enabled: (options?.enabled ?? true) && arbi.isLoggedIn,\n staleTime: Infinity,\n })\n}\n\nexport interface UpdateProfileVars {\n givenName?: string\n /** `''` clears it. */\n familyName?: string\n /** A data URL or URL; `''` clears it (the backend caps it at 100 KB). */\n picture?: string\n}\n\n/**\n * Save the name and/or picture (PATCH /v1/user/profile). The profile query is updated in place and\n * the workspace list (member rows carry the name) is refreshed, so every surface follows.\n */\nexport function useUpdateProfile() {\n const arbi = useArbi()\n const qc = useQueryClient()\n return useMutation({\n mutationFn: async (vars: UpdateProfileVars) => {\n await arbi.profile.update({\n ...(vars.givenName !== undefined && { given_name: vars.givenName.trim() }),\n ...(vars.familyName !== undefined && { family_name: vars.familyName.trim() }),\n ...(vars.picture !== undefined && { picture: vars.picture }),\n })\n const profile = arbi.user.profile()\n return profile ? toProfileView(profile) : null\n },\n onSuccess: (profile) => {\n qc.setQueryData(arbiQueryKeys.profile(), profile)\n return qc.invalidateQueries({ queryKey: arbiQueryKeys.workspaces() })\n },\n })\n}\n\n// ── Controllers (no SDK) ────────────────────────────────────────────────────\n\nexport interface UseNameEditorOptions {\n givenName: string | null | undefined\n familyName: string | null | undefined\n /** Persist the new name. Reject to keep the editor open (see `error`). */\n save: (name: { givenName: string; familyName: string }) => Promise<unknown> | unknown\n}\n\nexport interface NameEditor {\n isEditing: boolean\n givenName: string\n familyName: string\n onGivenNameChange: (value: string) => void\n onFamilyNameChange: (value: string) => void\n onStartEdit: () => void\n onSave: () => void\n onCancel: () => void\n isSaving: boolean\n /** The last failed save. */\n error: unknown\n}\n\n/**\n * State of the inline name editor of `ProfileCard`: start edit (seeded from the current name),\n * save (trimmed; a blank given name is not saved), cancel. Spread it into `ProfileCard`'s `name`\n * with `display`.\n */\nexport function useNameEditor({ givenName, familyName, save }: UseNameEditorOptions): NameEditor {\n const [isEditing, setIsEditing] = useState(false)\n const [given, setGiven] = useState('')\n const [family, setFamily] = useState('')\n const [isSaving, setIsSaving] = useState(false)\n const [error, setError] = useState<unknown>(null)\n\n const onStartEdit = useCallback(() => {\n setGiven(givenName ?? '')\n setFamily(familyName ?? '')\n setError(null)\n setIsEditing(true)\n }, [givenName, familyName])\n\n const onSave = useCallback(() => {\n const trimmedGiven = given.trim()\n if (!trimmedGiven) return\n setIsSaving(true)\n setError(null)\n void Promise.resolve()\n .then(() => save({ givenName: trimmedGiven, familyName: family.trim() }))\n .then(() => setIsEditing(false))\n .catch((e: unknown) => setError(e))\n .finally(() => setIsSaving(false))\n }, [given, family, save])\n\n return {\n isEditing,\n givenName: given,\n familyName: family,\n onGivenNameChange: setGiven,\n onFamilyNameChange: setFamily,\n onStartEdit,\n onSave,\n onCancel: () => setIsEditing(false),\n isSaving,\n error,\n }\n}\n\n/** Largest picture file accepted before cropping. */\nexport const MAX_AVATAR_FILE_BYTES = 5 * 1024 * 1024\n\nexport type AvatarFileProblem = 'not-image' | 'too-large' | 'unreadable'\n\nexport interface UseAvatarCropOptions {\n /** Persist the cropped picture (a data URL). */\n upload: (dataUrl: string) => Promise<unknown> | unknown\n /** Report a rejected file or a failed read; default is silent (the picker just does not open). */\n onProblem?: (problem: AvatarFileProblem) => void\n maxBytes?: number\n}\n\nexport interface AvatarCrop {\n /** Pass to `AvatarPicker.onFileChosen`. */\n onFileChosen: (file: File) => void\n /** The chosen image awaiting a crop (a data URL), else `null`. */\n pendingImage: string | null\n /** Pass to the crop dialog's `onComplete`. */\n onCropComplete: (result: { dataUrl: string }) => void\n onCropCancel: () => void\n isUploading: boolean\n}\n\n/**\n * The choose, validate, crop, upload sequence behind `AvatarPicker`: the picker hands over a file,\n * this checks it (image, size) and reads it for the crop dialog, then uploads the cropped data URL.\n */\nexport function useAvatarCrop({\n upload,\n onProblem,\n maxBytes = MAX_AVATAR_FILE_BYTES,\n}: UseAvatarCropOptions): AvatarCrop {\n const [pendingImage, setPendingImage] = useState<string | null>(null)\n const [isUploading, setIsUploading] = useState(false)\n\n const onFileChosen = useCallback(\n (file: File) => {\n if (!file.type.startsWith('image/')) return onProblem?.('not-image')\n if (file.size > maxBytes) return onProblem?.('too-large')\n const reader = new FileReader()\n reader.onload = () => setPendingImage(reader.result as string)\n reader.onerror = () => onProblem?.('unreadable')\n reader.readAsDataURL(file)\n },\n [maxBytes, onProblem]\n )\n\n const onCropComplete = useCallback(\n (result: { dataUrl: string }) => {\n setPendingImage(null)\n setIsUploading(true)\n void Promise.resolve()\n .then(() => upload(result.dataUrl))\n .catch(() => {\n // The host's `upload` reports its own failure; the picker just stops spinning.\n })\n .finally(() => setIsUploading(false))\n },\n [upload]\n )\n\n return {\n onFileChosen,\n pendingImage,\n onCropComplete,\n onCropCancel: () => setPendingImage(null),\n isUploading,\n }\n}\n","/**\n * Email change: ask for a code at the new address, confirm it. The SDK-bound mutations and the\n * `ProfileCard` flow controller (cooldown on re-sending the code) are separate, as in `profile.ts`.\n */\n\nimport { useCallback, useEffect, useState } from 'react'\nimport { useMutation, useQueryClient } from '@tanstack/react-query'\nimport { useArbi } from '../useArbi'\nimport { arbiQueryKeys } from '../hooks'\nimport { toProfileView } from './profile'\n\n// ── SDK-bound hooks ─────────────────────────────────────────────────────────\n\n/** Send the 3-word verification code to the new address (not for SSO accounts). */\nexport function useRequestEmailChange() {\n const arbi = useArbi()\n return useMutation({\n mutationFn: (newEmail: string) => arbi.account.requestEmailChange(newEmail),\n })\n}\n\n/** Confirm the new address with the emailed code; the profile query shows the new email. */\nexport function useConfirmEmailChange() {\n const arbi = useArbi()\n const qc = useQueryClient()\n return useMutation({\n mutationFn: ({ newEmail, code }: { newEmail: string; code: string }) =>\n arbi.account.confirmEmailChange(newEmail, code),\n onSuccess: () => {\n const profile = arbi.user.profile()\n qc.setQueryData(arbiQueryKeys.profile(), profile ? toProfileView(profile) : null)\n },\n })\n}\n\n// ── Controller (no SDK) ─────────────────────────────────────────────────────\n\nexport interface UseEmailChangeOptions {\n /** Send a code to `newEmail`. */\n requestCode: (newEmail: string) => Promise<unknown> | unknown\n /** Confirm `newEmail` with `code`. Resolve to finish the flow. */\n confirm: (args: { newEmail: string; code: string }) => Promise<unknown> | unknown\n /** Seconds before another code may be requested. Default 30. */\n cooldownSeconds?: number\n}\n\nexport interface EmailChange {\n /** The flow is open: `ProfileCard` hides the plain email row. */\n isOpen: boolean\n onStart: () => void\n step: 'enter' | 'verify'\n newEmail: string\n onNewEmailChange: (value: string) => void\n onSendCode: () => void\n isSending: boolean\n code: string\n onCodeChange: (value: string) => void\n onConfirm: () => void\n isConfirming: boolean\n cooldownSeconds: number\n onCancel: () => void\n /** The last failed send or confirm. */\n error: unknown\n}\n\n/** The two-step email-change flow of `ProfileCard`: enter address, verify code. */\nexport function useEmailChange({\n requestCode,\n confirm,\n cooldownSeconds: cooldownLength = 30,\n}: UseEmailChangeOptions): EmailChange {\n const [isOpen, setIsOpen] = useState(false)\n const [step, setStep] = useState<'enter' | 'verify'>('enter')\n const [newEmail, setNewEmail] = useState('')\n const [code, setCode] = useState('')\n const [cooldown, setCooldown] = useState(0)\n const [isSending, setIsSending] = useState(false)\n const [isConfirming, setIsConfirming] = useState(false)\n const [error, setError] = useState<unknown>(null)\n\n useEffect(() => {\n if (cooldown <= 0) return\n const timer = setTimeout(() => setCooldown((c) => c - 1), 1000)\n return () => clearTimeout(timer)\n }, [cooldown])\n\n const reset = useCallback(() => {\n setIsOpen(false)\n setStep('enter')\n setNewEmail('')\n setCode('')\n setError(null)\n }, [])\n\n const onSendCode = useCallback(() => {\n const email = newEmail.trim()\n if (!email) return\n setIsSending(true)\n setError(null)\n void Promise.resolve()\n .then(() => requestCode(email))\n .then(() => {\n setStep('verify')\n setCooldown(cooldownLength)\n })\n .catch((e: unknown) => setError(e))\n .finally(() => setIsSending(false))\n }, [newEmail, requestCode, cooldownLength])\n\n const onConfirm = useCallback(() => {\n const email = newEmail.trim()\n const entered = code.trim()\n if (!email || !entered) return\n setIsConfirming(true)\n setError(null)\n void Promise.resolve()\n .then(() => confirm({ newEmail: email, code: entered }))\n .then(reset)\n .catch((e: unknown) => setError(e))\n .finally(() => setIsConfirming(false))\n }, [newEmail, code, confirm, reset])\n\n return {\n isOpen,\n onStart: () => setIsOpen(true),\n step,\n newEmail,\n onNewEmailChange: setNewEmail,\n onSendCode,\n isSending,\n code,\n onCodeChange: setCode,\n onConfirm,\n isConfirming,\n cooldownSeconds: cooldown,\n onCancel: reset,\n error,\n }\n}\n","/**\n * Password change: re-key the account under a new master password.\n *\n * `usePasswordChange` is the SDK-bound mutation (re-wraps every workspace key and re-encrypts\n * direct messages, see `Arbi.account.changePassword`). `usePasswordChangeForm` is the controller\n * behind `PasswordChangeDialog`: fields, validation, error wording, the success state that hands\n * over the new recovery key. It takes the submit as a function, so an app without an\n * `ArbiProvider` binds the same dialog.\n */\n\nimport { useCallback, useMemo, useState } from 'react'\nimport { useMutation } from '@tanstack/react-query'\nimport { passwordChangeErrorMessage } from '@arbidocs/client'\nimport { useArbi } from '../useArbi'\n\n// ── SDK-bound hook ──────────────────────────────────────────────────────────\n\n/** What a finished password change reports. */\nexport interface PasswordChangeResult {\n /** The new Ed25519 signing key: its recovery file is what the user should save now. */\n newSigningPrivateKey: Uint8Array\n workspacesUpdated: number\n messagesReEncrypted: number\n}\n\nexport interface PasswordChangeVars {\n newPassword: string\n /** Omit in recovery mode (after signing in with a recovery key). */\n currentPassword?: string\n}\n\n/** Change (or, in recovery mode, set) the master password. Needs an `ArbiProvider`. */\nexport function usePasswordChange() {\n const arbi = useArbi()\n return useMutation({\n mutationFn: (vars: PasswordChangeVars): Promise<PasswordChangeResult> =>\n arbi.account.changePassword(vars),\n })\n}\n\n// ── Controller (no SDK) ─────────────────────────────────────────────────────\n\nexport interface PasswordChangeFormMessages {\n required: string\n mismatch: string\n sameAsCurrent: string\n wrongCurrent: string\n wrongRecoveryKey: string\n}\n\nexport const DEFAULT_PASSWORD_CHANGE_FORM_MESSAGES: PasswordChangeFormMessages = {\n required: 'All fields are required',\n mismatch: 'New passwords do not match',\n sameAsCurrent: 'New password must be different from current password',\n wrongCurrent: 'Current password is incorrect.',\n wrongRecoveryKey: 'Recovery key did not match this account. Try a different recovery file.',\n}\n\nexport interface UsePasswordChangeFormOptions<R> {\n /** After recovery with a key: no current password is asked for. */\n recoveryMode?: boolean\n /** The host's password policy: the first unmet requirement, or `null` when the password is fine. */\n getUnmetRequirement: (password: string) => string | null\n /** Do the change. Resolve with whatever the success state needs (the new signing key). */\n submit: (vars: PasswordChangeVars) => Promise<R>\n /** The dialog should close (cancel, or done). */\n onClose: () => void\n /** Recovery finished: continue into the app. Recovery closes itself, with no success screen. */\n onRecoveryComplete?: () => void\n messages?: Partial<PasswordChangeFormMessages>\n}\n\nexport interface PasswordChangeForm<R> {\n currentPassword: string\n onCurrentPasswordChange: (value: string) => void\n newPassword: string\n onNewPasswordChange: (value: string) => void\n confirmPassword: string\n onConfirmPasswordChange: (value: string) => void\n error: string | null\n isProcessing: boolean\n isSubmitDisabled: boolean\n onSubmit: () => void\n /** The outcome once the change went through (normal mode); render the recovery key from it. */\n result: R | null\n /** Cancel and clear the form. */\n onCancel: () => void\n /** Leave the success screen. */\n onDone: () => void\n}\n\n/** The state machine of `PasswordChangeDialog`; spread it into the dialog's props. */\nexport function usePasswordChangeForm<R>({\n recoveryMode = false,\n getUnmetRequirement,\n submit,\n onClose,\n onRecoveryComplete,\n messages,\n}: UsePasswordChangeFormOptions<R>): PasswordChangeForm<R> {\n const m = useMemo(() => ({ ...DEFAULT_PASSWORD_CHANGE_FORM_MESSAGES, ...messages }), [messages])\n const [currentPassword, setCurrentPassword] = useState('')\n const [newPassword, setNewPassword] = useState('')\n const [confirmPassword, setConfirmPassword] = useState('')\n const [error, setError] = useState<string | null>(null)\n const [isProcessing, setIsProcessing] = useState(false)\n const [result, setResult] = useState<R | null>(null)\n\n const clear = useCallback(() => {\n setCurrentPassword('')\n setNewPassword('')\n setConfirmPassword('')\n }, [])\n\n const isSubmitDisabled =\n isProcessing ||\n (!recoveryMode && !currentPassword) ||\n !newPassword ||\n !confirmPassword ||\n getUnmetRequirement(newPassword) !== null ||\n newPassword !== confirmPassword\n\n const onSubmit = useCallback(() => {\n setError(null)\n if ((!recoveryMode && !currentPassword) || !newPassword || !confirmPassword) {\n return setError(m.required)\n }\n if (newPassword !== confirmPassword) return setError(m.mismatch)\n const unmet = getUnmetRequirement(newPassword)\n if (unmet !== null) return setError(unmet)\n if (!recoveryMode && currentPassword === newPassword) return setError(m.sameAsCurrent)\n\n setIsProcessing(true)\n void submit({ newPassword, currentPassword: recoveryMode ? undefined : currentPassword })\n .then((outcome) => {\n clear()\n if (recoveryMode) {\n onClose()\n onRecoveryComplete?.()\n } else {\n setResult(outcome)\n }\n })\n .catch((e: unknown) => {\n const message = passwordChangeErrorMessage(e)\n const wrongCurrent = /invalid signature|current password|401/i.test(message)\n setError(wrongCurrent ? (recoveryMode ? m.wrongRecoveryKey : m.wrongCurrent) : message)\n })\n .finally(() => setIsProcessing(false))\n }, [\n recoveryMode,\n currentPassword,\n newPassword,\n confirmPassword,\n getUnmetRequirement,\n submit,\n clear,\n onClose,\n onRecoveryComplete,\n m,\n ])\n\n return {\n currentPassword,\n onCurrentPasswordChange: setCurrentPassword,\n newPassword,\n onNewPasswordChange: setNewPassword,\n confirmPassword,\n onConfirmPasswordChange: setConfirmPassword,\n error,\n isProcessing,\n isSubmitDisabled,\n onSubmit,\n result,\n onCancel: () => {\n clear()\n setError(null)\n setResult(null)\n onClose()\n },\n onDone: () => {\n setResult(null)\n onClose()\n },\n }\n}\n","/**\n * Notification preferences: which email categories the user wants (the `email_notifications`\n * record of the user settings). All default on. The master switch on `NotificationCategoryList`\n * is \"on while at least one category is on\" and writes every category at once.\n */\n\nimport { useCallback, useMemo } from 'react'\nimport { useMutation, useQuery, useQueryClient } from '@tanstack/react-query'\nimport { useArbi } from '../useArbi'\nimport { arbiQueryKeys } from '../hooks'\n\n/** Category key to on/off, e.g. `{ messages: true, product_updates: false }`. */\nexport type EmailPreferences = Record<string, boolean>\n\n// ── Pure core ───────────────────────────────────────────────────────────────\n\nexport interface NotificationPreferencesModel {\n /** Master switch: on while at least one category is on. */\n masterChecked: boolean\n /** Each category's state (`true` when the record says nothing: the default). */\n checked: Record<string, boolean>\n /** The PATCH body for the master switch: every category set to `value`. */\n masterPatch: (value: boolean) => EmailPreferences\n /** The PATCH body for one category. */\n categoryPatch: (key: string, value: boolean) => EmailPreferences\n}\n\n/** Derive the switch states from the stored record and the list of category keys. */\nexport function toNotificationPreferences(\n stored: EmailPreferences | null | undefined,\n keys: readonly string[]\n): NotificationPreferencesModel {\n const checked = Object.fromEntries(keys.map((key) => [key, stored?.[key] ?? true]))\n return {\n masterChecked: keys.some((key) => checked[key]),\n checked,\n masterPatch: (value) => Object.fromEntries(keys.map((key) => [key, value])),\n categoryPatch: (key, value) => ({ [key]: value }),\n }\n}\n\n// ── SDK-bound hooks ─────────────────────────────────────────────────────────\n\n/** The user's settings record (flags, pins, notification preferences). */\nexport function useUserSettings(options?: { enabled?: boolean }) {\n const arbi = useArbi()\n return useQuery({\n queryKey: arbiQueryKeys.userSettings(),\n queryFn: () => arbi.settings.get(),\n enabled: (options?.enabled ?? true) && arbi.isLoggedIn,\n })\n}\n\n/**\n * The email notification preferences and the save. `save` writes the given keys (a patch,\n * merged by the server) and updates the cached settings straight away, so the switches do not\n * wait for the round trip; a failed write rolls back.\n */\nexport function useNotificationPreferences(\n keys: readonly string[],\n options?: { enabled?: boolean }\n) {\n const arbi = useArbi()\n const qc = useQueryClient()\n const settings = useUserSettings(options)\n const stored = settings.data?.email_notifications as EmailPreferences | undefined\n\n const save = useMutation({\n mutationFn: (patch: EmailPreferences) =>\n arbi.settings.update({ email_notifications: patch } as never),\n onMutate: async (patch) => {\n await qc.cancelQueries({ queryKey: arbiQueryKeys.userSettings() })\n const previous = qc.getQueryData(arbiQueryKeys.userSettings())\n qc.setQueryData(arbiQueryKeys.userSettings(), (old: typeof settings.data) =>\n old ? { ...old, email_notifications: { ...old.email_notifications, ...patch } } : old\n )\n return { previous }\n },\n onError: (_err, _patch, context) => {\n qc.setQueryData(arbiQueryKeys.userSettings(), context?.previous)\n },\n onSettled: () => qc.invalidateQueries({ queryKey: arbiQueryKeys.userSettings() }),\n })\n\n const model = useMemo(() => toNotificationPreferences(stored, keys), [stored, keys])\n const setAll = useCallback(\n (value: boolean) => save.mutate(model.masterPatch(value)),\n [save, model]\n )\n const setCategory = useCallback(\n (key: string, value: boolean) => save.mutate(model.categoryPatch(key, value)),\n [save, model]\n )\n\n return {\n ...model,\n isLoading: settings.isLoading,\n isSaving: save.isPending,\n /** The master switch handler: every category on or off. */\n setAll,\n /** One category's handler. */\n setCategory,\n }\n}\n","/**\n * Session management beyond `useSessions` (the list): end one session, sign out everywhere, and\n * tell which listed session is this device's.\n */\n\nimport { useMutation, useQueryClient } from '@tanstack/react-query'\nimport { useArbi } from '../useArbi'\nimport { arbiQueryKeys } from '../hooks'\n\n/** End one of the user's sessions at once (not this device's: that is a logout). */\nexport function useTerminateSession() {\n const arbi = useArbi()\n const qc = useQueryClient()\n return useMutation({\n mutationFn: (sessionId: string) => arbi.sessions.terminate(sessionId),\n onSuccess: () => qc.invalidateQueries({ queryKey: arbiQueryKeys.sessions() }),\n })\n}\n\n/** Sign out of every device, this one included. The instance is logged out afterwards. */\nexport function useLogoutAllSessions() {\n const arbi = useArbi()\n const qc = useQueryClient()\n return useMutation({\n mutationFn: () => arbi.sessions.logoutAll(),\n onSuccess: () => qc.clear(),\n })\n}\n\n/** The id this device's session carries in the `useSessions` list, or `null`. */\nexport function useCurrentSessionId(): string | null {\n return useArbi().sessions.currentId()\n}\n","/**\n * Delete account: the two-step flow behind `DeleteAccountDialog` and the backend's refusals.\n * The backend closes the account (soft delete) unless the user still has an active subscription\n * or is the sole admin of a workspace with other members; the refusal names which.\n */\n\nimport { useCallback, useState } from 'react'\nimport { useMutation } from '@tanstack/react-query'\nimport { useArbi } from '../useArbi'\n\n/** Why an account cannot be closed yet. */\nexport type DeleteAccountBlocker =\n { type: 'active_subscription' } | { type: 'workspace_members'; workspaces: string[] }\n\n/** Read the blockers out of a failed deletion; an empty list means it failed for another reason. */\nexport function parseDeleteAccountBlockers(error: unknown): DeleteAccountBlocker[] {\n const body = (error as { apiError?: unknown } | null)?.apiError ?? error\n const detail = (body as { detail?: unknown } | null)?.detail\n if (detail === 'active_subscription') return [{ type: 'active_subscription' }]\n if (detail && typeof detail === 'object') {\n const d = detail as { reason?: unknown; workspaces?: unknown }\n if (d.reason === 'workspace_members' && Array.isArray(d.workspaces)) {\n return [{ type: 'workspace_members', workspaces: d.workspaces.map(String) }]\n }\n }\n return []\n}\n\n/** Close the account and sign out. Needs an `ArbiProvider`. */\nexport function useDeleteAccount() {\n const arbi = useArbi()\n return useMutation({ mutationFn: () => arbi.account.requestDeletion() })\n}\n\nexport interface UseDeleteAccountFlowOptions {\n userEmail: string\n /** Close the account. Reject with the backend's error to surface blockers. */\n remove: () => Promise<unknown> | unknown\n /** The dialog should close. */\n onClose: () => void\n /** The account is closed (sign the user out of the app). */\n onDeleted: () => void\n /** A failure that is not a blocker. */\n onError?: (error: unknown) => void\n}\n\nexport interface DeleteAccountFlow {\n step: 'warning' | 'confirm'\n blockers: DeleteAccountBlocker[]\n confirmEmail: string\n onConfirmEmailChange: (value: string) => void\n onContinue: () => void\n onBack: () => void\n isDeleting: boolean\n onSubmit: () => void\n onClose: () => void\n}\n\n/** Step, typed-email confirmation and blockers of `DeleteAccountDialog`. */\nexport function useDeleteAccountFlow({\n userEmail,\n remove,\n onClose,\n onDeleted,\n onError,\n}: UseDeleteAccountFlowOptions): DeleteAccountFlow {\n const [step, setStep] = useState<'warning' | 'confirm'>('warning')\n const [confirmEmail, setConfirmEmail] = useState('')\n const [blockers, setBlockers] = useState<DeleteAccountBlocker[]>([])\n const [isDeleting, setIsDeleting] = useState(false)\n\n const close = useCallback(() => {\n setStep('warning')\n setConfirmEmail('')\n setBlockers([])\n onClose()\n }, [onClose])\n\n const onSubmit = useCallback(() => {\n if (confirmEmail.toLowerCase() !== userEmail.toLowerCase()) return\n setIsDeleting(true)\n void Promise.resolve()\n .then(remove)\n .then(() => {\n close()\n onDeleted()\n })\n .catch((error: unknown) => {\n const found = parseDeleteAccountBlockers(error)\n if (found.length > 0) {\n setBlockers(found)\n setStep('warning')\n } else {\n onError?.(error)\n }\n })\n .finally(() => setIsDeleting(false))\n }, [confirmEmail, userEmail, remove, close, onDeleted, onError])\n\n return {\n step,\n blockers,\n confirmEmail,\n onConfirmEmailChange: setConfirmEmail,\n onContinue: () => setStep('confirm'),\n onBack: () => setStep('warning'),\n isDeleting,\n onSubmit,\n onClose: close,\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 /** Bind this turn to the open native Word document. */\n activeArtifactExtId?: string\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 activeArtifactExtId: opts?.activeArtifactExtId,\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' | 'react' | '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 while it is\n // open, and again whenever the composer changes size: opening a citation also opens the document\n // viewer, which narrows the chat column after the first measurement.\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 const measure = () => {\n const rect = edge.getBoundingClientRect()\n setDock({ left: rect.left, top: rect.top, width: rect.width })\n }\n measure()\n const observer = new ResizeObserver(measure)\n observer.observe(edge)\n window.addEventListener('resize', measure)\n return () => {\n observer.disconnect()\n window.removeEventListener('resize', measure)\n }\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-sm text-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 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 {/* Readable floor: never below the text-xs token, bold, so the number is easy to spot. */}\n <sup className=\"ml-px align-super text-[max(0.8em,var(--text-xs))] font-bold leading-none tabular-nums text-ai-ink\">\n {citationNum}\n </sup>\n </MarkMenu>\n)\n\nexport const CitationRenderer = React.memo(CitationRendererComponent)\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 AtSign,\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 'agent_input_requested':\n return { Icon: MessageCircleMore, iconClassName: 'text-primary', label: 'Input needed' }\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 'docx_mention':\n case 'mention':\n return { Icon: AtSign, iconClassName: 'text-primary', label: 'Mention' }\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","import { useMutation, useQuery, useQueryClient } from '@tanstack/react-query'\nimport { useArbi } from '../useArbi'\nimport { useArbiWebSocket } from '../websocket/hooks'\n\nconst workTypes = [\n 'mention',\n 'workspace_access_request',\n 'conversation_ready_for_review',\n 'conversation_approval_request',\n 'conversation_done',\n 'workflow_failed',\n] as const\n\n/** Persisted work notices, isolated by account and API, with live refresh and read receipts. */\nexport function useWorkNotifications(options: {\n apiUrl: string\n userId?: string\n enabled: boolean\n}) {\n const arbi = useArbi()\n const queries = useQueryClient()\n const queryKey = ['work-notifications', options.apiUrl, options.userId]\n const query = useQuery({\n queryKey,\n queryFn: async () =>\n (await Promise.all(workTypes.map((type) => arbi.notifications.list(type)))).flat(),\n enabled: options.enabled && Boolean(options.userId),\n refetchInterval: 30_000,\n })\n useArbiWebSocket((message) => {\n if (workTypes.some((type) => type === message.type))\n void queries.invalidateQueries({ queryKey })\n })\n const receipt = useMutation({\n mutationFn: (ids: string[]) => arbi.notifications.markRead(ids),\n onSuccess: () => queries.invalidateQueries({ queryKey }),\n })\n return { ...query, markRead: receipt.mutateAsync }\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 { arbiQueryKeys } from '../hooks'\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\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: arbiQueryKeys.contacts(),\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 * Pinned above the rows, below the heading: a call to action such as `DmInviteChip` from\n * `@arbidocs/blocks/collaboration`, or a start-by-email form. Shown even when the list is empty.\n */\n lead?: 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 lead,\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 {lead}\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 * Start a conversation with someone by email, for a person who is not yet in the rail: an address\n * and a first message. The send resolves the recipient's key internally (`sendMessageTo`).\n */\n\nimport { useId, useState } from 'react'\nimport { Loader2, Send } from 'lucide-react'\nimport { Button } from '../ui/button'\nimport { Input } from '../ui/input'\nimport { Label } from '../ui/label'\nimport { Textarea } from '../ui/textarea'\nimport type { DmClassNames } from './types'\nimport { cn } from '../lib/utils'\n\nexport interface StartByEmailLabels {\n email: string\n emailPlaceholder: string\n message: string\n messagePlaceholder: string\n send: string\n sending: string\n invalidEmail: string\n}\n\nexport const DEFAULT_START_BY_EMAIL_LABELS: StartByEmailLabels = {\n email: 'Email address',\n emailPlaceholder: 'name@example.com',\n message: 'Message',\n messagePlaceholder: 'Write the first message…',\n send: 'Send',\n sending: 'Sending…',\n invalidEmail: 'Enter a valid email address.',\n}\n\nconst EMAIL = /^[^\\s@]+@[^\\s@]+\\.[^\\s@]+$/\n\nexport interface StartByEmailProps {\n /** Send the first message to `email`. Reject to keep the form and show the error. */\n onStart: (email: string, text: string) => Promise<unknown>\n /** Called after a successful send, with the value `onStart` resolved to. */\n onStarted?: (result: unknown) => void\n classNames?: Pick<DmClassNames, 'sendButton'>\n labels?: Partial<StartByEmailLabels>\n className?: string\n}\n\nexport function StartByEmail({\n onStart,\n onStarted,\n classNames,\n labels,\n className,\n}: StartByEmailProps) {\n const l = { ...DEFAULT_START_BY_EMAIL_LABELS, ...labels }\n const uid = useId()\n const [email, setEmail] = useState('')\n const [text, setText] = useState('')\n const [busy, setBusy] = useState(false)\n const [error, setError] = useState<string | null>(null)\n\n const address = email.trim().toLowerCase()\n const valid = EMAIL.test(address)\n\n const submit = async () => {\n if (!valid || !text.trim() || busy) return\n setBusy(true)\n setError(null)\n try {\n const result = await onStart(address, text.trim())\n setEmail('')\n setText('')\n onStarted?.(result)\n } catch (e) {\n setError(e instanceof Error ? e.message : String(e))\n } finally {\n setBusy(false)\n }\n }\n\n return (\n <form\n data-testid=\"arbi-dm-start\"\n className={cn('flex flex-col gap-2 border-b border-border px-4 py-3', className)}\n onSubmit={(e) => {\n e.preventDefault()\n void submit()\n }}\n >\n <Label htmlFor={`${uid}-email`}>{l.email}</Label>\n <Input\n id={`${uid}-email`}\n type=\"email\"\n value={email}\n onChange={(e) => setEmail(e.target.value)}\n placeholder={l.emailPlaceholder}\n aria-invalid={email !== '' && !valid}\n aria-describedby={email !== '' && !valid ? `${uid}-bad` : undefined}\n disabled={busy}\n data-testid=\"arbi-dm-start-email\"\n />\n {email !== '' && !valid && (\n <p id={`${uid}-bad`} className=\"text-xs text-destructive\">\n {l.invalidEmail}\n </p>\n )}\n <Label htmlFor={`${uid}-text`}>{l.message}</Label>\n <Textarea\n id={`${uid}-text`}\n value={text}\n onChange={(e) => setText(e.target.value)}\n placeholder={l.messagePlaceholder}\n rows={2}\n disabled={busy}\n data-testid=\"arbi-dm-start-message\"\n />\n {error && (\n <p role=\"alert\" className=\"text-xs text-destructive\" data-testid=\"arbi-dm-start-error\">\n {error}\n </p>\n )}\n <Button\n type=\"submit\"\n size=\"sm\"\n disabled={!valid || !text.trim() || busy}\n className={cn('self-end', classNames?.sendButton)}\n data-testid=\"arbi-dm-start-send\"\n >\n {busy ? (\n <Loader2 className=\"size-4 animate-spin\" aria-hidden />\n ) : (\n <Send className=\"size-4\" aria-hidden />\n )}\n {busy ? l.sending : l.send}\n </Button>\n </form>\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'\nimport { StartByEmail, type StartByEmailLabels } from './StartByEmail'\nimport type { DmNotification } from './types'\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 * Replaces the rail's \"Conversations / N colleagues\" heading. `null` for no heading.\n */\n listHeader?: React.ReactNode\n /**\n * Pinned at the top of the rail, e.g. `<DmInviteChip onClick={...} />` from\n * `@arbidocs/blocks/collaboration`. Shown even when there are no conversations.\n */\n listLead?: React.ReactNode\n /**\n * Offer a form at the top of the rail to message an address that is not in the list yet\n * (email plus first message). The new conversation opens once it is sent.\n */\n startByEmail?: boolean | { labels?: Partial<StartByEmailLabels> }\n /**\n * Hide the signed-in user's own row. A contact list that includes the owner would otherwise\n * offer a conversation with yourself.\n */\n hideOwnContact?: boolean\n}\n\nexport function DirectMessages({\n className,\n classNames,\n emptyThread,\n emptyList,\n listHeader,\n listLead,\n startByEmail,\n hideOwnContact,\n}: DirectMessagesProps) {\n const {\n conversations: allConversations,\n myExtId,\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 const conversations = useMemo(\n () =>\n hideOwnContact && myExtId\n ? allConversations.filter((c) => c.peer.external_id !== myExtId)\n : allConversations,\n [allConversations, hideOwnContact, myExtId]\n )\n\n // A first message sent by email opens its thread: the SDK hands back the created notifications.\n const openStarted = (created: unknown) => {\n const peer = Array.isArray(created)\n ? (created[0] as DmNotification | undefined)?.recipient?.external_id\n : undefined\n if (peer) setSelectedPeerId(peer)\n }\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 header={listHeader}\n lead={\n <>\n {listLead}\n {startByEmail && (\n <StartByEmail\n onStart={sendMessageTo}\n onStarted={openStarted}\n classNames={classNames}\n labels={typeof startByEmail === 'object' ? startByEmail.labels : undefined}\n />\n )}\n </>\n }\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/workforce.ts","../src/chat/citations.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/contacts.ts","../src/account/profile.ts","../src/account/email.ts","../src/account/password.ts","../src/account/notifications.ts","../src/account/sessions.ts","../src/account/delete.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/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/notifications/useWorkNotifications.ts","../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/StartByEmail.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","useQueryClient","useMutation","arbiQueryKeys","useQuery","resolveCitations","summarizeCitations","useDocuments","useConversations","useMemo","useAssistantQuery","useState","useRef","useEffect","useConversationThreads","useCallback","error","lastMessage","stored","options","memo","TypingIndicator","jsx","jsxs","ChatBubble","cn","Link","Trash2","CheckCheck","Check","create","createContext","useContext","isMessageType","connectWithReconnect","useWorkspaces","passwordChangeErrorMessage","diffWords","Loader2","AlertTriangle","Fragment","AiMarkdown","ShieldCheck","Copy","Sparkles","Card","Button","FileText","Badge","GitCompareArrows","Download","AnimatePresence","motion","ImageIcon","Search","CornerDownLeft","useParsedDocument","useTags","React","X","TagEntity","MarkdownRenderer","PassageCard","ArrowLeft","Input","Send","Tags","notify","normalizeCitationMarkup","useLayoutEffect","ReactMarkdown","createPortal","MarkMenu","FILE_TYPE_COLORS","Crown","useId","getEntityIcon","MessageCircleMore","AtSign","UserCheck","PartyPopper","Gift","Gauge","Activity","Info","SquareArrowOutUpRight","FolderPlus","Pencil","FileX2","FileCheck2","useActivity","UserEntity","getEntityColorStyles","AgentBadge","formatRelativeTime","MessagesSquare","ScrollArea","Textarea","Label","emptyThread","Cropper","Slider","Dialog","DialogContent","DialogHeader","DialogTitle","DialogFooter","ArrowRight","ModuleRegistry","AllCommunityModule","DocumentEntity","AgGridReact","DropdownMenu","DropdownMenuTrigger","MoreHorizontal","DropdownMenuContent","DropdownMenuItem","SquarePen","DropdownMenuSeparator","useThumbnails","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 * Work, workflows, agents and skills: the mutation and read hooks behind an \"AI workforce\" screen.\n *\n * A conversation with a `status` is a task: it is listed by `useConversations` and changed through\n * `useUpdateConversation` and friends. A workflow is the automation that creates them. Everything\n * sits on the SDK (`arbi.conversations`, `arbi.workflows`, `arbi.agents`, `arbi.agentConfig`,\n * `arbi.workspaces`, `arbi.assistant.listSkills`) and invalidates through {@link arbiQueryKeys}, so\n * `useConversations`, `useWorkflows`, `useAgents` and `useConfigs` refresh on their own after a\n * write. Mapping a form onto these requests (`TaskComposerValues` to a create-work or create-workflow\n * request, an agent form to a persona) is the pure part and lives next to the forms in\n * `@arbidocs/blocks/agents`.\n *\n * Requires an `ArbiProvider` and a React Query client above it.\n */\n\nimport { useMutation, useQuery, useQueryClient } from '@tanstack/react-query'\nimport type {\n ActivityResponse,\n ConversationResponse,\n CreateWorkRequest,\n CreateWorkflowRequest,\n PlanWorkRequest,\n RequestApprovalRequest,\n ReviewWorkRequest,\n UpdateConversationRequest,\n UpdateWorkflowRequest,\n WorkflowResponse,\n WorkflowRunResponse,\n} from '@arbidocs/sdk/browser'\nimport { useArbi } from './useArbi'\nimport { arbiQueryKeys } from './hooks'\n\n/** An agent or deployment config: section name (`Agents`, `QueryLLM`, ...) to its parameters. */\nexport type AgentConfigSections = Record<string, Record<string, unknown>>\n\n// ── Conversations as work ───────────────────────────────────────────────────\n\n/**\n * Patch a conversation: rename it, share it or make it private (`shared`, owner only), or change\n * its work fields (description, due date, sign-off person, parent, `status` `todo | done`, plan).\n * The one write behind title edits, the share toggle and marking a task done.\n */\nexport function useUpdateConversation() {\n const arbi = useArbi()\n const qc = useQueryClient()\n return useMutation({\n mutationFn: ({\n conversationId,\n patch,\n }: {\n conversationId: string\n patch: UpdateConversationRequest\n }): Promise<ConversationResponse> => arbi.conversations.update(conversationId, patch),\n onSuccess: () => qc.invalidateQueries({ queryKey: arbiQueryKeys.allConversations() }),\n })\n}\n\n/**\n * Create a work item from a `CreateWorkRequest`: a plain to-do, or (with a prompt or skill) agent\n * work that starts at once. Resolves with the created conversation.\n */\nexport function useCreateWork() {\n const arbi = useArbi()\n const qc = useQueryClient()\n return useMutation({\n mutationFn: (body: CreateWorkRequest): Promise<ConversationResponse> =>\n arbi.conversations.createWork(body),\n onSuccess: () => qc.invalidateQueries({ queryKey: arbiQueryKeys.allConversations() }),\n })\n}\n\n/**\n * Run a work item now, or retry it. A run parked waiting for workspace access (a temporary\n * authorization tier) is granted a temporary, session-scoped key and run again, so the person\n * clicking Run is the approval. Resolves with the updated conversation.\n */\nexport function useRunConversation() {\n const arbi = useArbi()\n const qc = useQueryClient()\n return useMutation({\n mutationFn: (conversationId: string): Promise<ConversationResponse> =>\n arbi.conversations.runWithAuth(conversationId),\n onSuccess: () => qc.invalidateQueries({ queryKey: arbiQueryKeys.allConversations() }),\n })\n}\n\n/**\n * The sign-off person's verdict on work that is ready for review: approve it (done) or send it\n * back with feedback so the agent revises it in the same thread. Resolves with the conversation.\n */\nexport function useReviewConversation() {\n const arbi = useArbi()\n const qc = useQueryClient()\n return useMutation({\n mutationFn: ({\n conversationId,\n review,\n }: {\n conversationId: string\n review: ReviewWorkRequest\n }): Promise<ConversationResponse> => arbi.conversations.review(conversationId, review),\n onSuccess: () => qc.invalidateQueries({ queryKey: arbiQueryKeys.allConversations() }),\n })\n}\n\n/**\n * Ask another person to approve a work item (a real request: they are notified and become its\n * sign-off person). Resolves with the updated conversation.\n */\nexport function useRequestConversationApproval() {\n const arbi = useArbi()\n const qc = useQueryClient()\n return useMutation({\n mutationFn: ({\n conversationId,\n request,\n }: {\n conversationId: string\n request: RequestApprovalRequest\n }): Promise<ConversationResponse> =>\n arbi.conversations.requestApproval(conversationId, request),\n onSuccess: () => qc.invalidateQueries({ queryKey: arbiQueryKeys.allConversations() }),\n })\n}\n\n/** Draft a reviewable plan (goal and acceptance checklist) from an objective. */\nexport function usePlanWork() {\n const arbi = useArbi()\n return useMutation({\n mutationFn: (body: PlanWorkRequest) => arbi.conversations.plan(body),\n })\n}\n\n/**\n * The agent run-session key a parked run waits for the owner to allow (public key and email,\n * non-secret). Enabled only while the run is waiting; 404 otherwise.\n */\nexport function useConversationPendingAuth(\n conversationId: string | undefined,\n options?: { enabled?: boolean }\n) {\n const arbi = useArbi()\n return useQuery({\n queryKey: [...arbiQueryKeys.allConversations(), conversationId ?? '', 'pending-auth'],\n queryFn: () => arbi.conversations.pendingAuth(conversationId as string),\n enabled: (options?.enabled ?? true) && !!conversationId && arbi.isLoggedIn,\n retry: false,\n })\n}\n\n/**\n * A task's history, oldest first (created, run started, handed off, sent back, done, ...). Cached\n * under the conversations prefix, so every task write that invalidates the list refreshes it too.\n * Pass `live` while a run is generating to re-read it every few seconds.\n */\nexport function useConversationActivity(\n conversationId: string | undefined,\n options?: { enabled?: boolean; live?: boolean }\n) {\n const arbi = useArbi()\n return useQuery({\n queryKey: [...arbiQueryKeys.allConversations(), conversationId ?? '', 'activity'],\n queryFn: (): Promise<ActivityResponse[]> =>\n arbi.conversations.activity(conversationId as string),\n enabled: (options?.enabled ?? true) && !!conversationId && arbi.isLoggedIn,\n refetchInterval: options?.live ? 2500 : false,\n })\n}\n\n// ── Workflows ───────────────────────────────────────────────────────────────\n\n/** The caller's workflows (their own, and the ones shared with the open workspace). */\nexport function useWorkflows(options?: { enabled?: boolean; live?: boolean }) {\n const arbi = useArbi()\n return useQuery({\n queryKey: arbiQueryKeys.workflows(),\n queryFn: (): Promise<WorkflowResponse[]> => arbi.workflows.list(),\n refetchInterval: options?.live ? 15_000 : false,\n enabled: options?.enabled ?? arbi.isLoggedIn,\n })\n}\n\n/** Create a workflow from a `CreateWorkflowRequest`. Resolves with the created workflow. */\nexport function useCreateWorkflow() {\n const arbi = useArbi()\n const qc = useQueryClient()\n return useMutation({\n mutationFn: (body: CreateWorkflowRequest): Promise<WorkflowResponse> =>\n arbi.workflows.create(body),\n onSuccess: () => qc.invalidateQueries({ queryKey: arbiQueryKeys.workflows() }),\n })\n}\n\n/** Patch a workflow: pause or resume it (`active`), share it, or change its trigger or action. */\nexport function useUpdateWorkflow() {\n const arbi = useArbi()\n const qc = useQueryClient()\n return useMutation({\n mutationFn: ({\n workflowId,\n patch,\n }: {\n workflowId: string\n patch: UpdateWorkflowRequest\n }): Promise<WorkflowResponse> => arbi.workflows.update(workflowId, patch),\n onSuccess: () => qc.invalidateQueries({ queryKey: arbiQueryKeys.workflows() }),\n })\n}\n\nexport function useDeleteWorkflow() {\n const arbi = useArbi()\n const qc = useQueryClient()\n return useMutation({\n mutationFn: (workflowId: string) => arbi.workflows.delete(workflowId),\n onSuccess: () => qc.invalidateQueries({ queryKey: arbiQueryKeys.workflows() }),\n })\n}\n\n/**\n * Run a workflow now. Resolves with the conversation it created\n * (`conversation_ext_id`), which joins the conversation list.\n */\nexport function useRunWorkflow() {\n const arbi = useArbi()\n const qc = useQueryClient()\n return useMutation({\n mutationFn: (workflowId: string): Promise<WorkflowRunResponse> =>\n arbi.workflows.run(workflowId),\n onSuccess: () =>\n Promise.all([\n qc.invalidateQueries({ queryKey: arbiQueryKeys.workflows() }),\n qc.invalidateQueries({ queryKey: arbiQueryKeys.allConversations() }),\n ]),\n })\n}\n\n// ── Agents ──────────────────────────────────────────────────────────────────\n\n/** Create an agent by name. The one-time `signing_private_key` is in the result. */\nexport function useCreateAgent() {\n const arbi = useArbi()\n const qc = useQueryClient()\n return useMutation({\n mutationFn: (name: string) => arbi.agents.create(name),\n onSuccess: () => qc.invalidateQueries({ queryKey: arbiQueryKeys.agents() }),\n })\n}\n\n/**\n * An agent's pinned config (persona, model, tool switches), or the library default config when\n * `agentExtId` is omitted: edit forms seed from the first, create forms from the second.\n */\nexport function useAgentConfig(agentExtId?: string, options?: { enabled?: boolean }) {\n const arbi = useArbi()\n return useQuery({\n queryKey: arbiQueryKeys.agentConfig(agentExtId),\n queryFn: async () =>\n (agentExtId\n ? await arbi.agents.getConfig(agentExtId)\n : await arbi.agentConfig.get('default')) as AgentConfigSections | null,\n enabled: (options?.enabled ?? true) && arbi.isLoggedIn,\n })\n}\n\n/** The model names an agent may be pinned to. */\nexport function useAgentModels(options?: { enabled?: boolean }) {\n const arbi = useArbi()\n return useQuery({\n queryKey: arbiQueryKeys.models(),\n queryFn: async () => (await arbi.agentConfig.getModels()).models.map((m) => m.model_name),\n enabled: (options?.enabled ?? true) && arbi.isLoggedIn,\n })\n}\n\nexport interface SaveAgentConfigVars {\n agentExtId: string\n /** Config title; defaults to `agent-<agentExtId>`. */\n title?: string\n /**\n * Parameters to set, per section, e.g. `{ Agents: { PERSONA: '...', WEB_SEARCH_ENABLED: true } }`.\n * Merged key by key over the agent's current config (or the default one for a new agent).\n */\n sections: AgentConfigSections\n}\n\n/** Pin a behaviour config to an agent: read its current config, merge `sections` over it, save. */\nexport function useSaveAgentConfig() {\n const arbi = useArbi()\n const qc = useQueryClient()\n return useMutation({\n mutationFn: async ({ agentExtId, title, sections }: SaveAgentConfigVars) => {\n const pinned = (await arbi.agents.getConfig(agentExtId)) as AgentConfigSections | null\n const base = pinned ?? ((await arbi.agentConfig.get('default')) as AgentConfigSections)\n const merged: AgentConfigSections = structuredClone(base)\n for (const [section, params] of Object.entries(sections)) {\n merged[section] = { ...(merged[section] ?? {}), ...params }\n }\n return arbi.agentConfig.save({\n ...merged,\n agent_ext_id: agentExtId,\n title: title ?? `agent-${agentExtId}`,\n } as never)\n },\n onSuccess: (_saved, { agentExtId }) =>\n Promise.all([\n qc.invalidateQueries({ queryKey: arbiQueryKeys.configs() }),\n qc.invalidateQueries({ queryKey: arbiQueryKeys.agentConfig(agentExtId) }),\n // The agent list shows the pinned persona/model, so it refreshes too.\n qc.invalidateQueries({ queryKey: arbiQueryKeys.agents() }),\n ]),\n })\n}\n\n/** The workspaces an agent can currently open (`permanent` tells standing from temporary). */\nexport function useAgentWorkspaces(\n agentExtId: string | undefined,\n options?: { enabled?: boolean }\n) {\n const arbi = useArbi()\n return useQuery({\n queryKey: arbiQueryKeys.agentWorkspaces(agentExtId ?? ''),\n queryFn: () => arbi.agents.listWorkspaces(agentExtId as string),\n enabled: (options?.enabled ?? true) && !!agentExtId && arbi.isLoggedIn,\n })\n}\n\n/** How an agent is given a workspace. */\nexport type AgentAccessMode =\n /** A standing member: the agent can open the workspace while the owner is away. */\n | { kind: 'standing' }\n /** A TTL'd, session-scoped key: gone when the run session ends. `ttlSeconds` omitted = default. */\n | { kind: 'temporary'; ttlSeconds?: number }\n\nexport interface GrantAgentAccessVars {\n agentExtId: string\n workspaceId: string\n /** Default `{ kind: 'standing' }`. */\n mode?: AgentAccessMode\n}\n\n/**\n * Give an agent access to a workspace you own. Standing access adds the agent as a member without\n * switching the open workspace; temporary access mints the agent's run session and deposits a\n * session-scoped key on it (the `session_pubkey_b64` path).\n */\nexport function useGrantAgentAccess() {\n const arbi = useArbi()\n const qc = useQueryClient()\n return useMutation({\n mutationFn: async ({\n agentExtId,\n workspaceId,\n mode = { kind: 'standing' },\n }: GrantAgentAccessVars) => {\n if (mode.kind === 'temporary') {\n return arbi.agents.grantTemporaryAccess(agentExtId, workspaceId, mode.ttlSeconds)\n }\n const agent = (await arbi.agents.list()).find((a) => a.external_id === agentExtId)\n if (!agent?.email) throw new Error(\"The agent's address is unknown.\")\n return arbi.workspaces.grantAccess({ workspaceId, emails: [agent.email] })\n },\n onSuccess: (_res, { agentExtId }) =>\n qc.invalidateQueries({ queryKey: arbiQueryKeys.agentWorkspaces(agentExtId) }),\n })\n}\n\n/** Take an agent out of a workspace (owner only). Restores the previously open workspace. */\nexport function useRevokeAgentAccess() {\n const arbi = useArbi()\n const qc = useQueryClient()\n return useMutation({\n mutationFn: async ({\n agentExtId,\n workspaceId,\n }: {\n agentExtId: string\n workspaceId: string\n }) => {\n const previous = arbi.hasWorkspace ? arbi.getWorkspaceId() : null\n await arbi.selectWorkspace(workspaceId)\n try {\n await arbi.workspaces.removeUsers([agentExtId])\n } finally {\n if (previous && previous !== workspaceId) await arbi.selectWorkspace(previous)\n }\n },\n onSuccess: (_res, { agentExtId }) =>\n qc.invalidateQueries({ queryKey: arbiQueryKeys.agentWorkspaces(agentExtId) }),\n })\n}\n\n// ── Skills ──────────────────────────────────────────────────────────────────\n\n/**\n * The skills the user can run (own plus the shared marketplace), metadata only. Skills live in the\n * deployment marketplace, so the list does not depend on the open workspace.\n */\nexport function useSkills(options?: {\n enabled?: boolean\n includeHidden?: boolean\n live?: boolean\n}) {\n const arbi = useArbi()\n return useQuery({\n queryKey: [...arbiQueryKeys.skills(), options?.includeHidden ?? false] as const,\n queryFn: () => arbi.assistant.listSkills({ includeHidden: options?.includeHidden }),\n refetchInterval: options?.live ? 5000 : false,\n enabled: (options?.enabled ?? true) && arbi.isLoggedIn,\n staleTime: 30_000,\n })\n}\n\n/** Upload skill files through the same document path as the main application. */\nexport function useUploadSkillFiles() {\n const arbi = useArbi()\n const qc = useQueryClient()\n return useMutation({\n mutationFn: async (\n entries: { folder: string; fileName: string; content: Blob }[]\n ): Promise<{ doc_ext_ids?: string[] }[]> => {\n if (!entries.length) throw new Error('Choose at least one skill file.')\n for (const entry of entries) {\n if (\n !/^skills\\/[a-z0-9][a-z0-9_-]*(?:\\/[^/]+)*$/.test(entry.folder) ||\n entry.folder.split('/').some((segment) => segment === '..' || segment === '.')\n )\n throw new Error('Skill files need a folder under skills/<name>.')\n }\n const results = []\n for (const entry of entries) {\n const result = await arbi.documents.uploadFile(entry.content, entry.fileName, {\n folder: entry.folder,\n wpType: 'skill',\n })\n if (result.skipped?.length)\n throw new Error(\n result.skipped.map((file) => `${file.file_name}: ${file.reason}`).join('; ')\n )\n results.push(result)\n }\n return results\n },\n onSuccess: () => qc.invalidateQueries({ queryKey: arbiQueryKeys.skills() }),\n })\n}\n\n/** Start the person's assistant as reviewable work, then resolve its persisted thread. */\nexport function useStartWorkQuery() {\n const arbi = useArbi()\n const qc = useQueryClient()\n return useMutation({\n mutationFn: async ({\n question,\n ...options\n }: Parameters<typeof arbi.assistant.submit>[1] & { question: string }) => {\n const response = await arbi.assistant.submit(question, options)\n for (let attempt = 0; attempt < 30; attempt++) {\n if (attempt) await new Promise((resolve) => setTimeout(resolve, 500))\n try {\n const message = await arbi.conversations.getMessage(response.id)\n if (message.conversation_ext_id)\n return { conversationId: message.conversation_ext_id, responseId: response.id }\n } catch (error) {\n if (!(error && typeof error === 'object' && 'status' in error && error.status === 404))\n throw error\n }\n }\n throw new Error(\n `The run ${response.id} started, but its thread is not available yet. Do not submit it again.`\n )\n },\n onSuccess: () => qc.invalidateQueries({ queryKey: arbiQueryKeys.allConversations() }),\n })\n}\n\n/** Independent agent login status, polled while its controls are visible. */\nexport function useAgentSession(agentId: string | undefined, options?: { enabled?: boolean }) {\n const arbi = useArbi()\n return useQuery({\n queryKey: ['arbi', 'agent-session', agentId],\n queryFn: () => arbi.agents.getSession(agentId!),\n enabled: !!agentId && arbi.isLoggedIn && (options?.enabled ?? true),\n refetchInterval: 5000,\n })\n}\nexport function useAgentChats(agentId: string | undefined) {\n const arbi = useArbi()\n return useQuery({\n queryKey: ['arbi', 'agent-chats', agentId],\n queryFn: () => arbi.agents.listChats(agentId!),\n enabled: !!agentId && arbi.isLoggedIn,\n refetchInterval: 5000,\n })\n}\nexport function useStartAgentSession() {\n const arbi = useArbi()\n const cache = useQueryClient()\n return useMutation({\n mutationFn: ({ agentId, workspaceId }: { agentId: string; workspaceId?: string }) =>\n arbi.agents.startSession(agentId, workspaceId),\n onSuccess: () => cache.invalidateQueries({ queryKey: ['arbi', 'agent-session'] }),\n })\n}\nexport function useCloseAgentSession() {\n const arbi = useArbi()\n const cache = useQueryClient()\n return useMutation({\n mutationFn: (agentId: string) => arbi.agents.closeSession(agentId),\n onSuccess: () => cache.invalidateQueries({ queryKey: ['arbi', 'agent-session'] }),\n })\n}\n","/**\n * Citation data for a chat answer: the SDK's `resolveCitations` / `summarizeCitations` joined into\n * one plain, serialisable shape per citation number, so a surface can show the source document,\n * page and passage for `[statement](#cite-N)` without touching SDK types.\n */\nimport {\n resolveCitations,\n summarizeCitations,\n type MessageMetadataPayload,\n} from '@arbidocs/sdk/browser'\n\nexport interface ArbiChatPassage {\n id: string\n /** The source document's id, when the backend reports it (what \"open document\" needs). */\n documentId: string | null\n documentTitle: string\n page: number | null\n text: string\n}\n\nexport interface ArbiChatCitation {\n /** The number in `(#cite-N)`. */\n num: string\n /** The statement the model cited. */\n statement: string\n /** Title of the first source document. */\n documentTitle: string\n /** Page of the first passage. */\n page: number | null\n passages: ArbiChatPassage[]\n}\n\n/** A passage as one readable line: whitespace folded, leading markdown list/heading marks dropped. */\nfunction previewText(content: string): string {\n return content\n .replace(/\\s+/g, ' ')\n .trim()\n .replace(/^(?:(?:[-*•>]|#{1,6})\\s+)+/, '')\n}\n\n/** The citations of a message's `tools` (stored history) or of streamed metadata. */\nexport function toChatCitations(\n source: { tools?: object | null } | null | undefined\n): ArbiChatCitation[] {\n if (!source?.tools) return []\n // Stored messages and streamed metadata carry the same `tools` map.\n const resolved = resolveCitations(source as MessageMetadataPayload)\n const summaries = summarizeCitations(resolved)\n return resolved.map((r, i) => {\n const summary = summaries[i]\n return {\n num: r.citationNum,\n statement: summary.statement,\n documentTitle: summary.docTitle,\n page: summary.pageNumber,\n passages: r.chunks.map((chunk) => ({\n id: chunk.metadata.chunk_ext_id,\n documentId: chunk.metadata.doc_ext_id ?? null,\n documentTitle: chunk.metadata.doc_title ?? summary.docTitle,\n page: chunk.metadata.page_number ?? null,\n text: previewText(chunk.content),\n })),\n }\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 are the workspace's stored conversations (backend titles, newest first) plus the new\n * chat being written: opening an old one loads its messages (citations included), the first\n * question of a new chat creates its conversation on the backend, follow-ups chain through the\n * previous response id so each thread keeps its context. Everything resets when `workspaceId`\n * changes. `stop()` aborts the running answer.\n */\nimport { useCallback, useEffect, useMemo, useRef, useState } from 'react'\nimport { useArbi } from '../useArbi'\nimport { useAgentChats } from '../workforce'\nimport { useAssistantQuery, useConversations, useConversationThreads, useDocuments } from '../hooks'\nimport { toChatCitations, type ArbiChatCitation } from './citations'\nimport type { QueryOptions } from '@arbidocs/sdk/browser'\n\nexport type { ArbiChatCitation, ArbiChatPassage } from './citations'\n\nexport type ArbiChatRole = 'user' | 'assistant'\nexport type ArbiChatMessageStatus = 'streaming' | 'complete' | 'error'\n\nexport interface ArbiChatMessage {\n mentions?: QueryOptions['mentions']\n authorId?: string\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 /** The sources behind `[statement](#cite-N)` marks in `content`. */\n citations?: ArbiChatCitation[]\n /** The reader stopped the answer; `content` is what had streamed. */\n stopped?: boolean\n /** The backend id of a finished assistant answer: what a follow-up chains from. */\n responseId?: string\n}\n\nexport interface ArbiChatThread {\n id: string\n /** The backend title, else 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 /** Use an owned agent's independent session, history and sandbox files. */\n agentId?: string\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 (used until the backend has titled the conversation). Default 48. */\n titleLength?: number\n /**\n * When the answer stream ends without the terminal `response.completed` event (a dropped\n * connection, a stalled run), the stored message is polled this often (ms) and for at most\n * `timeoutMs` before the turn is shown as failed with a Retry. Default 3000 / 120000.\n */\n streamRecovery?: { intervalMs?: number; timeoutMs?: number }\n}\n\nexport interface ArbiChat {\n assistantMode: 'always' | 'mentioned'\n isUpdatingAssistantMode: boolean\n isPostingComment: boolean\n setAssistantMode: (mode: 'always' | 'mentioned') => Promise<void>\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 /** A stored conversation's messages are loading. */\n isLoadingThread: boolean\n /** The conversation list is loading. */\n isLoadingThreads: boolean\n /** Loading or deleting a stored conversation failed. */\n historyError: string | null\n documents: ArbiChatDocument[]\n isLoadingDocuments: boolean\n isUploading: boolean\n uploadError: string | null\n send: (text: string, options?: { mentions?: QueryOptions['mentions'] }) => Promise<void>\n /** Re-ask the question whose answer failed. */\n retry: () => Promise<void>\n /** Abort the running answer; what streamed so far stays, marked stopped. */\n stop: () => void\n selectThread: (id: string) => void\n newThread: () => void\n /** Deletes the conversation on the backend too. */\n deleteThread: (id: string) => void\n toggleDocument: (id: string) => void\n selectAllDocuments: () => void\n upload: (files: File[]) => Promise<void>\n}\n\ninterface LocalChatMessage extends ArbiChatMessage {\n pendingHistory?: boolean\n storedId?: string\n questionId?: string\n}\n\ninterface ThreadState {\n assistantMode?: 'always' | 'mentioned'\n /** Stable local key: never changes, even when the backend conversation appears. */\n key: string\n /** The backend conversation, once there is one. The public thread id is this, else `key`. */\n conversationId: string | null\n /** Local title (the first question) until the backend has one. */\n title: string\n messages: LocalChatMessage[]\n responseId: string | null\n /** False for a stored conversation whose messages have not been fetched yet. */\n isLoaded: boolean\n}\n\nlet counter = 0\nconst nextId = (prefix: string) =>\n `${prefix}-${Date.now().toString(36)}-${(counter++).toString(36)}`\n\nconst emptyThread = (): ThreadState => ({\n key: nextId('thread'),\n conversationId: null,\n title: '',\n messages: [],\n responseId: null,\n isLoaded: true,\n})\n\nconst storedThread = (conversationId: string): ThreadState => ({\n key: conversationId,\n conversationId,\n title: '',\n messages: [],\n responseId: null,\n isLoaded: false,\n})\n\nconst publicId = (t: ThreadState) => t.conversationId ?? t.key\n\ntype StoredMessage = {\n mentions?: QueryOptions['mentions']\n created_by_ext_id?: string | null\n external_id: string\n role: 'user' | 'assistant' | 'system'\n content: string\n status: string\n tools?: object\n}\n\nconst UNFINISHED_STATUSES: ReadonlySet<string> = new Set(['failed', 'in_progress', 'queued'])\nconst FAILED_MESSAGE = 'The assistant request failed.'\nconst UNFINISHED_MESSAGE = 'The answer did not finish. Try again.'\n\n/** A stored assistant message that never reached `completed` (failed, or still `in_progress`/`queued`). */\nconst isUnfinished = (m: StoredMessage) => UNFINISHED_STATUSES.has(m.status)\n\n/**\n * A stored conversation's primary thread (the longest) as chat messages. An assistant answer that\n * never finished is kept as a failed message (with Retry) — never dropped or shown as an empty bubble.\n */\nfunction messagesFromHistory(\n history: ReadonlyArray<StoredMessage>,\n live = false\n): ArbiChatMessage[] {\n return history\n .filter(\n (m) =>\n m.role !== 'system' &&\n (m.content.trim() !== '' ||\n (m.role === 'assistant' && (isUnfinished(m) || m.status === 'cancelled')))\n )\n .map((m) => {\n if (m.role === 'user') {\n return {\n id: m.external_id,\n role: 'user',\n content: m.content,\n status: 'complete',\n ...(m.created_by_ext_id ? { authorId: m.created_by_ext_id } : {}),\n ...(m.mentions?.length ? { mentions: m.mentions } : {}),\n }\n }\n const citations = toChatCitations({ tools: m.tools })\n const unfinished = isUnfinished(m)\n const runningElsewhere = live && (m.status === 'in_progress' || m.status === 'queued')\n return {\n id: m.external_id,\n role: 'assistant',\n content: m.content,\n status: runningElsewhere ? 'streaming' : unfinished ? 'error' : 'complete',\n ...(m.status === 'cancelled' ? { stopped: true } : {}),\n ...(unfinished && !runningElsewhere\n ? { error: m.status === 'failed' ? FAILED_MESSAGE : UNFINISHED_MESSAGE }\n : {}),\n ...(unfinished ? {} : { responseId: m.external_id }),\n ...(citations.length > 0 ? { citations } : {}),\n }\n })\n}\n\n/** Accept shared history without dropping local turns the server has not acknowledged yet. */\nfunction mergeHistory(history: ArbiChatMessage[], local: LocalChatMessage[]): LocalChatMessage[] {\n const merged: LocalChatMessage[] = [...history]\n for (const message of local) {\n if (!message.pendingHistory) continue\n const question = local.find((candidate) => candidate.id === message.questionId)\n const pending =\n question?.storedId && history.some((stored) => stored.id === question.storedId)\n ? { ...message, questionId: question.storedId }\n : message\n const storedId = message.storedId ?? message.responseId ?? message.id\n const index = merged.findIndex((stored) => stored.id === storedId)\n if (index < 0) merged.push(pending)\n else if (message.role === 'assistant' && merged[index].status === 'streaming') {\n // An older snapshot must not erase a finished or failed local answer.\n merged[index] = pending\n }\n }\n return merged\n}\n\n/** Failed or stalled answers must never become the parent of the next question. */\nfunction chainId(messages: ReadonlyArray<ArbiChatMessage>): string | null {\n for (let i = messages.length - 1; i >= 0; i--) {\n const m = messages[i]\n if (m.role === 'assistant' && m.status === 'complete' && m.responseId) return m.responseId\n }\n return null\n}\n\nconst sleep = (ms: number) => new Promise<void>((resolve) => setTimeout(resolve, ms))\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)\nconst isAbort = (e: unknown) => e instanceof DOMException && e.name === 'AbortError'\n\n/** The backend titles a conversation a moment after its first answer: look again a few times. */\nconst TITLE_REFRESH_DELAYS_MS = [2500, 6000, 12000]\n\nexport function useArbiChat(options: UseArbiChatOptions = {}): ArbiChat {\n const { workspaceId, agentId, model, titleLength = 48, streamRecovery } = options\n const recoveryIntervalMs = streamRecovery?.intervalMs ?? 3000\n const recoveryTimeoutMs = streamRecovery?.timeoutMs ?? 120000\n const arbi = useArbi()\n const { data: docs = [], isLoading: isLoadingDocuments, refetch } = useDocuments(workspaceId)\n const ordinaryHistory = useConversations(workspaceId, { enabled: !agentId, live: true })\n const agentHistory = useAgentChats(agentId)\n const stored = useMemo(\n () =>\n agentId\n ? (agentHistory.data ?? [])\n .filter((chat) => chat.workspace_ext_id === workspaceId)\n .map((chat) => ({\n external_id: chat.conversation_ext_id,\n title: chat.title,\n updated_at: chat.updated_at,\n message_count: 1,\n status: null,\n assistant_mode: 'always' as const,\n }))\n : (ordinaryHistory.data ?? []),\n [agentId, agentHistory.data, ordinaryHistory.data, workspaceId]\n )\n const isLoadingThreads = agentId ? agentHistory.isLoading : ordinaryHistory.isLoading\n const refetchConversations = agentId ? agentHistory.refetch : ordinaryHistory.refetch\n const query = useAssistantQuery()\n const { mutateAsync } = query\n\n const [stagedFiles, setStagedFiles] = useState<Array<{ id: string; name: string }>>([])\n const [threads, setThreads] = useState<ThreadState[]>(() => [emptyThread()])\n const [activeKey, setActiveKey] = useState(() => threads[0].key)\n const [deselected, setDeselected] = useState<ReadonlySet<string>>(new Set())\n const [isRunning, setIsRunning] = useState(false)\n const [isPostingComment, setIsPostingComment] = useState(false)\n const [isUpdatingAssistantMode, setIsUpdatingAssistantMode] = useState(false)\n const [isUploading, setIsUploading] = useState(false)\n const [uploadError, setUploadError] = useState<string | null>(null)\n const [historyError, setHistoryError] = useState<string | null>(null)\n const abortRef = useRef<AbortController | null>(null)\n const runIdRef = useRef<string | null>(null)\n const stopRequestedRef = useRef(false)\n const timersRef = useRef<ReturnType<typeof setTimeout>[]>([])\n\n useEffect(() => {\n const timers = timersRef.current\n return () => timers.forEach(clearTimeout)\n }, [])\n\n // Everything is scoped to one workspace: start clean when it changes.\n const chatScope = `${workspaceId ?? ''}:${agentId ?? ''}`\n const scopeRef = useRef(chatScope)\n useEffect(() => {\n if (scopeRef.current === chatScope) return\n scopeRef.current = chatScope\n setStagedFiles([])\n const fresh = emptyThread()\n setThreads([fresh])\n setActiveKey(fresh.key)\n setDeselected(new Set())\n setUploadError(null)\n setHistoryError(null)\n }, [chatScope])\n\n const active = threads.find((t) => t.key === activeKey) ?? threads[0]\n const assistantMode =\n active.assistantMode ??\n stored.find((c) => c.external_id === active.conversationId)?.assistant_mode ??\n 'always'\n\n // The list: the chat being written, then the workspace's stored conversations, newest first\n // (a stored conversation we hold messages for is shown from our copy, with the backend title).\n const threadEntries = useMemo(() => {\n const storedIds = new Set(stored.map((c) => c.external_id))\n const byConversation = new Map(\n threads.filter((t) => t.conversationId).map((t) => [t.conversationId as string, t])\n )\n const fresh = threads.filter((t) => !t.conversationId)\n const justSaved = threads.filter((t) => t.conversationId && !storedIds.has(t.conversationId))\n const persisted = [...stored]\n .filter((c) => c.status != null || c.message_count > 0 || byConversation.has(c.external_id))\n .sort((a, b) => b.updated_at.localeCompare(a.updated_at))\n .map((c) => {\n const local = byConversation.get(c.external_id)\n return {\n key: local?.key ?? c.external_id,\n id: c.external_id,\n title: c.title || local?.title || '',\n }\n })\n return [\n ...fresh.map((t) => ({ key: t.key, id: publicId(t), title: t.title })),\n ...justSaved.map((t) => ({ key: t.key, id: publicId(t), title: t.title })),\n ...persisted,\n ]\n }, [threads, stored])\n\n const liveHistory =\n assistantMode === 'mentioned' ||\n stored.some(\n (conversation) =>\n conversation.external_id === active.conversationId && conversation.status === 'generating'\n ) ||\n active.messages.some((message) => message.status === 'streaming')\n const needsLoad = !!active.conversationId && !active.isLoaded\n const loaded = useConversationThreads(workspaceId, active.conversationId ?? undefined, {\n enabled: needsLoad || (liveHistory && !isRunning && !isPostingComment),\n live: liveHistory,\n })\n const refetchThread = loaded.refetch\n const selectedStored = stored.find(\n (conversation) => conversation.external_id === active.conversationId\n )\n const historyRevision = selectedStored\n ? `${selectedStored.external_id}:${selectedStored.updated_at}:${selectedStored.message_count}:${selectedStored.status}`\n : undefined\n const observedHistoryRevision = useRef<string | undefined>(undefined)\n useEffect(() => {\n const previous = observedHistoryRevision.current\n observedHistoryRevision.current = historyRevision\n // Completion can reach the list after an initial history containing only the question.\n // Fetch again when stored metadata advances, even if the run has already become ready.\n if (\n previous &&\n previous !== historyRevision &&\n active.isLoaded &&\n !isRunning &&\n !isPostingComment\n )\n void refetchThread()\n }, [historyRevision, active.isLoaded, isRunning, isPostingComment, refetchThread])\n useEffect(() => {\n const data = loaded.data\n if (\n isRunning ||\n isPostingComment ||\n !data ||\n data.conversation_ext_id !== active.conversationId\n )\n return\n const primary = [...data.threads].sort((a, b) => b.history.length - a.history.length)[0]\n const messages = messagesFromHistory(primary?.history ?? [], liveHistory)\n setThreads((all) =>\n all.map((t) =>\n t.key === active.key\n ? (() => {\n const merged = mergeHistory(messages, t.messages)\n return {\n ...t,\n isLoaded: true,\n assistantMode: data.assistant_mode,\n messages: merged,\n responseId: chainId(merged),\n }\n })()\n : t\n )\n )\n }, [\n loaded.data,\n liveHistory,\n needsLoad,\n active.conversationId,\n active.key,\n assistantMode,\n isRunning,\n isPostingComment,\n ])\n useEffect(() => {\n if (loaded.error)\n setHistoryError(messageOf(loaded.error, 'The conversation could not be loaded.'))\n }, [loaded.error])\n\n const selectedIds = useMemo(\n () =>\n (agentId ? [] : docs)\n .map((d) => d.external_id)\n .filter((id): id is string => !!id && !deselected.has(id)),\n [docs, deselected, agentId]\n )\n const documents = useMemo<ArbiChatDocument[]>(\n () =>\n agentId\n ? stagedFiles.map((file) => ({ ...file, isSelected: !deselected.has(file.id) }))\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, agentId, stagedFiles]\n )\n\n const patchThread = useCallback(\n (key: string, patch: (t: ThreadState) => ThreadState) =>\n setThreads((all) => all.map((t) => (t.key === key ? patch(t) : t))),\n []\n )\n const patchMessage = useCallback(\n (threadKey: string, messageId: string, patch: Partial<LocalChatMessage>) =>\n patchThread(threadKey, (t) => ({\n ...t,\n messages: t.messages.map((m) => (m.id === messageId ? { ...m, ...patch } : m)),\n })),\n [patchThread]\n )\n\n const refreshTitles = useCallback(() => {\n void refetchConversations()\n timersRef.current.forEach(clearTimeout)\n timersRef.current = TITLE_REFRESH_DELAYS_MS.map((delay) =>\n setTimeout(() => void refetchConversations(), delay)\n )\n }, [refetchConversations])\n\n /**\n * Poll the stored assistant message until it settles. `completed` carries the stored answer,\n * `failed` a run the backend gave up on, `null` one still unfinished when the time is up (or\n * unknowable: no conversation yet, or the read keeps failing).\n */\n const recoverStoredAnswer = useCallback(\n async (\n conversationId: string | null,\n messageId: string | null,\n signal: AbortSignal\n ): Promise<{ kind: 'completed'; message: StoredMessage } | { kind: 'failed' } | null> => {\n if (!conversationId || !messageId) return null\n const deadline = Date.now() + recoveryTimeoutMs\n let failedReads = 0\n for (;;) {\n try {\n const { threads: all } = await arbi.conversations.getThreads(conversationId)\n const found = all\n .flatMap((t) => t.history as ReadonlyArray<StoredMessage>)\n .find((m) => m.external_id === messageId)\n if (found?.status === 'completed' && found.content.trim() !== '') {\n return { kind: 'completed', message: found }\n }\n if (found?.status === 'failed') return { kind: 'failed' }\n failedReads = 0\n } catch {\n // One failed read is not a verdict; a stored message that stays unreadable is.\n if (++failedReads >= 3) return null\n }\n if (signal.aborted || Date.now() + recoveryIntervalMs > deadline) return null\n await sleep(recoveryIntervalMs)\n }\n },\n [arbi, recoveryIntervalMs, recoveryTimeoutMs]\n )\n\n const cancelNativeRun = useCallback(\n async (responseId: string, controller: AbortController) => {\n try {\n await arbi.assistant.cancelRun(responseId)\n if (abortRef.current === controller) controller.abort()\n } catch (error) {\n stopRequestedRef.current = false\n setHistoryError(messageOf(error, 'The agent run could not be stopped.'))\n }\n },\n [arbi]\n )\n\n const ask = useCallback(\n async (thread: ThreadState, text: string, mentions?: QueryOptions['mentions']) => {\n const userMessage: LocalChatMessage = {\n pendingHistory: true,\n ...(mentions?.length ? { mentions } : {}),\n id: nextId('msg'),\n role: 'user',\n content: text,\n status: 'complete',\n }\n const answer: LocalChatMessage = {\n pendingHistory: true,\n questionId: userMessage.id,\n id: nextId('msg'),\n role: 'assistant',\n content: '',\n status: 'streaming',\n }\n patchThread(thread.key, (t) => ({\n ...t,\n title: t.title || titleFromQuestion(text, titleLength),\n messages: [...t.messages, userMessage, answer],\n }))\n const controller = new AbortController()\n abortRef.current = controller\n runIdRef.current = null\n stopRequestedRef.current = false\n setIsRunning(true)\n let buffer = ''\n let steps = 0\n let streamError: string | null = null\n let conversationId = thread.conversationId\n let backendMessageId: string | null = null\n // A turn that does not finish must not become the parent of the next question.\n const revertChain = () =>\n patchThread(thread.key, (t) => ({ ...t, responseId: chainId(t.messages) }))\n const fail = (error: string, content?: string) => {\n patchMessage(thread.key, answer.id, {\n status: 'error',\n error,\n ...(content !== undefined ? { content } : {}),\n })\n revertChain()\n }\n try {\n const lastMessage = thread.messages[thread.messages.length - 1]\n const parentId =\n lastMessage?.role === 'user' && (lastMessage.storedId || !lastMessage.pendingHistory)\n ? (lastMessage.storedId ?? lastMessage.id)\n : thread.responseId\n const result = await mutateAsync({\n question:\n agentId && stagedFiles.some((file) => !deselected.has(file.id))\n ? text +\n '\\n\\nSource files staged in your sandbox:\\n' +\n stagedFiles\n .filter((file) => !deselected.has(file.id))\n .map((file) => `${file.name}: ${file.id}`)\n .join('\\n')\n : text,\n ...(agentId ? { agentId, workspaceId } : {}),\n docIds: selectedIds,\n previousResponseId: parentId,\n ...(thread.conversationId ? { conversationId: thread.conversationId } : {}),\n ...(!thread.conversationId && thread.assistantMode === 'mentioned'\n ? { assistantMode: 'mentioned' as const }\n : {}),\n ...(mentions?.length ? { mentions } : {}),\n model,\n signal: controller.signal,\n onStreamStart: (data) => {\n // Chain follow-ups even when this answer is stopped before it completes.\n if (data.assistant_message_ext_id) {\n backendMessageId = data.assistant_message_ext_id\n runIdRef.current = backendMessageId\n if (agentId && stopRequestedRef.current)\n void cancelNativeRun(backendMessageId, controller)\n patchMessage(thread.key, answer.id, { storedId: backendMessageId })\n patchThread(thread.key, (t) => ({\n ...t,\n responseId: data.assistant_message_ext_id ?? t.responseId,\n }))\n }\n },\n onUserMessage: (ev) => {\n conversationId = conversationId ?? ev.conversation_ext_id\n patchMessage(thread.key, userMessage.id, { storedId: ev.external_id })\n // The first question of a new chat creates its conversation on the backend.\n patchThread(thread.key, (t) => ({\n ...t,\n conversationId: t.conversationId ?? ev.conversation_ext_id,\n }))\n },\n onMetadata: (meta) => {\n const citations = toChatCitations(meta)\n if (citations.length > 0) patchMessage(thread.key, answer.id, { citations })\n },\n onToken: (token) => {\n buffer += token\n patchMessage(thread.key, 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.key, 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 const messageId = result.assistantMessageExtId ?? backendMessageId\n if (failure && !finalText) {\n fail(failure)\n } else if (!result.completed && !failure) {\n // The stream ended without a terminal event: the run may have finished (or still be\n // running) server-side. Ask the stored message instead of calling an empty bubble done.\n const stored = await recoverStoredAnswer(conversationId, messageId, controller.signal)\n if (stored?.kind === 'completed') {\n const citations = toChatCitations({ tools: stored.message.tools })\n patchMessage(thread.key, answer.id, {\n status: 'complete',\n content: stored.message.content,\n stepCount: result.agentSteps.length || steps || undefined,\n responseId: stored.message.external_id,\n ...(citations.length > 0 ? { citations } : {}),\n })\n patchThread(thread.key, (t) => ({ ...t, responseId: stored.message.external_id }))\n } else if (controller.signal.aborted) {\n patchMessage(thread.key, answer.id, {\n status: 'complete',\n content: finalText,\n stopped: true,\n })\n } else {\n fail(\n stored?.kind === 'failed' ? FAILED_MESSAGE : UNFINISHED_MESSAGE,\n finalText || undefined\n )\n }\n } else {\n const citations = toChatCitations(result.metadata)\n patchMessage(thread.key, answer.id, {\n status: 'complete',\n content: finalText,\n stepCount: result.agentSteps.length || steps || undefined,\n ...(messageId ? { responseId: messageId } : {}),\n ...(citations.length > 0 ? { citations } : {}),\n })\n patchThread(thread.key, (t) => ({ ...t, responseId: messageId ?? t.responseId }))\n }\n } catch (e) {\n if (controller.signal.aborted || isAbort(e)) {\n patchMessage(thread.key, answer.id, {\n status: 'complete',\n content: buffer,\n stopped: true,\n })\n } else {\n fail(messageOf(e, FAILED_MESSAGE))\n }\n } finally {\n if (abortRef.current === controller) abortRef.current = null\n setIsRunning(false)\n refreshTitles()\n }\n },\n [\n mutateAsync,\n patchMessage,\n patchThread,\n refreshTitles,\n recoverStoredAnswer,\n selectedIds,\n model,\n titleLength,\n agentId,\n cancelNativeRun,\n workspaceId,\n stagedFiles,\n deselected,\n ]\n )\n\n const send = useCallback(\n async (text: string, options?: { mentions?: QueryOptions['mentions'] }) => {\n const trimmed = text.trim()\n if (!trimmed || isRunning || isPostingComment || isUpdatingAssistantMode || !active.isLoaded)\n return\n setHistoryError(null)\n if (\n assistantMode === 'mentioned' &&\n !options?.mentions?.some((m) => m.type === 'assistant')\n ) {\n setIsPostingComment(true)\n setHistoryError(null)\n try {\n const saved = await arbi.conversations.postMessage({\n content: trimmed,\n assistant_mode: 'mentioned',\n mentions: options?.mentions ?? [],\n ...(active.conversationId ? { conversation_ext_id: active.conversationId } : {}),\n })\n patchThread(active.key, (t) => ({\n ...t,\n conversationId: saved.conversation_ext_id,\n title: t.title || titleFromQuestion(trimmed, titleLength),\n assistantMode: 'mentioned',\n responseId: saved.external_id,\n messages: [\n ...t.messages,\n {\n pendingHistory: true,\n id: saved.external_id,\n role: 'user',\n content: saved.content,\n status: 'complete',\n ...(saved.created_by_ext_id ? { authorId: saved.created_by_ext_id } : {}),\n },\n ],\n }))\n await refetchConversations()\n if (active.conversationId) await refetchThread()\n } catch (e) {\n setHistoryError(messageOf(e, 'The comment could not be posted.'))\n throw e\n } finally {\n setIsPostingComment(false)\n }\n return\n }\n if (active.messages.some((message) => message.status === 'streaming')) {\n const message =\n 'An assistant reply is already running in this thread. You can still post a comment.'\n setHistoryError(message)\n throw new Error(message)\n }\n await ask(active, trimmed, options?.mentions)\n },\n [\n active,\n ask,\n isRunning,\n isPostingComment,\n isUpdatingAssistantMode,\n assistantMode,\n arbi,\n patchThread,\n titleLength,\n refetchConversations,\n refetchThread,\n ]\n )\n\n const setAssistantMode = useCallback(\n async (mode: 'always' | 'mentioned') => {\n if (isRunning || isPostingComment || isUpdatingAssistantMode) return\n setIsUpdatingAssistantMode(true)\n setHistoryError(null)\n try {\n if (active.conversationId) {\n await arbi.conversations.setAssistantMode(active.conversationId, mode)\n await refetchThread()\n }\n patchThread(active.key, (t) => ({ ...t, assistantMode: mode }))\n await refetchConversations()\n } catch (e) {\n setHistoryError(messageOf(e, 'The assistant mode could not be changed.'))\n } finally {\n setIsUpdatingAssistantMode(false)\n }\n },\n [\n active,\n arbi,\n patchThread,\n refetchConversations,\n refetchThread,\n isRunning,\n isPostingComment,\n isUpdatingAssistantMode,\n ]\n )\n\n const stop = useCallback(() => {\n const controller = abortRef.current\n if (!controller) return\n if (!agentId) {\n controller.abort()\n return\n }\n stopRequestedRef.current = true\n if (runIdRef.current) void cancelNativeRun(runIdRef.current, controller)\n }, [agentId, cancelNativeRun])\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 = failed?.questionId\n ? messages.find((message) => message.id === failed.questionId)\n : messages[messages.length - 2]\n if (failed?.status !== 'error' || question?.role !== 'user') return\n const rest = messages.filter(\n (message) => message.id !== failed.id && message.id !== question.id\n )\n const trimmed: ThreadState = { ...active, messages: rest, responseId: chainId(rest) }\n patchThread(active.key, () => trimmed)\n await ask(trimmed, question.content, question.mentions)\n }, [active, ask, isRunning, patchThread])\n\n const newThread = useCallback(() => {\n setHistoryError(null)\n // One blank chat at most: reuse it instead of piling up empty ones.\n const blank = threads.find((t) => !t.conversationId && t.messages.length === 0)\n if (blank) {\n setActiveKey(blank.key)\n return\n }\n const fresh = emptyThread()\n setThreads((all) => [fresh, ...all])\n setActiveKey(fresh.key)\n }, [threads])\n\n const selectThread = useCallback(\n (id: string) => {\n const entry = threadEntries.find((e) => e.id === id)\n if (!entry) return\n setHistoryError(null)\n setThreads((all) => (all.some((t) => t.key === entry.key) ? all : [...all, storedThread(id)]))\n setActiveKey(entry.key)\n },\n [threadEntries]\n )\n\n const deleteThread = useCallback(\n (id: string) => {\n const entry = threadEntries.find((e) => e.id === id)\n if (!entry) return\n const remove = () => {\n const rest = threads.filter((t) => t.key !== entry.key)\n const next = rest.length > 0 ? rest : [emptyThread()]\n setThreads(next)\n if (entry.key === active.key) setActiveKey(next[0].key)\n }\n const local = threads.find((t) => t.key === entry.key)\n const conversationId = local ? local.conversationId : id\n if (!conversationId) return remove()\n void (async () => {\n try {\n await arbi.conversations.delete(conversationId)\n remove()\n await refetchConversations()\n } catch (e) {\n setHistoryError(messageOf(e, 'The conversation could not be deleted.'))\n }\n })()\n },\n [threadEntries, threads, active.key, arbi, refetchConversations]\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) {\n if (agentId) {\n const staged = await arbi.agents.stageFile(agentId, file, file.name)\n setStagedFiles((all) => [\n ...all.filter((existing) => existing.id !== staged.path),\n { id: staged.path, name: staged.name },\n ])\n } else await arbi.documents.uploadFile(file, file.name)\n }\n // New documents are not in `deselected`, so they join the selection by default.\n if (!agentId) await refetch()\n } catch (e) {\n setUploadError(messageOf(e, 'The upload failed.'))\n } finally {\n setIsUploading(false)\n }\n },\n [arbi, refetch, agentId]\n )\n\n return {\n assistantMode,\n isUpdatingAssistantMode,\n isPostingComment,\n setAssistantMode,\n threads: threadEntries.map(({ id, title }) => ({ id, title })),\n activeThreadId: publicId(active),\n messages: active.messages,\n isRunning,\n error,\n isLoadingThread: needsLoad && !historyError,\n isLoadingThreads,\n historyError,\n documents,\n isLoadingDocuments,\n isUploading,\n uploadError,\n send,\n retry,\n stop,\n selectThread,\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 * Contacts: the user's colleagues and pending invitations.\n *\n * Shares `arbiQueryKeys.contacts()` with `useDirectMessages`, so a change made here refreshes the\n * conversation rail on its own. The parts that turn an email list into a request and the backend\n * outcome into a sentence live in `@arbidocs/blocks/collaboration` (`AddContactsForm`).\n */\n\nimport { useMemo } from 'react'\nimport { useMutation, useQuery, useQueryClient } from '@tanstack/react-query'\nimport { useArbi } from './useArbi'\nimport { arbiQueryKeys } from './hooks'\n\n/** The user's contacts, registered and pending. */\nexport function useContacts(options?: { enabled?: boolean }) {\n const arbi = useArbi()\n return useQuery({\n queryKey: arbiQueryKeys.contacts(),\n queryFn: () => arbi.contacts.list(),\n enabled: (options?.enabled ?? true) && arbi.isLoggedIn,\n })\n}\n\n/** Contacts still waiting to join (an invitation sent or expired); `Invite again` re-adds them. */\nexport function usePendingContacts(options?: { enabled?: boolean }) {\n const contacts = useContacts(options)\n const pending = useMemo(\n () =>\n (contacts.data ?? []).filter(\n (c) => c.status === 'invitation_pending' || c.status === 'invitation_expired'\n ),\n [contacts.data]\n )\n return { ...contacts, pending }\n}\n\n/**\n * Add contacts by email. An address not yet on ARBI is invited. Resolves with one row per\n * address (`outcome`, `status`); map it with `toAddContactsRows` from `@arbidocs/blocks/collaboration`.\n */\nexport function useAddContacts() {\n const arbi = useArbi()\n const qc = useQueryClient()\n return useMutation({\n mutationFn: (emails: string[]) => arbi.contacts.add(emails),\n onSuccess: () => qc.invalidateQueries({ queryKey: arbiQueryKeys.contacts() }),\n })\n}\n\n/** Remove contacts, or withdraw invitations, by contact id. */\nexport function useRemoveContacts() {\n const arbi = useArbi()\n const qc = useQueryClient()\n return useMutation({\n mutationFn: (contactIds: string[]) => arbi.contacts.remove(contactIds),\n onSuccess: () => qc.invalidateQueries({ queryKey: arbiQueryKeys.contacts() }),\n })\n}\n","/**\n * Profile: the signed-in user's name and picture.\n *\n * Two layers, like the rest of the package. The SDK-bound hooks (`useProfile`, `useUpdateProfile`)\n * need an `ArbiProvider`. The controllers (`useNameEditor`, `useAvatarCrop`) own only the form\n * state and take the save as a function, so an app that has its own API layer (ARBI-frontend)\n * binds the same `ProfileCard` / `AvatarPicker` parts without a provider.\n */\n\nimport { useCallback, useState } from 'react'\nimport { useMutation, useQuery, useQueryClient } from '@tanstack/react-query'\nimport type { LoginProfile } from '@arbidocs/sdk/browser'\nimport { useArbi } from '../useArbi'\nimport { arbiQueryKeys } from '../hooks'\n\n// ── View model ──────────────────────────────────────────────────────────────\n\nexport interface ProfileView {\n givenName: string\n familyName: string | null\n picture: string | null\n email: string\n /** The sign-in provider manages the email (it cannot be changed here). */\n isSso: boolean\n /** Given and family name joined; empty while the profile has no name. */\n fullName: string\n}\n\n/** The profile as the UI reads it. `fullName` is the profile name, never the email. */\nexport function toProfileView(profile: LoginProfile): ProfileView {\n return {\n ...profile,\n fullName: [profile.givenName, profile.familyName]\n .map((part) => part?.trim())\n .filter(Boolean)\n .join(' '),\n }\n}\n\n// ── SDK-bound hooks ─────────────────────────────────────────────────────────\n\n/** The signed-in user's profile; `null` when the session has none (restored without a login). */\nexport function useProfile(options?: { enabled?: boolean }) {\n const arbi = useArbi()\n return useQuery({\n queryKey: arbiQueryKeys.profile(),\n queryFn: (): ProfileView | null => {\n const profile = arbi.user.profile()\n return profile ? toProfileView(profile) : null\n },\n enabled: (options?.enabled ?? true) && arbi.isLoggedIn,\n staleTime: Infinity,\n })\n}\n\nexport interface UpdateProfileVars {\n givenName?: string\n /** `''` clears it. */\n familyName?: string\n /** A data URL or URL; `''` clears it (the backend caps it at 100 KB). */\n picture?: string\n}\n\n/**\n * Save the name and/or picture (PATCH /v1/user/profile). The profile query is updated in place and\n * the workspace list (member rows carry the name) is refreshed, so every surface follows.\n */\nexport function useUpdateProfile() {\n const arbi = useArbi()\n const qc = useQueryClient()\n return useMutation({\n mutationFn: async (vars: UpdateProfileVars) => {\n await arbi.profile.update({\n ...(vars.givenName !== undefined && { given_name: vars.givenName.trim() }),\n ...(vars.familyName !== undefined && { family_name: vars.familyName.trim() }),\n ...(vars.picture !== undefined && { picture: vars.picture }),\n })\n const profile = arbi.user.profile()\n return profile ? toProfileView(profile) : null\n },\n onSuccess: (profile) => {\n qc.setQueryData(arbiQueryKeys.profile(), profile)\n return qc.invalidateQueries({ queryKey: arbiQueryKeys.workspaces() })\n },\n })\n}\n\n// ── Controllers (no SDK) ────────────────────────────────────────────────────\n\nexport interface UseNameEditorOptions {\n givenName: string | null | undefined\n familyName: string | null | undefined\n /** Persist the new name. Reject to keep the editor open (see `error`). */\n save: (name: { givenName: string; familyName: string }) => Promise<unknown> | unknown\n}\n\nexport interface NameEditor {\n isEditing: boolean\n givenName: string\n familyName: string\n onGivenNameChange: (value: string) => void\n onFamilyNameChange: (value: string) => void\n onStartEdit: () => void\n onSave: () => void\n onCancel: () => void\n isSaving: boolean\n /** The last failed save. */\n error: unknown\n}\n\n/**\n * State of the inline name editor of `ProfileCard`: start edit (seeded from the current name),\n * save (trimmed; a blank given name is not saved), cancel. Spread it into `ProfileCard`'s `name`\n * with `display`.\n */\nexport function useNameEditor({ givenName, familyName, save }: UseNameEditorOptions): NameEditor {\n const [isEditing, setIsEditing] = useState(false)\n const [given, setGiven] = useState('')\n const [family, setFamily] = useState('')\n const [isSaving, setIsSaving] = useState(false)\n const [error, setError] = useState<unknown>(null)\n\n const onStartEdit = useCallback(() => {\n setGiven(givenName ?? '')\n setFamily(familyName ?? '')\n setError(null)\n setIsEditing(true)\n }, [givenName, familyName])\n\n const onSave = useCallback(() => {\n const trimmedGiven = given.trim()\n if (!trimmedGiven) return\n setIsSaving(true)\n setError(null)\n void Promise.resolve()\n .then(() => save({ givenName: trimmedGiven, familyName: family.trim() }))\n .then(() => setIsEditing(false))\n .catch((e: unknown) => setError(e))\n .finally(() => setIsSaving(false))\n }, [given, family, save])\n\n return {\n isEditing,\n givenName: given,\n familyName: family,\n onGivenNameChange: setGiven,\n onFamilyNameChange: setFamily,\n onStartEdit,\n onSave,\n onCancel: () => setIsEditing(false),\n isSaving,\n error,\n }\n}\n\n/** Largest picture file accepted before cropping. */\nexport const MAX_AVATAR_FILE_BYTES = 5 * 1024 * 1024\n\nexport type AvatarFileProblem = 'not-image' | 'too-large' | 'unreadable'\n\nexport interface UseAvatarCropOptions {\n /** Persist the cropped picture (a data URL). */\n upload: (dataUrl: string) => Promise<unknown> | unknown\n /** Report a rejected file or a failed read; default is silent (the picker just does not open). */\n onProblem?: (problem: AvatarFileProblem) => void\n maxBytes?: number\n}\n\nexport interface AvatarCrop {\n /** Pass to `AvatarPicker.onFileChosen`. */\n onFileChosen: (file: File) => void\n /** The chosen image awaiting a crop (a data URL), else `null`. */\n pendingImage: string | null\n /** Pass to the crop dialog's `onComplete`. */\n onCropComplete: (result: { dataUrl: string }) => void\n onCropCancel: () => void\n isUploading: boolean\n}\n\n/**\n * The choose, validate, crop, upload sequence behind `AvatarPicker`: the picker hands over a file,\n * this checks it (image, size) and reads it for the crop dialog, then uploads the cropped data URL.\n */\nexport function useAvatarCrop({\n upload,\n onProblem,\n maxBytes = MAX_AVATAR_FILE_BYTES,\n}: UseAvatarCropOptions): AvatarCrop {\n const [pendingImage, setPendingImage] = useState<string | null>(null)\n const [isUploading, setIsUploading] = useState(false)\n\n const onFileChosen = useCallback(\n (file: File) => {\n if (!file.type.startsWith('image/')) return onProblem?.('not-image')\n if (file.size > maxBytes) return onProblem?.('too-large')\n const reader = new FileReader()\n reader.onload = () => setPendingImage(reader.result as string)\n reader.onerror = () => onProblem?.('unreadable')\n reader.readAsDataURL(file)\n },\n [maxBytes, onProblem]\n )\n\n const onCropComplete = useCallback(\n (result: { dataUrl: string }) => {\n setPendingImage(null)\n setIsUploading(true)\n void Promise.resolve()\n .then(() => upload(result.dataUrl))\n .catch(() => {\n // The host's `upload` reports its own failure; the picker just stops spinning.\n })\n .finally(() => setIsUploading(false))\n },\n [upload]\n )\n\n return {\n onFileChosen,\n pendingImage,\n onCropComplete,\n onCropCancel: () => setPendingImage(null),\n isUploading,\n }\n}\n","/**\n * Email change: ask for a code at the new address, confirm it. The SDK-bound mutations and the\n * `ProfileCard` flow controller (cooldown on re-sending the code) are separate, as in `profile.ts`.\n */\n\nimport { useCallback, useEffect, useState } from 'react'\nimport { useMutation, useQueryClient } from '@tanstack/react-query'\nimport { useArbi } from '../useArbi'\nimport { arbiQueryKeys } from '../hooks'\nimport { toProfileView } from './profile'\n\n// ── SDK-bound hooks ─────────────────────────────────────────────────────────\n\n/** Send the 3-word verification code to the new address (not for SSO accounts). */\nexport function useRequestEmailChange() {\n const arbi = useArbi()\n return useMutation({\n mutationFn: (newEmail: string) => arbi.account.requestEmailChange(newEmail),\n })\n}\n\n/** Confirm the new address with the emailed code; the profile query shows the new email. */\nexport function useConfirmEmailChange() {\n const arbi = useArbi()\n const qc = useQueryClient()\n return useMutation({\n mutationFn: ({ newEmail, code }: { newEmail: string; code: string }) =>\n arbi.account.confirmEmailChange(newEmail, code),\n onSuccess: () => {\n const profile = arbi.user.profile()\n qc.setQueryData(arbiQueryKeys.profile(), profile ? toProfileView(profile) : null)\n },\n })\n}\n\n// ── Controller (no SDK) ─────────────────────────────────────────────────────\n\nexport interface UseEmailChangeOptions {\n /** Send a code to `newEmail`. */\n requestCode: (newEmail: string) => Promise<unknown> | unknown\n /** Confirm `newEmail` with `code`. Resolve to finish the flow. */\n confirm: (args: { newEmail: string; code: string }) => Promise<unknown> | unknown\n /** Seconds before another code may be requested. Default 30. */\n cooldownSeconds?: number\n}\n\nexport interface EmailChange {\n /** The flow is open: `ProfileCard` hides the plain email row. */\n isOpen: boolean\n onStart: () => void\n step: 'enter' | 'verify'\n newEmail: string\n onNewEmailChange: (value: string) => void\n onSendCode: () => void\n isSending: boolean\n code: string\n onCodeChange: (value: string) => void\n onConfirm: () => void\n isConfirming: boolean\n cooldownSeconds: number\n onCancel: () => void\n /** The last failed send or confirm. */\n error: unknown\n}\n\n/** The two-step email-change flow of `ProfileCard`: enter address, verify code. */\nexport function useEmailChange({\n requestCode,\n confirm,\n cooldownSeconds: cooldownLength = 30,\n}: UseEmailChangeOptions): EmailChange {\n const [isOpen, setIsOpen] = useState(false)\n const [step, setStep] = useState<'enter' | 'verify'>('enter')\n const [newEmail, setNewEmail] = useState('')\n const [code, setCode] = useState('')\n const [cooldown, setCooldown] = useState(0)\n const [isSending, setIsSending] = useState(false)\n const [isConfirming, setIsConfirming] = useState(false)\n const [error, setError] = useState<unknown>(null)\n\n useEffect(() => {\n if (cooldown <= 0) return\n const timer = setTimeout(() => setCooldown((c) => c - 1), 1000)\n return () => clearTimeout(timer)\n }, [cooldown])\n\n const reset = useCallback(() => {\n setIsOpen(false)\n setStep('enter')\n setNewEmail('')\n setCode('')\n setError(null)\n }, [])\n\n const onSendCode = useCallback(() => {\n const email = newEmail.trim()\n if (!email) return\n setIsSending(true)\n setError(null)\n void Promise.resolve()\n .then(() => requestCode(email))\n .then(() => {\n setStep('verify')\n setCooldown(cooldownLength)\n })\n .catch((e: unknown) => setError(e))\n .finally(() => setIsSending(false))\n }, [newEmail, requestCode, cooldownLength])\n\n const onConfirm = useCallback(() => {\n const email = newEmail.trim()\n const entered = code.trim()\n if (!email || !entered) return\n setIsConfirming(true)\n setError(null)\n void Promise.resolve()\n .then(() => confirm({ newEmail: email, code: entered }))\n .then(reset)\n .catch((e: unknown) => setError(e))\n .finally(() => setIsConfirming(false))\n }, [newEmail, code, confirm, reset])\n\n return {\n isOpen,\n onStart: () => setIsOpen(true),\n step,\n newEmail,\n onNewEmailChange: setNewEmail,\n onSendCode,\n isSending,\n code,\n onCodeChange: setCode,\n onConfirm,\n isConfirming,\n cooldownSeconds: cooldown,\n onCancel: reset,\n error,\n }\n}\n","/**\n * Password change: re-key the account under a new master password.\n *\n * `usePasswordChange` is the SDK-bound mutation (re-wraps every workspace key and re-encrypts\n * direct messages, see `Arbi.account.changePassword`). `usePasswordChangeForm` is the controller\n * behind `PasswordChangeDialog`: fields, validation, error wording, the success state that hands\n * over the new recovery key. It takes the submit as a function, so an app without an\n * `ArbiProvider` binds the same dialog.\n */\n\nimport { useCallback, useMemo, useState } from 'react'\nimport { useMutation } from '@tanstack/react-query'\nimport { passwordChangeErrorMessage } from '@arbidocs/client'\nimport { useArbi } from '../useArbi'\n\n// ── SDK-bound hook ──────────────────────────────────────────────────────────\n\n/** What a finished password change reports. */\nexport interface PasswordChangeResult {\n /** The new Ed25519 signing key: its recovery file is what the user should save now. */\n newSigningPrivateKey: Uint8Array\n workspacesUpdated: number\n messagesReEncrypted: number\n}\n\nexport interface PasswordChangeVars {\n newPassword: string\n /** Omit in recovery mode (after signing in with a recovery key). */\n currentPassword?: string\n}\n\n/** Change (or, in recovery mode, set) the master password. Needs an `ArbiProvider`. */\nexport function usePasswordChange() {\n const arbi = useArbi()\n return useMutation({\n mutationFn: (vars: PasswordChangeVars): Promise<PasswordChangeResult> =>\n arbi.account.changePassword(vars),\n })\n}\n\n// ── Controller (no SDK) ─────────────────────────────────────────────────────\n\nexport interface PasswordChangeFormMessages {\n required: string\n mismatch: string\n sameAsCurrent: string\n wrongCurrent: string\n wrongRecoveryKey: string\n}\n\nexport const DEFAULT_PASSWORD_CHANGE_FORM_MESSAGES: PasswordChangeFormMessages = {\n required: 'All fields are required',\n mismatch: 'New passwords do not match',\n sameAsCurrent: 'New password must be different from current password',\n wrongCurrent: 'Current password is incorrect.',\n wrongRecoveryKey: 'Recovery key did not match this account. Try a different recovery file.',\n}\n\nexport interface UsePasswordChangeFormOptions<R> {\n /** After recovery with a key: no current password is asked for. */\n recoveryMode?: boolean\n /** The host's password policy: the first unmet requirement, or `null` when the password is fine. */\n getUnmetRequirement: (password: string) => string | null\n /** Do the change. Resolve with whatever the success state needs (the new signing key). */\n submit: (vars: PasswordChangeVars) => Promise<R>\n /** The dialog should close (cancel, or done). */\n onClose: () => void\n /** Recovery finished: continue into the app. Recovery closes itself, with no success screen. */\n onRecoveryComplete?: () => void\n messages?: Partial<PasswordChangeFormMessages>\n}\n\nexport interface PasswordChangeForm<R> {\n currentPassword: string\n onCurrentPasswordChange: (value: string) => void\n newPassword: string\n onNewPasswordChange: (value: string) => void\n confirmPassword: string\n onConfirmPasswordChange: (value: string) => void\n error: string | null\n isProcessing: boolean\n isSubmitDisabled: boolean\n onSubmit: () => void\n /** The outcome once the change went through (normal mode); render the recovery key from it. */\n result: R | null\n /** Cancel and clear the form. */\n onCancel: () => void\n /** Leave the success screen. */\n onDone: () => void\n}\n\n/** The state machine of `PasswordChangeDialog`; spread it into the dialog's props. */\nexport function usePasswordChangeForm<R>({\n recoveryMode = false,\n getUnmetRequirement,\n submit,\n onClose,\n onRecoveryComplete,\n messages,\n}: UsePasswordChangeFormOptions<R>): PasswordChangeForm<R> {\n const m = useMemo(() => ({ ...DEFAULT_PASSWORD_CHANGE_FORM_MESSAGES, ...messages }), [messages])\n const [currentPassword, setCurrentPassword] = useState('')\n const [newPassword, setNewPassword] = useState('')\n const [confirmPassword, setConfirmPassword] = useState('')\n const [error, setError] = useState<string | null>(null)\n const [isProcessing, setIsProcessing] = useState(false)\n const [result, setResult] = useState<R | null>(null)\n\n const clear = useCallback(() => {\n setCurrentPassword('')\n setNewPassword('')\n setConfirmPassword('')\n }, [])\n\n const isSubmitDisabled =\n isProcessing ||\n (!recoveryMode && !currentPassword) ||\n !newPassword ||\n !confirmPassword ||\n getUnmetRequirement(newPassword) !== null ||\n newPassword !== confirmPassword\n\n const onSubmit = useCallback(() => {\n setError(null)\n if ((!recoveryMode && !currentPassword) || !newPassword || !confirmPassword) {\n return setError(m.required)\n }\n if (newPassword !== confirmPassword) return setError(m.mismatch)\n const unmet = getUnmetRequirement(newPassword)\n if (unmet !== null) return setError(unmet)\n if (!recoveryMode && currentPassword === newPassword) return setError(m.sameAsCurrent)\n\n setIsProcessing(true)\n void submit({ newPassword, currentPassword: recoveryMode ? undefined : currentPassword })\n .then((outcome) => {\n clear()\n if (recoveryMode) {\n onClose()\n onRecoveryComplete?.()\n } else {\n setResult(outcome)\n }\n })\n .catch((e: unknown) => {\n const message = passwordChangeErrorMessage(e)\n const wrongCurrent = /invalid signature|current password|401/i.test(message)\n setError(wrongCurrent ? (recoveryMode ? m.wrongRecoveryKey : m.wrongCurrent) : message)\n })\n .finally(() => setIsProcessing(false))\n }, [\n recoveryMode,\n currentPassword,\n newPassword,\n confirmPassword,\n getUnmetRequirement,\n submit,\n clear,\n onClose,\n onRecoveryComplete,\n m,\n ])\n\n return {\n currentPassword,\n onCurrentPasswordChange: setCurrentPassword,\n newPassword,\n onNewPasswordChange: setNewPassword,\n confirmPassword,\n onConfirmPasswordChange: setConfirmPassword,\n error,\n isProcessing,\n isSubmitDisabled,\n onSubmit,\n result,\n onCancel: () => {\n clear()\n setError(null)\n setResult(null)\n onClose()\n },\n onDone: () => {\n setResult(null)\n onClose()\n },\n }\n}\n","/**\n * Notification preferences: which email categories the user wants (the `email_notifications`\n * record of the user settings). All default on. The master switch on `NotificationCategoryList`\n * is \"on while at least one category is on\" and writes every category at once.\n */\n\nimport { useCallback, useMemo } from 'react'\nimport { useMutation, useQuery, useQueryClient } from '@tanstack/react-query'\nimport { useArbi } from '../useArbi'\nimport { arbiQueryKeys } from '../hooks'\n\n/** Category key to on/off, e.g. `{ messages: true, product_updates: false }`. */\nexport type EmailPreferences = Record<string, boolean>\n\n// ── Pure core ───────────────────────────────────────────────────────────────\n\nexport interface NotificationPreferencesModel {\n /** Master switch: on while at least one category is on. */\n masterChecked: boolean\n /** Each category's state (`true` when the record says nothing: the default). */\n checked: Record<string, boolean>\n /** The PATCH body for the master switch: every category set to `value`. */\n masterPatch: (value: boolean) => EmailPreferences\n /** The PATCH body for one category. */\n categoryPatch: (key: string, value: boolean) => EmailPreferences\n}\n\n/** Derive the switch states from the stored record and the list of category keys. */\nexport function toNotificationPreferences(\n stored: EmailPreferences | null | undefined,\n keys: readonly string[]\n): NotificationPreferencesModel {\n const checked = Object.fromEntries(keys.map((key) => [key, stored?.[key] ?? true]))\n return {\n masterChecked: keys.some((key) => checked[key]),\n checked,\n masterPatch: (value) => Object.fromEntries(keys.map((key) => [key, value])),\n categoryPatch: (key, value) => ({ [key]: value }),\n }\n}\n\n// ── SDK-bound hooks ─────────────────────────────────────────────────────────\n\n/** The user's settings record (flags, pins, notification preferences). */\nexport function useUserSettings(options?: { enabled?: boolean }) {\n const arbi = useArbi()\n return useQuery({\n queryKey: arbiQueryKeys.userSettings(),\n queryFn: () => arbi.settings.get(),\n enabled: (options?.enabled ?? true) && arbi.isLoggedIn,\n })\n}\n\n/**\n * The email notification preferences and the save. `save` writes the given keys (a patch,\n * merged by the server) and updates the cached settings straight away, so the switches do not\n * wait for the round trip; a failed write rolls back.\n */\nexport function useNotificationPreferences(\n keys: readonly string[],\n options?: { enabled?: boolean }\n) {\n const arbi = useArbi()\n const qc = useQueryClient()\n const settings = useUserSettings(options)\n const stored = settings.data?.email_notifications as EmailPreferences | undefined\n\n const save = useMutation({\n mutationFn: (patch: EmailPreferences) =>\n arbi.settings.update({ email_notifications: patch } as never),\n onMutate: async (patch) => {\n await qc.cancelQueries({ queryKey: arbiQueryKeys.userSettings() })\n const previous = qc.getQueryData(arbiQueryKeys.userSettings())\n qc.setQueryData(arbiQueryKeys.userSettings(), (old: typeof settings.data) =>\n old ? { ...old, email_notifications: { ...old.email_notifications, ...patch } } : old\n )\n return { previous }\n },\n onError: (_err, _patch, context) => {\n qc.setQueryData(arbiQueryKeys.userSettings(), context?.previous)\n },\n onSettled: () => qc.invalidateQueries({ queryKey: arbiQueryKeys.userSettings() }),\n })\n\n const model = useMemo(() => toNotificationPreferences(stored, keys), [stored, keys])\n const setAll = useCallback(\n (value: boolean) => save.mutate(model.masterPatch(value)),\n [save, model]\n )\n const setCategory = useCallback(\n (key: string, value: boolean) => save.mutate(model.categoryPatch(key, value)),\n [save, model]\n )\n\n return {\n ...model,\n isLoading: settings.isLoading,\n isSaving: save.isPending,\n /** The master switch handler: every category on or off. */\n setAll,\n /** One category's handler. */\n setCategory,\n }\n}\n","/**\n * Session management beyond `useSessions` (the list): end one session, sign out everywhere, and\n * tell which listed session is this device's.\n */\n\nimport { useMutation, useQueryClient } from '@tanstack/react-query'\nimport { useArbi } from '../useArbi'\nimport { arbiQueryKeys } from '../hooks'\n\n/** End one of the user's sessions at once (not this device's: that is a logout). */\nexport function useTerminateSession() {\n const arbi = useArbi()\n const qc = useQueryClient()\n return useMutation({\n mutationFn: (sessionId: string) => arbi.sessions.terminate(sessionId),\n onSuccess: () => qc.invalidateQueries({ queryKey: arbiQueryKeys.sessions() }),\n })\n}\n\n/** Sign out of every device, this one included. The instance is logged out afterwards. */\nexport function useLogoutAllSessions() {\n const arbi = useArbi()\n const qc = useQueryClient()\n return useMutation({\n mutationFn: () => arbi.sessions.logoutAll(),\n onSuccess: () => qc.clear(),\n })\n}\n\n/** The id this device's session carries in the `useSessions` list, or `null`. */\nexport function useCurrentSessionId(): string | null {\n return useArbi().sessions.currentId()\n}\n","/**\n * Delete account: the two-step flow behind `DeleteAccountDialog` and the backend's refusals.\n * The backend closes the account (soft delete) unless the user still has an active subscription\n * or is the sole admin of a workspace with other members; the refusal names which.\n */\n\nimport { useCallback, useState } from 'react'\nimport { useMutation } from '@tanstack/react-query'\nimport { useArbi } from '../useArbi'\n\n/** Why an account cannot be closed yet. */\nexport type DeleteAccountBlocker =\n { type: 'active_subscription' } | { type: 'workspace_members'; workspaces: string[] }\n\n/** Read the blockers out of a failed deletion; an empty list means it failed for another reason. */\nexport function parseDeleteAccountBlockers(error: unknown): DeleteAccountBlocker[] {\n const body = (error as { apiError?: unknown } | null)?.apiError ?? error\n const detail = (body as { detail?: unknown } | null)?.detail\n if (detail === 'active_subscription') return [{ type: 'active_subscription' }]\n if (detail && typeof detail === 'object') {\n const d = detail as { reason?: unknown; workspaces?: unknown }\n if (d.reason === 'workspace_members' && Array.isArray(d.workspaces)) {\n return [{ type: 'workspace_members', workspaces: d.workspaces.map(String) }]\n }\n }\n return []\n}\n\n/** Close the account and sign out. Needs an `ArbiProvider`. */\nexport function useDeleteAccount() {\n const arbi = useArbi()\n return useMutation({ mutationFn: () => arbi.account.requestDeletion() })\n}\n\nexport interface UseDeleteAccountFlowOptions {\n userEmail: string\n /** Close the account. Reject with the backend's error to surface blockers. */\n remove: () => Promise<unknown> | unknown\n /** The dialog should close. */\n onClose: () => void\n /** The account is closed (sign the user out of the app). */\n onDeleted: () => void\n /** A failure that is not a blocker. */\n onError?: (error: unknown) => void\n}\n\nexport interface DeleteAccountFlow {\n step: 'warning' | 'confirm'\n blockers: DeleteAccountBlocker[]\n confirmEmail: string\n onConfirmEmailChange: (value: string) => void\n onContinue: () => void\n onBack: () => void\n isDeleting: boolean\n onSubmit: () => void\n onClose: () => void\n}\n\n/** Step, typed-email confirmation and blockers of `DeleteAccountDialog`. */\nexport function useDeleteAccountFlow({\n userEmail,\n remove,\n onClose,\n onDeleted,\n onError,\n}: UseDeleteAccountFlowOptions): DeleteAccountFlow {\n const [step, setStep] = useState<'warning' | 'confirm'>('warning')\n const [confirmEmail, setConfirmEmail] = useState('')\n const [blockers, setBlockers] = useState<DeleteAccountBlocker[]>([])\n const [isDeleting, setIsDeleting] = useState(false)\n\n const close = useCallback(() => {\n setStep('warning')\n setConfirmEmail('')\n setBlockers([])\n onClose()\n }, [onClose])\n\n const onSubmit = useCallback(() => {\n if (confirmEmail.toLowerCase() !== userEmail.toLowerCase()) return\n setIsDeleting(true)\n void Promise.resolve()\n .then(remove)\n .then(() => {\n close()\n onDeleted()\n })\n .catch((error: unknown) => {\n const found = parseDeleteAccountBlockers(error)\n if (found.length > 0) {\n setBlockers(found)\n setStep('warning')\n } else {\n onError?.(error)\n }\n })\n .finally(() => setIsDeleting(false))\n }, [confirmEmail, userEmail, remove, close, onDeleted, onError])\n\n return {\n step,\n blockers,\n confirmEmail,\n onConfirmEmailChange: setConfirmEmail,\n onContinue: () => setStep('confirm'),\n onBack: () => setStep('warning'),\n isDeleting,\n onSubmit,\n onClose: close,\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 /** Bind this turn to the open native Word document. */\n activeArtifactExtId?: string\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 activeArtifactExtId: opts?.activeArtifactExtId,\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' | 'react' | '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 /** Display names keyed by doc_ext_id. A chunk's `doc_title` is the raw upload name, which can\n * differ from the name the workspace shows; when a name is given here it is used instead. */\n docTitles?: ReadonlyMap<string, string>\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 docTitles,\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 const displayTitle = chunk.metadata.doc_ext_id\n ? docTitles?.get(chunk.metadata.doc_ext_id)\n : undefined\n map.set(\n chunk.metadata.chunk_ext_id,\n displayTitle\n ? { ...chunk, metadata: { ...chunk.metadata, doc_title: displayTitle } }\n : chunk\n )\n }\n })\n }\n })\n }\n return map\n }, [citationData, docTitles])\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 while it is\n // open, and again whenever the composer changes size: opening a citation also opens the document\n // viewer, which narrows the chat column after the first measurement.\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 const measure = () => {\n const rect = edge.getBoundingClientRect()\n setDock({ left: rect.left, top: rect.top, width: rect.width })\n }\n measure()\n const observer = new ResizeObserver(measure)\n observer.observe(edge)\n window.addEventListener('resize', measure)\n return () => {\n observer.disconnect()\n window.removeEventListener('resize', measure)\n }\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-sm text-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 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 {/* Readable floor: never below the text-xs token, bold, so the number is easy to spot. */}\n <sup className=\"ml-px align-super text-[max(0.8em,var(--text-xs))] font-bold leading-none tabular-nums text-ai-ink\">\n {citationNum}\n </sup>\n </MarkMenu>\n)\n\nexport const CitationRenderer = React.memo(CitationRendererComponent)\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 AtSign,\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 'agent_input_requested':\n return { Icon: MessageCircleMore, iconClassName: 'text-primary', label: 'Input needed' }\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 'docx_mention':\n case 'mention':\n return { Icon: AtSign, iconClassName: 'text-primary', label: 'Mention' }\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","import { useMutation, useQuery, useQueryClient } from '@tanstack/react-query'\nimport { useArbi } from '../useArbi'\nimport { useArbiWebSocket } from '../websocket/hooks'\n\nconst workTypes = [\n 'mention',\n 'workspace_access_request',\n 'conversation_ready_for_review',\n 'conversation_approval_request',\n 'conversation_done',\n 'workflow_failed',\n] as const\n\n/** Persisted work notices, isolated by account and API, with live refresh and read receipts. */\nexport function useWorkNotifications(options: {\n apiUrl: string\n userId?: string\n enabled: boolean\n}) {\n const arbi = useArbi()\n const queries = useQueryClient()\n const queryKey = ['work-notifications', options.apiUrl, options.userId]\n const query = useQuery({\n queryKey,\n queryFn: async () =>\n (await Promise.all(workTypes.map((type) => arbi.notifications.list(type)))).flat(),\n enabled: options.enabled && Boolean(options.userId),\n refetchInterval: 30_000,\n })\n useArbiWebSocket((message) => {\n if (workTypes.some((type) => type === message.type))\n void queries.invalidateQueries({ queryKey })\n })\n const receipt = useMutation({\n mutationFn: (ids: string[]) => arbi.notifications.markRead(ids),\n onSuccess: () => queries.invalidateQueries({ queryKey }),\n })\n return { ...query, markRead: receipt.mutateAsync }\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 { arbiQueryKeys } from '../hooks'\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\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: arbiQueryKeys.contacts(),\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 * Pinned above the rows, below the heading: a call to action such as `DmInviteChip` from\n * `@arbidocs/blocks/collaboration`, or a start-by-email form. Shown even when the list is empty.\n */\n lead?: 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 lead,\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 {lead}\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 * Start a conversation with someone by email, for a person who is not yet in the rail: an address\n * and a first message. The send resolves the recipient's key internally (`sendMessageTo`).\n */\n\nimport { useId, useState } from 'react'\nimport { Loader2, Send } from 'lucide-react'\nimport { Button } from '../ui/button'\nimport { Input } from '../ui/input'\nimport { Label } from '../ui/label'\nimport { Textarea } from '../ui/textarea'\nimport type { DmClassNames } from './types'\nimport { cn } from '../lib/utils'\n\nexport interface StartByEmailLabels {\n email: string\n emailPlaceholder: string\n message: string\n messagePlaceholder: string\n send: string\n sending: string\n invalidEmail: string\n}\n\nexport const DEFAULT_START_BY_EMAIL_LABELS: StartByEmailLabels = {\n email: 'Email address',\n emailPlaceholder: 'name@example.com',\n message: 'Message',\n messagePlaceholder: 'Write the first message…',\n send: 'Send',\n sending: 'Sending…',\n invalidEmail: 'Enter a valid email address.',\n}\n\nconst EMAIL = /^[^\\s@]+@[^\\s@]+\\.[^\\s@]+$/\n\nexport interface StartByEmailProps {\n /** Send the first message to `email`. Reject to keep the form and show the error. */\n onStart: (email: string, text: string) => Promise<unknown>\n /** Called after a successful send, with the value `onStart` resolved to. */\n onStarted?: (result: unknown) => void\n classNames?: Pick<DmClassNames, 'sendButton'>\n labels?: Partial<StartByEmailLabels>\n className?: string\n}\n\nexport function StartByEmail({\n onStart,\n onStarted,\n classNames,\n labels,\n className,\n}: StartByEmailProps) {\n const l = { ...DEFAULT_START_BY_EMAIL_LABELS, ...labels }\n const uid = useId()\n const [email, setEmail] = useState('')\n const [text, setText] = useState('')\n const [busy, setBusy] = useState(false)\n const [error, setError] = useState<string | null>(null)\n\n const address = email.trim().toLowerCase()\n const valid = EMAIL.test(address)\n\n const submit = async () => {\n if (!valid || !text.trim() || busy) return\n setBusy(true)\n setError(null)\n try {\n const result = await onStart(address, text.trim())\n setEmail('')\n setText('')\n onStarted?.(result)\n } catch (e) {\n setError(e instanceof Error ? e.message : String(e))\n } finally {\n setBusy(false)\n }\n }\n\n return (\n <form\n data-testid=\"arbi-dm-start\"\n className={cn('flex flex-col gap-2 border-b border-border px-4 py-3', className)}\n onSubmit={(e) => {\n e.preventDefault()\n void submit()\n }}\n >\n <Label htmlFor={`${uid}-email`}>{l.email}</Label>\n <Input\n id={`${uid}-email`}\n type=\"email\"\n value={email}\n onChange={(e) => setEmail(e.target.value)}\n placeholder={l.emailPlaceholder}\n aria-invalid={email !== '' && !valid}\n aria-describedby={email !== '' && !valid ? `${uid}-bad` : undefined}\n disabled={busy}\n data-testid=\"arbi-dm-start-email\"\n />\n {email !== '' && !valid && (\n <p id={`${uid}-bad`} className=\"text-xs text-destructive\">\n {l.invalidEmail}\n </p>\n )}\n <Label htmlFor={`${uid}-text`}>{l.message}</Label>\n <Textarea\n id={`${uid}-text`}\n value={text}\n onChange={(e) => setText(e.target.value)}\n placeholder={l.messagePlaceholder}\n rows={2}\n disabled={busy}\n data-testid=\"arbi-dm-start-message\"\n />\n {error && (\n <p role=\"alert\" className=\"text-xs text-destructive\" data-testid=\"arbi-dm-start-error\">\n {error}\n </p>\n )}\n <Button\n type=\"submit\"\n size=\"sm\"\n disabled={!valid || !text.trim() || busy}\n className={cn('self-end', classNames?.sendButton)}\n data-testid=\"arbi-dm-start-send\"\n >\n {busy ? (\n <Loader2 className=\"size-4 animate-spin\" aria-hidden />\n ) : (\n <Send className=\"size-4\" aria-hidden />\n )}\n {busy ? l.sending : l.send}\n </Button>\n </form>\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'\nimport { StartByEmail, type StartByEmailLabels } from './StartByEmail'\nimport type { DmNotification } from './types'\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 * Replaces the rail's \"Conversations / N colleagues\" heading. `null` for no heading.\n */\n listHeader?: React.ReactNode\n /**\n * Pinned at the top of the rail, e.g. `<DmInviteChip onClick={...} />` from\n * `@arbidocs/blocks/collaboration`. Shown even when there are no conversations.\n */\n listLead?: React.ReactNode\n /**\n * Offer a form at the top of the rail to message an address that is not in the list yet\n * (email plus first message). The new conversation opens once it is sent.\n */\n startByEmail?: boolean | { labels?: Partial<StartByEmailLabels> }\n /**\n * Hide the signed-in user's own row. A contact list that includes the owner would otherwise\n * offer a conversation with yourself.\n */\n hideOwnContact?: boolean\n}\n\nexport function DirectMessages({\n className,\n classNames,\n emptyThread,\n emptyList,\n listHeader,\n listLead,\n startByEmail,\n hideOwnContact,\n}: DirectMessagesProps) {\n const {\n conversations: allConversations,\n myExtId,\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 const conversations = useMemo(\n () =>\n hideOwnContact && myExtId\n ? allConversations.filter((c) => c.peer.external_id !== myExtId)\n : allConversations,\n [allConversations, hideOwnContact, myExtId]\n )\n\n // A first message sent by email opens its thread: the SDK hands back the created notifications.\n const openStarted = (created: unknown) => {\n const peer = Array.isArray(created)\n ? (created[0] as DmNotification | undefined)?.recipient?.external_id\n : undefined\n if (peer) setSelectedPeerId(peer)\n }\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 header={listHeader}\n lead={\n <>\n {listLead}\n {startByEmail && (\n <StartByEmail\n onStart={sendMessageTo}\n onStarted={openStarted}\n classNames={classNames}\n labels={typeof startByEmail === 'object' ? startByEmail.labels : undefined}\n />\n )}\n </>\n }\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"]}