@arbidocs/react 0.5.57 → 0.5.58

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.
Files changed (56) hide show
  1. package/README.md +9 -0
  2. package/dist/artifacts/index.cjs +14 -14
  3. package/dist/artifacts/index.js +4 -4
  4. package/dist/calls/livekit/index.cjs +49 -49
  5. package/dist/calls/livekit/index.js +4 -4
  6. package/dist/{chunk-V64EETLS.cjs → chunk-3QK4VVPG.cjs} +4 -4
  7. package/dist/{chunk-V64EETLS.cjs.map → chunk-3QK4VVPG.cjs.map} +1 -1
  8. package/dist/{chunk-WRMA2JYX.js → chunk-7VENKMLD.js} +5 -5
  9. package/dist/{chunk-WRMA2JYX.js.map → chunk-7VENKMLD.js.map} +1 -1
  10. package/dist/{chunk-2JQ7QNOO.cjs → chunk-A675AQXL.cjs} +154 -69
  11. package/dist/chunk-A675AQXL.cjs.map +1 -0
  12. package/dist/{chunk-KUGZXI7V.js → chunk-CE4RY7VA.js} +3 -3
  13. package/dist/{chunk-KUGZXI7V.js.map → chunk-CE4RY7VA.js.map} +1 -1
  14. package/dist/{chunk-RRWAX52L.cjs → chunk-G76ASVVH.cjs} +6 -2
  15. package/dist/chunk-G76ASVVH.cjs.map +1 -0
  16. package/dist/{chunk-PVUZULHI.js → chunk-J33GSXDT.js} +92 -12
  17. package/dist/chunk-J33GSXDT.js.map +1 -0
  18. package/dist/{chunk-3CVY5SGY.cjs → chunk-JNS3BOPU.cjs} +65 -65
  19. package/dist/{chunk-3CVY5SGY.cjs.map → chunk-JNS3BOPU.cjs.map} +1 -1
  20. package/dist/{chunk-UKEUDTOE.cjs → chunk-LCSUCZVX.cjs} +46 -46
  21. package/dist/{chunk-UKEUDTOE.cjs.map → chunk-LCSUCZVX.cjs.map} +1 -1
  22. package/dist/{chunk-4TKNUJKD.js → chunk-M2SZQBCO.js} +3 -3
  23. package/dist/{chunk-4TKNUJKD.js.map → chunk-M2SZQBCO.js.map} +1 -1
  24. package/dist/{chunk-DFZECLD3.js → chunk-R7YNABZY.js} +2 -2
  25. package/dist/chunk-R7YNABZY.js.map +1 -0
  26. package/dist/{chunk-JFL7BBZ6.js → chunk-S2W3ZOWG.js} +4 -4
  27. package/dist/{chunk-JFL7BBZ6.js.map → chunk-S2W3ZOWG.js.map} +1 -1
  28. package/dist/{chunk-FSPLYO52.cjs → chunk-SOOLC65L.cjs} +3 -3
  29. package/dist/{chunk-FSPLYO52.cjs.map → chunk-SOOLC65L.cjs.map} +1 -1
  30. package/dist/{chunk-PBXJFMES.js → chunk-U64WCQP3.js} +6 -2
  31. package/dist/chunk-U64WCQP3.js.map +1 -0
  32. package/dist/{chunk-YRY6DGRU.cjs → chunk-Y7S2SQH3.cjs} +2 -2
  33. package/dist/chunk-Y7S2SQH3.cjs.map +1 -0
  34. package/dist/document-tools/index.cjs +60 -60
  35. package/dist/document-tools/index.d.cts +2 -2
  36. package/dist/document-tools/index.d.ts +2 -2
  37. package/dist/document-tools/index.js +5 -5
  38. package/dist/index.cjs +2567 -1342
  39. package/dist/index.cjs.map +1 -1
  40. package/dist/index.d.cts +1672 -1085
  41. package/dist/index.d.ts +1672 -1085
  42. package/dist/index.js +1226 -63
  43. package/dist/index.js.map +1 -1
  44. package/dist/{query-keys.d-DM2N5pzN.d.cts → query-keys.d-DEEMzkLz.d.cts} +4 -0
  45. package/dist/{query-keys.d-DM2N5pzN.d.ts → query-keys.d-DEEMzkLz.d.ts} +4 -0
  46. package/dist/ui/index.cjs +164 -164
  47. package/dist/ui/index.js +2 -2
  48. package/dist/viewers/index.cjs +2 -2
  49. package/dist/viewers/index.js +1 -1
  50. package/package.json +3 -3
  51. package/dist/chunk-2JQ7QNOO.cjs.map +0 -1
  52. package/dist/chunk-DFZECLD3.js.map +0 -1
  53. package/dist/chunk-PBXJFMES.js.map +0 -1
  54. package/dist/chunk-PVUZULHI.js.map +0 -1
  55. package/dist/chunk-RRWAX52L.cjs.map +0 -1
  56. package/dist/chunk-YRY6DGRU.cjs.map +0 -1
package/dist/index.js CHANGED
@@ -1,29 +1,29 @@
1
- import { invalidateConversationLists, patchConversation, invalidateConversationDetails, removeConversationFromLists, addConversationToList, findConversation, isConversationShared, isKnownSoloConversation, useUserSettings, patchConversationList, useFeature, useAccountClient, useUpdateUserSettings, myChatId, upsertChat, appendToThread, dropFromThread, deleteChatMessage, removeChat, getOpenChat, cachedChat, applyChatEvent, applyCallEvent } from './chunk-WRMA2JYX.js';
2
- export { AUDIENCE_CHOICES, CALL_CAPTION_TOPIC, CALL_CHAT_MAX_CHARS, CALL_CHAT_TOPIC, CALL_MODERATION_TOPIC, CALL_RECORDING_TOPIC, CALL_TRANSCRIPTION_TOPIC, CALL_WEBINAR_TOPIC, CAPTION_MAX_CHARS, COMPOSITE_AUDIO_BITS_PER_SECOND, COMPOSITE_VIDEO_BITS_PER_SECOND, DEFAULT_JOIN_CHOICES, EMPTY_CALL_SESSION, EXPORT_SAMPLE_RATE, HISTORY_LIMIT, LIVE_SEGMENTER, MAX_AVATAR_FILE_BYTES, MUTED_DEDUPE_MS, PLAYBACK_LOOKAHEAD_MS, READ_ONLY_MEETING_TEXT, RECORDING_CHUNK_MS, RECORDING_SEGMENTER, SEGMENT_FRAME_MS, SEGMENT_ID_PATTERN, SEGMENT_PRE_ROLL_MS, SHORT_PIECE_MERGE_GAP_MS, SPEAKER_AUDIO_BITS_PER_SECOND, TrackUploader, UPLOAD_ATTEMPTS, UPLOAD_BACKOFF_MS, acceptRing, addConversationToList, appendToThread, applyAgentDmStatus, applyCallEvent, applyChatEvent, applyChatMessage, applyChatRead, applyChatUpdated, arbiAccountClient, buildMeetingChatBody, cachedChat, cachedChats, callLink, callMemberKeys, callSession, chatByExtId, chatHasLiveCall, chatLiveCallId, chatTranscriptRef, clearMeetingChatCache, clearTrackUploaders, clockTime, compositeFiles, compositeTrack, conversationKeyForCall, createLocalFeatureStore, createMutedNotifier, createTrackCutter, cutAtPauses, declineRing, decodeCallChatPacket, decodeCaptionPacket, decodeMono16k, decryptPart, encodeCallChatPacket, encodeCaptionPacket, encodeWav, encryptPart, ensureMeetingChat, entitlementRefusal, extensionFor, fetchPart, fileSafe, findConversation, floatToWav, formatTranscriptMarkdown, getOpenChat, hasRecordingTranscript, invalidateCall, invalidateConversationDetails, invalidateConversationLists, isConversationListKey, isConversationShared, isKnownSoloConversation, isRecordingOver, isRecordingSegmentId, isRetryable, isWorkspaceGuestOf, joinFromPreJoin, knownMeetingChat, loadMeetingHistory, markRejoining, meetingChatRefFrom, meetingRefForCall, mergeChatLines, mutedNoticeFromEvent, mutedNoticeFromPacket, mutedNoticeText, myChatId, newPacketId, newSegmentId, newTrackKey, nextSeqAfter, onCallEvent, openCall, openQuestion, openRecording, parseWebinarPacket, partKey, partOffsetMs, partsDue, patchConversation, patchConversationList, persistMeetingMessage, persistTranscriptSegment, playheadAt, postRecordingDocsToThread, postTranscriptToThread, readLocalFeature, recordingFiles, recordingWindowsOf, rejoinAsAudience, removeChat, removeConversationFromLists, resetCallSession, resolveMeetingChat, saveRecordingFilesToThread, schedulePart, sealQuestionText, serverCallsExperimental, setOpenChat, sortTranscriptMessages, sortedParts, speakerTracks, speakerWav, splitIntoFiles, standalone, startChatCall, startContactsCall, startDmCall, startThreadCall, startsMediaFile, storeTranscriptSegment, stripSpeakerPrefix, supersedeLiveTranscript, supersededTranscriptLines, threadHasLiveCall, threadLiveCallId, threadTranscriptLines, threadTranscriptRef, threadTranscriptText, timelineDurationMs, timelineOf, toProfileView, trackUploaderFor, transcribeRecording, transcriptPersistRole, transcriptSegmentOf, unwrapTrackKey, upsertChat, useAccountClient, useAvatarCrop, useCall, useCallInviteLinks, useCallRecording, useCallRecordings, useCallSession, useCallTranscriptionAvailable, useCallsConfig, useCallsEnabled, useCanHostCalls, useEntitlements, useFeature, useFeatureSwitch, useIsEntitled, useMeetingReadOnly, useNameEditor, useOpenCallMeetingChat, useProfile, useRecordingActions, useRecordingWindows, useRevokeCallInviteLink, useSaveToThread, useServerCallsEnabled, useServerCallsExperimental, useUpdateProfile, useUpdateUserSettings, useUserSettings, wrapTrackKey, writeSamples } from './chunk-WRMA2JYX.js';
3
- import { replayableTagMutations, patchDocuments, setCachedDocument, adjustTagCounts, patchCachedDocument, FINISHED_DOCUMENT_STATUSES, refreshDocuments, getCachedDocuments, useArbiWsStore, IN_FLIGHT_DOCUMENT_STATUSES, forgetDocuments, useSimilarDocuments, SIMILARITY_THRESHOLD, useDocuments, finishEntityExtraction } from './chunk-JFL7BBZ6.js';
4
- export { DISMISSED_TASK_TTL_MS, DOCUMENTS_FIRST_PAGE_MEASURE, DOCUMENTS_FIRST_PAGE_SIZE, DOCUMENTS_PAGE_SIZE, FINISHED_DOCUMENT_STATUSES, IN_FLIGHT_DOCUMENT_STATUSES, SIMILARITY_THRESHOLD, adjustTagCounts, dropTagFromCachedDocuments, finishEntityExtraction, forgetDocuments, getCachedDocuments, invalidateTagData, invalidateTagTables, isDocumentsLoading, isRowNewer, isStaleTaskUpdate, patchCachedDocument, patchDocuments, patchWorkspaceTags, refreshDocuments, resolveDocumentStatus, setCachedDocument, settledByRows, startEntityExtraction, stopDocumentsLoading, subscribeDocumentRows, upsertDocuments, useArbiWsStore, useCreateTag, useDeleteTag, useDocument, useDocuments, useDocumentsById, useDocumentsLoading, useEntityExtractionDocIds, useExtractEntities, useInvalidateTagData, useIsCreatingTag, useRefreshDocuments, useSetTagValues, useSimilarDocuments, useTagKindSchema, useUpdateTag, useUpdateTagKindSchema } from './chunk-JFL7BBZ6.js';
5
- import { useArbiSessionState, useConversations, useArbiSession, useWorkspaces, useConfig, useArbiSessionStore, useAvailableModels, useParsedDocument, useTags, selectDraft, useConversationThreads, createArbiSessionStore, useAgents, useAssistantQuery, useActivity, queuedMessages, MIN_QUEUED_MESSAGE_VISIBILITY_MS } from './chunk-PVUZULHI.js';
6
- export { DEFAULT_DOCUMENT_VIEWER_STATE, EMPTY_SESSION_STATE, MAX_THREAD_TABS, MIN_QUEUED_MESSAGE_VISIBILITY_MS, PROJECT_CREATION_DENIED_REASON, agentControl, clearSealedDrafts, closePanelIn, conversationKey, createArbiLayoutStore, createArbiSessionStore, createDebouncedWriter, createSealedDraftStorage, createStoragePersist, defaultLayoutState, dmTabId, flushOnPageExit, isPanelOpen, isUsageMetered, layoutActionsOf, nextViewingDocument, openPanelIn, panelPlace, parseSavedLayout, queuedMessages, restoreLayout, savedLayoutOf, selectDraft, selectIsGenerating, selectViewingDocumentId, threadTabId, useActivity, useAgents, useArbiSession, useArbiSessionState, useArbiSessionStore, useAssistantQuery, useAvailableModels, useBoxRole, useBuiltinCommands, useCanCreateProjects, useConfig, useConfigs, useConversationThreads, useConversations, useCurrentUser, useDeleteAgents, useDocumentVersionList, useFirmPool, useHealth, useMessageDetails, useParsedDocument, useProjectInvoices, useProjectUsage, useProjects, useProjectsUsage, useSessionPageTab, useSessionView, useSignedInSession, useTags, useThumbnails, useTopUpFirmPool, useTransientView, useUserUsageToday, useWorkspaceActivity, useWorkspaces } from './chunk-PVUZULHI.js';
7
- import { fetchDocumentFile, downloadBlob, fetchMarkupPdf, fetchDocumentPdf } from './chunk-4TKNUJKD.js';
8
- import { arbiMutationKeys, arbiQueryKeys, mailQueryKeys, connectorQueryKeys, calendarQueryKeys } from './chunk-PBXJFMES.js';
9
- export { arbiMutationKeys, arbiQueryKeys, calendarQueryKeys, callQueryKeys, connectorQueryKeys, isUnderQueryKey, mailQueryKeys } from './chunk-PBXJFMES.js';
1
+ import { useUserSettings, invalidateConversationLists, patchConversation, invalidateConversationDetails, removeConversationFromLists, addConversationToList, findConversation, isConversationShared, isKnownSoloConversation, patchConversationList, useFeature, useAccountClient, useUpdateUserSettings, myChatId, upsertChat, appendToThread, dropFromThread, deleteChatMessage, removeChat, getOpenChat, cachedChat, applyChatEvent, applyCallEvent } from './chunk-7VENKMLD.js';
2
+ export { AUDIENCE_CHOICES, CALL_CAPTION_TOPIC, CALL_CHAT_MAX_CHARS, CALL_CHAT_TOPIC, CALL_MODERATION_TOPIC, CALL_RECORDING_TOPIC, CALL_TRANSCRIPTION_TOPIC, CALL_WEBINAR_TOPIC, CAPTION_MAX_CHARS, COMPOSITE_AUDIO_BITS_PER_SECOND, COMPOSITE_VIDEO_BITS_PER_SECOND, DEFAULT_JOIN_CHOICES, EMPTY_CALL_SESSION, EXPORT_SAMPLE_RATE, HISTORY_LIMIT, LIVE_SEGMENTER, MAX_AVATAR_FILE_BYTES, MUTED_DEDUPE_MS, PLAYBACK_LOOKAHEAD_MS, READ_ONLY_MEETING_TEXT, RECORDING_CHUNK_MS, RECORDING_SEGMENTER, SEGMENT_FRAME_MS, SEGMENT_ID_PATTERN, SEGMENT_PRE_ROLL_MS, SHORT_PIECE_MERGE_GAP_MS, SPEAKER_AUDIO_BITS_PER_SECOND, TrackUploader, UPLOAD_ATTEMPTS, UPLOAD_BACKOFF_MS, acceptRing, addConversationToList, appendToThread, applyAgentDmStatus, applyCallEvent, applyChatEvent, applyChatMessage, applyChatRead, applyChatUpdated, arbiAccountClient, buildMeetingChatBody, cachedChat, cachedChats, callLink, callMemberKeys, callSession, chatByExtId, chatHasLiveCall, chatLiveCallId, chatTranscriptRef, clearMeetingChatCache, clearTrackUploaders, clockTime, compositeFiles, compositeTrack, conversationKeyForCall, createLocalFeatureStore, createMutedNotifier, createTrackCutter, cutAtPauses, declineRing, decodeCallChatPacket, decodeCaptionPacket, decodeMono16k, decryptPart, encodeCallChatPacket, encodeCaptionPacket, encodeWav, encryptPart, ensureMeetingChat, entitlementRefusal, extensionFor, fetchPart, fileSafe, findConversation, floatToWav, formatTranscriptMarkdown, getOpenChat, hasRecordingTranscript, invalidateCall, invalidateConversationDetails, invalidateConversationLists, isConversationListKey, isConversationShared, isKnownSoloConversation, isRecordingOver, isRecordingSegmentId, isRetryable, isWorkspaceGuestOf, joinFromPreJoin, knownMeetingChat, loadMeetingHistory, markRejoining, meetingChatRefFrom, meetingRefForCall, mergeChatLines, mutedNoticeFromEvent, mutedNoticeFromPacket, mutedNoticeText, myChatId, newPacketId, newSegmentId, newTrackKey, nextSeqAfter, onCallEvent, openCall, openQuestion, openRecording, parseWebinarPacket, partKey, partOffsetMs, partsDue, patchConversation, patchConversationList, persistMeetingMessage, persistTranscriptSegment, playheadAt, postRecordingDocsToThread, postTranscriptToThread, readLocalFeature, recordingFiles, recordingWindowsOf, rejoinAsAudience, removeChat, removeConversationFromLists, resetCallSession, resolveMeetingChat, saveRecordingFilesToThread, schedulePart, sealQuestionText, serverCallsExperimental, setOpenChat, sortTranscriptMessages, sortedParts, speakerTracks, speakerWav, splitIntoFiles, standalone, startChatCall, startContactsCall, startDmCall, startThreadCall, startsMediaFile, storeTranscriptSegment, stripSpeakerPrefix, supersedeLiveTranscript, supersededTranscriptLines, threadHasLiveCall, threadLiveCallId, threadTranscriptLines, threadTranscriptRef, threadTranscriptText, timelineDurationMs, timelineOf, toProfileView, trackUploaderFor, transcribeRecording, transcriptPersistRole, transcriptSegmentOf, unwrapTrackKey, upsertChat, useAccountClient, useAvatarCrop, useCall, useCallInviteLinks, useCallRecording, useCallRecordings, useCallSession, useCallTranscriptionAvailable, useCallsConfig, useCallsEnabled, useCanHostCalls, useEntitlements, useFeature, useFeatureSwitch, useIsEntitled, useMeetingReadOnly, useNameEditor, useOpenCallMeetingChat, useProfile, useRecordingActions, useRecordingWindows, useRevokeCallInviteLink, useSaveToThread, useServerCallsEnabled, useServerCallsExperimental, useUpdateProfile, useUpdateUserSettings, useUserSettings, wrapTrackKey, writeSamples } from './chunk-7VENKMLD.js';
3
+ import { replayableTagMutations, patchDocuments, setCachedDocument, adjustTagCounts, patchCachedDocument, FINISHED_DOCUMENT_STATUSES, refreshDocuments, getCachedDocuments, useArbiWsStore, IN_FLIGHT_DOCUMENT_STATUSES, forgetDocuments, useSimilarDocuments, SIMILARITY_THRESHOLD, useDocuments, finishEntityExtraction } from './chunk-S2W3ZOWG.js';
4
+ export { DISMISSED_TASK_TTL_MS, DOCUMENTS_FIRST_PAGE_MEASURE, DOCUMENTS_FIRST_PAGE_SIZE, DOCUMENTS_PAGE_SIZE, FINISHED_DOCUMENT_STATUSES, IN_FLIGHT_DOCUMENT_STATUSES, SIMILARITY_THRESHOLD, adjustTagCounts, dropTagFromCachedDocuments, finishEntityExtraction, forgetDocuments, getCachedDocuments, invalidateTagData, invalidateTagTables, isDocumentsLoading, isRowNewer, isStaleTaskUpdate, patchCachedDocument, patchDocuments, patchWorkspaceTags, refreshDocuments, resolveDocumentStatus, setCachedDocument, settledByRows, startEntityExtraction, stopDocumentsLoading, subscribeDocumentRows, upsertDocuments, useArbiWsStore, useCreateTag, useDeleteTag, useDocument, useDocuments, useDocumentsById, useDocumentsLoading, useEntityExtractionDocIds, useExtractEntities, useInvalidateTagData, useIsCreatingTag, useRefreshDocuments, useSetTagValues, useSimilarDocuments, useTagKindSchema, useUpdateTag, useUpdateTagKindSchema } from './chunk-S2W3ZOWG.js';
5
+ import { useArbiSessionState, useArbiSession, useWorkspaces, useConversations, useConfig, useArbiSessionStore, useAvailableModels, useParsedDocument, useTags, selectDraft, useConversationThreads, createArbiSessionStore, useProjects, useAgents, useAssistantQuery, useActivity, queuedMessages, MIN_QUEUED_MESSAGE_VISIBILITY_MS } from './chunk-J33GSXDT.js';
6
+ export { DEFAULT_DOCUMENT_VIEWER_STATE, EMPTY_SESSION_STATE, MAX_THREAD_TABS, MIN_QUEUED_MESSAGE_VISIBILITY_MS, PROJECT_CREATION_DENIED_REASON, WORKSPACE_LAST_OPENED_KEY, WORKSPACE_STORAGE_KEY, agentControl, browserWorkspaceStorage, clearSealedDrafts, closePanelIn, conversationKey, createArbiLayoutStore, createArbiSessionStore, createArbiWorkspaceStore, createDebouncedWriter, createSealedDraftStorage, createStoragePersist, defaultLayoutState, dmTabId, flushOnPageExit, isPanelOpen, isUsageMetered, layoutActionsOf, nextViewingDocument, openPanelIn, panelPlace, parseSavedLayout, queuedMessages, readWorkspaceLastOpened, restoreLayout, savedLayoutOf, selectDraft, selectIsGenerating, selectViewingDocumentId, threadTabId, useActivity, useAgents, useArbiSession, useArbiSessionState, useArbiSessionStore, useAssistantQuery, useAvailableModels, useBoxRole, useBuiltinCommands, useCanCreateProjects, useConfig, useConfigs, useConversationThreads, useConversations, useCurrentUser, useDeleteAgents, useDocumentVersionList, useFirmPool, useHealth, useMessageDetails, useParsedDocument, useProjectInvoices, useProjectUsage, useProjects, useProjectsUsage, useSessionPageTab, useSessionView, useSignedInSession, useTags, useThumbnails, useTopUpFirmPool, useTransientView, useUserUsageToday, useWorkspaceActivity, useWorkspaces } from './chunk-J33GSXDT.js';
10
7
  import { ArbiHost, extractMentions, UNBOUND, bindingOfRow, readLegacyThreadDocuments, forgetLegacyThreadDocuments, toMessageMentions, takeDocumentForTurn, hasMessageBody, createSearchSession, clearSearchSession } from './chunk-CMNZI4WQ.js';
11
8
  export { LEGACY_THREAD_DOCUMENTS_KEY, MENTION_HREF_PREFIX, NotificationBell, Toaster, UNBOUND, bindingOfRow, clearSearchSession, createSearchSession, extractMentions, filterMentionCandidates, findMentionQuery, forgetLegacyThreadDocuments, hasMessageBody, insertMention, latestThreadOfDocument, linkMentions, mentionFromHref, openDocumentId, opensInWord, persistSearchSession, readLegacyThreadDocuments, requestSearch, savedDocumentIdFor, sharedSearchSession, takeDocumentForTurn, takePendingSearch, toMessageMentions, useOpenDocumentId, useRegisterOpenDocument, useTurnDocumentId } from './chunk-CMNZI4WQ.js';
12
9
  import { notify } from './chunk-5HDC43MF.js';
13
10
  export { DEFAULT_NOTIFY_TONE, MAX_SESSION_NOTIFICATIONS, configureNotify, notify, persistNotifyHistory, seedNotifications, selectUnread, toast, useNotify } from './chunk-5HDC43MF.js';
14
11
  export { mergeHostConfig } from './chunk-DPYBZDJB.js';
12
+ import { fetchDocumentFile, downloadBlob, fetchMarkupPdf, fetchDocumentPdf } from './chunk-M2SZQBCO.js';
13
+ import { arbiMutationKeys, arbiQueryKeys, mailQueryKeys, connectorQueryKeys, calendarQueryKeys } from './chunk-U64WCQP3.js';
14
+ export { arbiMutationKeys, arbiQueryKeys, calendarQueryKeys, callQueryKeys, connectorQueryKeys, isUnderQueryKey, mailQueryKeys } from './chunk-U64WCQP3.js';
15
15
  export { cleanDraftMarkdown, cleanDraftWithReport, promoteBoldTitle, repairParsedStructure, repairParsedTitle, stripAgentPreamble, unescapeMarkdown, unwrapCitationLinks } from './chunk-NNWMHMEC.js';
16
16
  import './chunk-WUTL62MC.js';
17
- import { returnFocusToMark, MarkMenu, getDocumentTitle, Badge, TagEntity, useAudioRecorder, MicWaveformIndicator, IconToggle, classifyMediaError, formatElapsed, AiMarkdown, Card, Input, FILE_TYPE_COLORS, getEntityIcon, UserEntity, getEntityColorStyles, AgentBadge, Textarea, Slider, getEntityLabel, getDocumentDate, usesOriginalBytesForViewer } from './chunk-KUGZXI7V.js';
18
- export { ARBI_MARK_SRC, AUDIO_MIME_PREFERENCE, AgentBadge, AiMarkdown, ArbiBotHeadIcon, ArbiIcon, AudIcon, BASE_COLORS, Badge, COLUMN_LABEL_FALLBACKS, Card, CardContent, CardDescription, CardFooter, CardHeader, CardTitle, Checkbox, ClaudeIcon, Collapsible, CollapsibleContent, CollapsibleTrigger, Command, CommandDialog, CommandEmpty, CommandGroup, CommandInput, CommandItem, CommandList, CommandSeparator, CommandShortcut, DEFAULT_METADATA_TAGS, DebouncedInput, DocIcon, DocumentCard, DocumentEntity, ENTITY_MAPPINGS, EmlIcon, EntityIcon, EntityPill, FILE_TYPE_COLORS, FireworksIcon, GeminiIcon, GoogleIcon, HoverCard, HoverCardContent, HoverCardTrigger, HtmlIcon, IconToggle, ImgIcon, InlineMicButton, Input, Label, MarkMenu, MicRecordingOverlay, MicWaveformIndicator, NEUTRAL_GRAY, OpenAIIcon, PLACEHOLDER_COLOR, PassageCard, PdfIcon, Popover, PopoverAnchor, PopoverClose, PopoverContent, PopoverTrigger, PresenceLabel, Progress, ProjectEntity, ProviderIcon, RadioGroup, RadioGroupItem, RagDot, RelevanceDot, Select, SelectContent, SelectGroup, SelectItem, SelectLabel, SelectScrollDownButton, SelectScrollUpButton, SelectSeparator, SelectTrigger, SelectValue, Separator, ShieldIcon, Slider, StatusPill, Switch, TAG_TYPE_ICONS, TAG_TYPE_LABELS, Table, TableBody, TableCaption, TableCell, TableFooter, TableHead, TableHeader, TableRow, Tabs, TabsContent, TabsList, TabsTrigger, TagEntity, Textarea, ThreadVisibilityIcon, Toggle, ToggleGroup, ToggleGroupItem, Tooltip, TooltipContent, TooltipProvider, TooltipTrigger, TxtIcon, UserEntity, UserMenu, VIDEO_MIME_PREFERENCE, VISIBILITY_ICONS, VerifiedBadge, VerifiedToggle, VidIcon, VisibilityIcon, VisibilityToggle, XlsIcon, agentAvatarColors, badgeVariants, buildFolderTree, canonicalFolderPath, cardVariants, classifyMediaError, configureEntityRegistry, configureRagLabels, configureStatusRegistry, createChunkedRecorder, entityNoun, extensionFromMime, formatDocDate, formatElapsed, formatFolderLabel, formatFriendlyDate, friendlyFileType, getDocIcon, getDocumentAuthor, getDocumentDate, getDocumentNature, getDocumentSubject, getDocumentTitle, getEntityColor, getEntityColorStyles, getEntityIcon, getEntityLabel, getFileExtension, getFileTypeIcon, getStatusVariant, getTagTypeIcon, getTagTypeLabel, getWorkspaceColor, isAudioFile, isDocumentAddableToConversation, isDownloadOnlyFile, isImageDocument, isImageFile, isMediaFile, isVideoFile, markdownToPlainText, markdownToPlainTextBlocks, pickRecorderMimeType, tagKindNouns, tagKindTitle, toggleVariants, useAudioRecorder, useDictateContext, usesOriginalBytesForViewer } from './chunk-KUGZXI7V.js';
17
+ import { returnFocusToMark, MarkMenu, getDocumentTitle, Badge, TagEntity, useAudioRecorder, MicWaveformIndicator, IconToggle, classifyMediaError, formatElapsed, friendlyFileType, AiMarkdown, Card, Input, FILE_TYPE_COLORS, getEntityIcon, UserEntity, getEntityColorStyles, AgentBadge, Textarea, Slider, getEntityLabel, getDocumentDate, usesOriginalBytesForViewer } from './chunk-CE4RY7VA.js';
18
+ export { ARBI_MARK_SRC, AUDIO_MIME_PREFERENCE, AgentBadge, AiMarkdown, ArbiBotHeadIcon, ArbiIcon, AudIcon, BASE_COLORS, Badge, COLUMN_LABEL_FALLBACKS, Card, CardContent, CardDescription, CardFooter, CardHeader, CardTitle, Checkbox, ClaudeIcon, Collapsible, CollapsibleContent, CollapsibleTrigger, Command, CommandDialog, CommandEmpty, CommandGroup, CommandInput, CommandItem, CommandList, CommandSeparator, CommandShortcut, DEFAULT_METADATA_TAGS, DebouncedInput, DocIcon, DocumentCard, DocumentEntity, ENTITY_MAPPINGS, EmlIcon, EntityIcon, EntityPill, FILE_TYPE_COLORS, FireworksIcon, GeminiIcon, GoogleIcon, HoverCard, HoverCardContent, HoverCardTrigger, HtmlIcon, IconToggle, ImgIcon, InlineMicButton, Input, Label, MarkMenu, MicRecordingOverlay, MicWaveformIndicator, NEUTRAL_GRAY, OpenAIIcon, PLACEHOLDER_COLOR, PassageCard, PdfIcon, Popover, PopoverAnchor, PopoverClose, PopoverContent, PopoverTrigger, PresenceLabel, Progress, ProjectEntity, ProviderIcon, RadioGroup, RadioGroupItem, RagDot, RelevanceDot, Select, SelectContent, SelectGroup, SelectItem, SelectLabel, SelectScrollDownButton, SelectScrollUpButton, SelectSeparator, SelectTrigger, SelectValue, Separator, ShieldIcon, Slider, StatusPill, Switch, TAG_TYPE_ICONS, TAG_TYPE_LABELS, Table, TableBody, TableCaption, TableCell, TableFooter, TableHead, TableHeader, TableRow, Tabs, TabsContent, TabsList, TabsTrigger, TagEntity, Textarea, ThreadVisibilityIcon, Toggle, ToggleGroup, ToggleGroupItem, Tooltip, TooltipContent, TooltipProvider, TooltipTrigger, TxtIcon, UserEntity, UserMenu, VIDEO_MIME_PREFERENCE, VISIBILITY_ICONS, VerifiedBadge, VerifiedToggle, VidIcon, VisibilityIcon, VisibilityToggle, XlsIcon, agentAvatarColors, badgeVariants, buildFolderTree, canonicalFolderPath, cardVariants, classifyMediaError, configureEntityRegistry, configureRagLabels, configureStatusRegistry, createChunkedRecorder, entityNoun, extensionFromMime, formatDocDate, formatElapsed, formatFolderLabel, formatFriendlyDate, friendlyFileType, getDocIcon, getDocumentAuthor, getDocumentDate, getDocumentNature, getDocumentSubject, getDocumentTitle, getEntityColor, getEntityColorStyles, getEntityIcon, getEntityLabel, getFileExtension, getFileTypeIcon, getStatusVariant, getTagTypeIcon, getTagTypeLabel, getWorkspaceColor, isAudioFile, isDocumentAddableToConversation, isDownloadOnlyFile, isImageDocument, isImageFile, isMediaFile, isVideoFile, markdownToPlainText, markdownToPlainTextBlocks, pickRecorderMimeType, tagKindNouns, tagKindTitle, toggleVariants, useAudioRecorder, useDictateContext, usesOriginalBytesForViewer } from './chunk-CE4RY7VA.js';
19
19
  import { getUserDisplayName, isAgent } from './chunk-APZZQZ6P.js';
20
20
  export { Avatar, AvatarFallback, AvatarImage, DEFAULT_SEGMENTER_CONFIG, INITIAL_SEGMENTER_STATE, createUserAvatarIcon, flushSegmenter, getUserAvatarColor, getUserDisplayName, getUserInitials, isAgent, levelFromRms, stepSegmenter } from './chunk-APZZQZ6P.js';
21
21
  import { MarkdownRenderer } from './chunk-C44GO33B.js';
22
22
  export { MarkdownCode, MarkdownLink, MarkdownRenderer, MarkdownStreamingContext, markdownBaseComponents, markdownSanitizeSchema, splitMarkdownBlocks } from './chunk-C44GO33B.js';
23
- import { Button, Dialog, DialogContent, DialogHeader, DialogTitle, DialogFooter } from './chunk-YNNAJJ5Z.js';
24
- export { Button, Dialog, DialogClose, DialogContent, DialogDescription, DialogFooter, DialogHeader, DialogOverlay, DialogPortal, DialogTitle, DialogTrigger, buttonVariants } from './chunk-YNNAJJ5Z.js';
25
23
  import { formatRelativeTime } from './chunk-Y3MTRA7D.js';
26
24
  export { ScrollArea, ScrollBar, configureEntityVocabulary, formatRelativeTime } from './chunk-Y3MTRA7D.js';
25
+ import { Button, Dialog, DialogContent, DialogHeader, DialogTitle, DialogFooter } from './chunk-YNNAJJ5Z.js';
26
+ export { Button, Dialog, DialogClose, DialogContent, DialogDescription, DialogFooter, DialogHeader, DialogOverlay, DialogPortal, DialogTitle, DialogTrigger, buttonVariants } from './chunk-YNNAJJ5Z.js';
27
27
  import { DropdownMenu, DropdownMenuTrigger, DropdownMenuContent, DropdownMenuItem, DropdownMenuSeparator } from './chunk-47CCGUWR.js';
28
28
  export { DropdownMenu, DropdownMenuCheckboxItem, DropdownMenuContent, DropdownMenuGroup, DropdownMenuItem, DropdownMenuLabel, DropdownMenuPortal, DropdownMenuRadioGroup, DropdownMenuRadioItem, DropdownMenuSeparator, DropdownMenuShortcut, DropdownMenuSub, DropdownMenuSubContent, DropdownMenuSubTrigger, DropdownMenuTrigger, PortalContainerProvider, usePortalContainer } from './chunk-47CCGUWR.js';
29
29
  import { normalizeCitationMarkup } from './chunk-QRCMKEE6.js';
@@ -31,11 +31,11 @@ export { closeOpenEmphasis, normalizeCitationMarkup, trimOpenCitation } from './
31
31
  import { cn } from './chunk-SN5YV6FF.js';
32
32
  export { cn } from './chunk-SN5YV6FF.js';
33
33
  import { AudioViewer, ImageViewer, VideoViewer } from './chunk-HDCRPPBW.js';
34
- import { useArbi, useArbiHost } from './chunk-DFZECLD3.js';
35
- export { useArbi, useArbiHost, useDeploymentDomain } from './chunk-DFZECLD3.js';
34
+ import { useArbi, useArbiHost } from './chunk-R7YNABZY.js';
35
+ export { useArbi, useArbiHost, useDeploymentDomain } from './chunk-R7YNABZY.js';
36
36
  export { useHostConfigRecord } from './chunk-CPZ36AQS.js';
37
37
  import React, { memo, useState, createContext, useMemo, useCallback, useEffect, useRef, useLayoutEffect, useSyncExternalStore, useContext, useId } from 'react';
38
- import { useQueryClient, useMutation, useQuery, onlineManager, partialMatchKey, useMutationState, keepPreviousData, useQueries } from '@tanstack/react-query';
38
+ import { useQuery, useQueryClient, useMutation, onlineManager, partialMatchKey, useMutationState, keepPreviousData, useQueries } from '@tanstack/react-query';
39
39
  import { documents, doctags, houseTemplates, STOP_ID_WAIT_MS, resolveCitations, summarizeCitations, createIndexAssigner, reduceOutputItem, findReplyTarget, ArbiApiError, quotaFromStreamError, STOP_REPEAT_WINDOW_MS, getRunToCancel, pickMainThread, extractDocumentIdsFromMessages, extractFactIdsFromMessages, hydrateAgentSteps, getSubagentBranchRecord, getRunToAttach, settings, isConnectorVendorVisible, ACCOUNT_VENDOR, searchChunks, formatFileSize, chats, connectWithReconnect, ArbiWorkspaceSupersededError, identityErrorCode } from '@arbidocs/sdk/browser';
40
40
  export { ACCOUNT_VENDOR, Arbi, ArbiError, DEFAULT_AI_USD_PER_GBP, DRIVE_SYNC_VENDORS, GOOGLE_VENDORS, IMANAGE_VENDORS, MAILBOX_SYNC_VENDORS, MAX_RETRIEVE_DOC_IDS, MICROSOFT_VENDORS, PublicBookingError, SHAREPOINT_VENDORS, bookPublicSlot, cancelPublicBooking, connectErrorMessage, formatGbp, formatGbpPerMillionTokens, getPublicBookingPage, isConnectorVendorVisible, isDriveSyncVendor, isMailboxSyncVendor, isSharePointVendor, usdToGbp } from '@arbidocs/sdk/browser';
41
41
  import { Link, Trash2, CheckCheck, Check, MoreHorizontal, SquarePen, Pencil, Download, X, Mic, Pause, Play, Square, Loader2, RotateCcw, Sparkles, Camera, Circle, AlertTriangle, ShieldCheck, Copy, FileText, GitCompareArrows, Search, CornerDownLeft, Send, Tags, Info, Activity, HardDrive, Gauge, Gift, PartyPopper, UserPlus, UserCheck, Reply, PenLine, AtSign, MessageCircleMore, FileX2, FileCheck2, FolderPlus, SquareArrowOutUpRight, Paperclip, ArrowRight, Image as Image$1, AppWindow } from 'lucide-react';
@@ -51,6 +51,21 @@ import Cropper from 'react-easy-crop';
51
51
 
52
52
  // src/host/index.ts
53
53
  var ArbiHost2 = ArbiHost;
54
+ function useCurrentWorkspace() {
55
+ const workspaceId = useArbiSessionState((s) => s.workspaceId);
56
+ const workspaceStatus = useArbiSessionState((s) => s.workspaceStatus);
57
+ const userId = useArbiSession().user?.external_id ?? null;
58
+ const { data: workspaces } = useWorkspaces();
59
+ const workspace = workspaceId ? workspaces?.find((w) => w.external_id === workspaceId) : void 0;
60
+ const membership = userId ? workspace?.users?.find((member) => member.user.external_id === userId) : void 0;
61
+ const role = membership?.role ?? null;
62
+ return useMemo(
63
+ () => ({ workspaceId, workspaceStatus, workspace, role, isMember: !!membership, userId }),
64
+ [workspaceId, workspaceStatus, workspace, role, membership, userId]
65
+ );
66
+ }
67
+
68
+ // src/workforce.ts
54
69
  function isActivityKey(queryKey, conversationId) {
55
70
  const [scope, resource, id, leaf] = queryKey;
56
71
  if (scope !== "arbi" || resource !== "conversations" || leaf !== "activity") return false;
@@ -112,11 +127,7 @@ function useWorkItems() {
112
127
  return { tasks, isLoading, refetch };
113
128
  }
114
129
  function useWorkspaceRole() {
115
- const workspaceId = useArbiSessionState((s) => s.workspaceId);
116
- const me = useArbiSession().user?.external_id;
117
- const { data: workspaces } = useWorkspaces();
118
- const workspace = workspaces?.find((w) => w.external_id === workspaceId);
119
- return workspace?.users?.find((m) => m.user.external_id === me)?.role ?? null;
130
+ return useCurrentWorkspace().role;
120
131
  }
121
132
  function useCanEditShared() {
122
133
  const role = useWorkspaceRole();
@@ -800,8 +811,8 @@ function getInterjectionText(item) {
800
811
  if (candidate?.type !== "reasoning" || candidate.arbi?.step !== "interjection" && candidate.arbi?.label !== "Your message") {
801
812
  return null;
802
813
  }
803
- const text = Array.isArray(candidate.summary) ? candidate.summary.map((c) => c.text ?? "").join("") : "";
804
- return text || null;
814
+ const text2 = Array.isArray(candidate.summary) ? candidate.summary.map((c) => c.text ?? "").join("") : "";
815
+ return text2 || null;
805
816
  }
806
817
  function threadEndingAtContains(queryClient, conversationId, leafId, messageId) {
807
818
  const data = queryClient.getQueryData(getThreadsQueryKey(conversationId));
@@ -901,8 +912,8 @@ function markNarrationSettled(queryClient, conversationId, messageId) {
901
912
  );
902
913
  }
903
914
  function removeSettledNarration(queryClient, conversationId, messageId, itemContent) {
904
- const text = Array.isArray(itemContent) ? itemContent.map((c) => c.text ?? "").join("") : "";
905
- if (!text.trim()) return;
915
+ const text2 = Array.isArray(itemContent) ? itemContent.map((c) => c.text ?? "").join("") : "";
916
+ if (!text2.trim()) return;
906
917
  flushStreamingTokens(queryClient);
907
918
  queryClient.setQueryData(
908
919
  getThreadsQueryKey(conversationId),
@@ -915,9 +926,9 @@ function removeSettledNarration(queryClient, conversationId, messageId, itemCont
915
926
  history: thread.history.map((msg) => {
916
927
  if (msg.external_id !== messageId) return msg;
917
928
  const body = msg.content ?? "";
918
- const at = body.lastIndexOf(text);
929
+ const at = body.lastIndexOf(text2);
919
930
  if (at === -1) return msg;
920
- const rest = body.slice(0, at) + body.slice(at + text.length);
931
+ const rest = body.slice(0, at) + body.slice(at + text2.length);
921
932
  const content = rest.trim() ? rest : "";
922
933
  const settled = Math.min(msg.settledNarrationLength ?? 0, content.length);
923
934
  return { ...msg, content, settledNarrationLength: settled || void 0 };
@@ -2567,8 +2578,8 @@ function VoiceNoteRecorder({
2567
2578
  if (!transcribe) return;
2568
2579
  let cancelled = false;
2569
2580
  setIsTranscribing(true);
2570
- transcribe(recorder.blob).then((text) => {
2571
- if (!cancelled) setTranscript(text);
2581
+ transcribe(recorder.blob).then((text2) => {
2582
+ if (!cancelled) setTranscript(text2);
2572
2583
  }).catch(() => {
2573
2584
  }).finally(() => {
2574
2585
  if (!cancelled) setIsTranscribing(false);
@@ -5206,8 +5217,8 @@ function useAttachRun(conversationId, responseId) {
5206
5217
  }
5207
5218
  const item = ev.item;
5208
5219
  if (item?.type === "message" && item.arbi?.label === "Answered") {
5209
- const text = Array.isArray(item.content) ? item.content.map((c) => c.text ?? "").join("") : "";
5210
- if (text) setMessageContent(queryClient, conversationId, responseId, text);
5220
+ const text2 = Array.isArray(item.content) ? item.content.map((c) => c.text ?? "").join("") : "";
5221
+ if (text2) setMessageContent(queryClient, conversationId, responseId, text2);
5211
5222
  }
5212
5223
  },
5213
5224
  onAgentControlState: (event) => {
@@ -5446,17 +5457,17 @@ function useConversation(options = {}) {
5446
5457
  [docs, deselected, agentId, stagedFiles]
5447
5458
  );
5448
5459
  const withStagedFiles = useCallback(
5449
- (text) => {
5460
+ (text2) => {
5450
5461
  const staged = stagedFiles.filter((file) => !deselected.has(file.id));
5451
- if (!agentId || staged.length === 0) return text;
5452
- return text + "\n\nSource files staged in your sandbox:\n" + staged.map((file) => `${file.name}: ${file.id}`).join("\n");
5462
+ if (!agentId || staged.length === 0) return text2;
5463
+ return text2 + "\n\nSource files staged in your sandbox:\n" + staged.map((file) => `${file.name}: ${file.id}`).join("\n");
5453
5464
  },
5454
5465
  [agentId, stagedFiles, deselected]
5455
5466
  );
5456
5467
  const { handleSendMessage, handleCreateBranch } = actions;
5457
5468
  const send = useCallback(
5458
- async (text) => {
5459
- const trimmed = text.trim();
5469
+ async (text2) => {
5470
+ const trimmed = text2.trim();
5460
5471
  if (!trimmed || isUpdatingAssistantMode) return;
5461
5472
  setHistoryError(null);
5462
5473
  session.setConversationDocuments(
@@ -5487,7 +5498,7 @@ function useConversation(options = {}) {
5487
5498
  ]
5488
5499
  );
5489
5500
  const branch = useCallback(
5490
- (parentId, text) => handleCreateBranch(parentId, withStagedFiles(text)),
5501
+ (parentId, text2) => handleCreateBranch(parentId, withStagedFiles(text2)),
5491
5502
  [handleCreateBranch, withStagedFiles]
5492
5503
  );
5493
5504
  const switchBranch = useCallback(
@@ -5820,6 +5831,18 @@ function useConversationTurn({
5820
5831
  ...actions
5821
5832
  };
5822
5833
  }
5834
+ function useActiveConfigId() {
5835
+ const chatModel = useArbiSessionState((s) => s.chatModel);
5836
+ const cursor = useArbiSessionState((s) => s.cursor);
5837
+ const { messageHistory } = useConversationData();
5838
+ const { data: userSettings } = useUserSettings();
5839
+ return useMemo(() => {
5840
+ if (chatModel) return chatModel;
5841
+ const parent = cursor ? messageHistory?.find((m) => m.external_id === cursor) : void 0;
5842
+ if (parent?.config_ext_id) return parent.config_ext_id;
5843
+ return userSettings?.last_config ?? void 0;
5844
+ }, [chatModel, cursor, messageHistory, userSettings?.last_config]);
5845
+ }
5823
5846
  var EMPTY_DOCS = [];
5824
5847
  function useConversationDocuments() {
5825
5848
  const currentConversationId = useArbiSessionState((state) => state.conversationId);
@@ -6299,9 +6322,9 @@ var ChatBubble = memo(function ChatBubble2({
6299
6322
  }
6300
6323
  );
6301
6324
  });
6302
- function hashText(text) {
6325
+ function hashText(text2) {
6303
6326
  let h = 5381;
6304
- for (let i = 0; i < text.length; i++) h = h * 33 ^ text.charCodeAt(i);
6327
+ for (let i = 0; i < text2.length; i++) h = h * 33 ^ text2.charCodeAt(i);
6305
6328
  return (h >>> 0).toString(36);
6306
6329
  }
6307
6330
  function createSkillPack({ id, skills, marker }) {
@@ -7191,25 +7214,55 @@ function useOpenSelectedWorkspace() {
7191
7214
  const { clearWorkspace, openSelectedWorkspace } = useSwitchWorkspace();
7192
7215
  const workspaceId = useArbiSessionState((s) => s.workspaceId);
7193
7216
  const status = useArbiSessionState((s) => s.workspaceStatus);
7194
- const { data: workspaces, isLoading: listing } = useWorkspaces();
7195
- const archived = workspaces?.find(
7196
- (w) => w.external_id === workspaceId && w.archive
7197
- );
7217
+ const session = useArbiSessionStore();
7218
+ const queryClient = useQueryClient();
7219
+ const { data: workspaces, isLoading: listing, isFetching } = useWorkspaces();
7220
+ const listed = workspaces;
7221
+ const archived = listed?.find((w) => w.external_id === workspaceId && w.archive);
7222
+ const reads = queryClient.getQueryState(arbiQueryKeys.workspaces())?.dataUpdateCount ?? 0;
7223
+ const opened = useRef({ id: null, reads: 0 });
7224
+ const openId = status === "open" ? workspaceId : null;
7225
+ if (opened.current.id !== openId) opened.current = { id: openId, reads };
7226
+ const gone = !!openId && !!listed && !isFetching && reads > opened.current.reads && !listed.some((w) => w.external_id === openId);
7198
7227
  useEffect(() => {
7199
7228
  if (!archived) return;
7200
7229
  notify.info(archivedWorkspaceMessage(archived.name));
7201
7230
  clearWorkspace();
7202
7231
  }, [archived, clearWorkspace]);
7232
+ useEffect(() => {
7233
+ if (gone) clearWorkspace();
7234
+ }, [gone, clearWorkspace]);
7203
7235
  const opening = useRef(false);
7204
7236
  const signedIn2 = arbi.isLoggedIn;
7205
7237
  useEffect(() => {
7206
- if (!workspaceId || archived || listing || status !== "closed" || !signedIn2 || opening.current)
7238
+ if (!workspaceId || archived || gone || listing || status !== "closed" || !signedIn2 || opening.current)
7207
7239
  return;
7208
7240
  opening.current = true;
7209
- void openSelectedWorkspace().finally(() => {
7241
+ void openSelectedWorkspace().then(async (ok) => {
7242
+ if (ok) return;
7243
+ const fresh = await queryClient.fetchQuery({
7244
+ queryKey: arbiQueryKeys.workspaces(),
7245
+ queryFn: () => arbi.workspaces.list(),
7246
+ staleTime: 0
7247
+ }).catch(() => null);
7248
+ if (fresh && session.getState().workspaceId === workspaceId && !fresh.some((w) => w.external_id === workspaceId))
7249
+ clearWorkspace();
7250
+ }).finally(() => {
7210
7251
  opening.current = false;
7211
7252
  });
7212
- }, [openSelectedWorkspace, workspaceId, archived, listing, status, signedIn2]);
7253
+ }, [
7254
+ arbi,
7255
+ session,
7256
+ clearWorkspace,
7257
+ openSelectedWorkspace,
7258
+ queryClient,
7259
+ workspaceId,
7260
+ archived,
7261
+ gone,
7262
+ listing,
7263
+ status,
7264
+ signedIn2
7265
+ ]);
7213
7266
  }
7214
7267
 
7215
7268
  // src/workspaces/shell-workspaces.ts
@@ -7707,7 +7760,10 @@ function useInvalidate() {
7707
7760
  const queryClient = useQueryClient();
7708
7761
  return {
7709
7762
  list: () => queryClient.invalidateQueries({ queryKey: arbiQueryKeys.databaseList() }),
7710
- rows: () => queryClient.invalidateQueries({ queryKey: arbiQueryKeys.databaseRows() }),
7763
+ rows: () => Promise.all([
7764
+ queryClient.invalidateQueries({ queryKey: arbiQueryKeys.databaseRows() }),
7765
+ queryClient.invalidateQueries({ queryKey: arbiQueryKeys.databaseAggregate() })
7766
+ ]),
7711
7767
  all: () => queryClient.invalidateQueries({ queryKey: arbiQueryKeys.databases() })
7712
7768
  };
7713
7769
  }
@@ -7740,6 +7796,16 @@ function useDatabaseRows(databaseId, q) {
7740
7796
  placeholderData: (previous) => previous
7741
7797
  });
7742
7798
  }
7799
+ function useDatabaseAggregate(databaseId, request, options) {
7800
+ const arbi = useArbi();
7801
+ return useQuery({
7802
+ queryKey: arbiQueryKeys.databaseAggregate(databaseId ?? "", request),
7803
+ queryFn: () => arbi.databases.aggregate(databaseId, request),
7804
+ enabled: (options?.enabled ?? true) && arbi.hasWorkspace && Boolean(databaseId),
7805
+ staleTime: 1e3 * 15,
7806
+ placeholderData: (previous) => previous
7807
+ });
7808
+ }
7743
7809
  function useSearchDatabaseRows() {
7744
7810
  const arbi = useArbi();
7745
7811
  return useCallback(
@@ -7801,6 +7867,7 @@ function useUpdateDatabaseRow() {
7801
7867
  (column) => column.id in (values ?? {}) && column.type === "relation" && column.relation?.database_id === databaseId
7802
7868
  );
7803
7869
  void invalidateRelatedRows(queryClient, databaseId, selfLinked);
7870
+ void queryClient.invalidateQueries({ queryKey: arbiQueryKeys.databaseAggregate() });
7804
7871
  },
7805
7872
  onError: () => {
7806
7873
  void queryClient.invalidateQueries({ queryKey: arbiQueryKeys.databaseRows() });
@@ -7838,6 +7905,1102 @@ function useExportDatabase() {
7838
7905
  [arbi]
7839
7906
  );
7840
7907
  }
7908
+
7909
+ // src/account/table-views.ts
7910
+ function isTableViewOf(view, workspaceId, table) {
7911
+ return view.workspace === workspaceId && (view.table ?? null) === table;
7912
+ }
7913
+ function viewsOfTable(all, workspaceId, table) {
7914
+ if (!workspaceId) return [];
7915
+ const byName = /* @__PURE__ */ new Map();
7916
+ for (const view of all ?? []) {
7917
+ if (isTableViewOf(view, workspaceId, table)) byName.set(view.name, view);
7918
+ }
7919
+ return [...byName.values()];
7920
+ }
7921
+
7922
+ // src/datasets/types.ts
7923
+ var AGGREGATE_FIELDS = {
7924
+ /** The group's label ("Open", "2026-06"). */
7925
+ group: "group",
7926
+ /** The group's key as grouped (a date bucket, an id), for ordering and links. */
7927
+ key: "key",
7928
+ /** The series' label (only with `splitBy`). */
7929
+ series: "series",
7930
+ /** The measured value; `null` when the group has no value to measure. */
7931
+ value: "value"
7932
+ };
7933
+
7934
+ // src/datasets/aggregate.ts
7935
+ var EMPTY_GROUP_LABEL = "(empty)";
7936
+ var MAX_SERIES = 12;
7937
+ var DEFAULT_LIMIT = 50;
7938
+ var pad = (n) => String(n).padStart(2, "0");
7939
+ function asDay(value) {
7940
+ if (typeof value !== "string" || value.length < 10) return null;
7941
+ const day = /* @__PURE__ */ new Date(`${value.slice(0, 10)}T00:00:00Z`);
7942
+ return Number.isNaN(day.getTime()) ? null : day;
7943
+ }
7944
+ function isoWeek(day) {
7945
+ const d = new Date(day);
7946
+ const weekday = d.getUTCDay() || 7;
7947
+ d.setUTCDate(d.getUTCDate() + 4 - weekday);
7948
+ const yearStart = Date.UTC(d.getUTCFullYear(), 0, 1);
7949
+ return [d.getUTCFullYear(), Math.ceil(((d.getTime() - yearStart) / 864e5 + 1) / 7)];
7950
+ }
7951
+ function bucketOf(value, bucket) {
7952
+ const day = asDay(value);
7953
+ if (!day) return null;
7954
+ const y = day.getUTCFullYear();
7955
+ const m = day.getUTCMonth() + 1;
7956
+ switch (bucket) {
7957
+ case "day":
7958
+ return `${y}-${pad(m)}-${pad(day.getUTCDate())}`;
7959
+ case "week": {
7960
+ const [wy, w] = isoWeek(day);
7961
+ return `${wy}-W${pad(w)}`;
7962
+ }
7963
+ case "quarter":
7964
+ return `${y}-Q${Math.floor((m - 1) / 3) + 1}`;
7965
+ case "year":
7966
+ return String(y);
7967
+ default:
7968
+ return `${y}-${pad(m)}`;
7969
+ }
7970
+ }
7971
+ function bucketStart(key, bucket) {
7972
+ const parts = key.match(/^(\d{4})(?:-(W|Q)?(\d{1,2}))?(?:-(\d{2}))?$/);
7973
+ if (!parts) return null;
7974
+ const year = Number(parts[1]);
7975
+ const n = Number(parts[3] ?? 1);
7976
+ switch (bucket) {
7977
+ case "day":
7978
+ return asDay(key);
7979
+ case "week": {
7980
+ const jan4 = new Date(Date.UTC(year, 0, 4));
7981
+ const monday = new Date(jan4);
7982
+ monday.setUTCDate(jan4.getUTCDate() - ((jan4.getUTCDay() || 7) - 1) + (n - 1) * 7);
7983
+ return monday;
7984
+ }
7985
+ case "quarter":
7986
+ return new Date(Date.UTC(year, (n - 1) * 3, 1));
7987
+ case "year":
7988
+ return new Date(Date.UTC(year, 0, 1));
7989
+ default:
7990
+ return new Date(Date.UTC(year, n - 1, 1));
7991
+ }
7992
+ }
7993
+ function nextBucket(day, bucket) {
7994
+ const d = new Date(day);
7995
+ if (bucket === "day") d.setUTCDate(d.getUTCDate() + 1);
7996
+ else if (bucket === "week") d.setUTCDate(d.getUTCDate() + 7);
7997
+ else if (bucket === "month") d.setUTCMonth(d.getUTCMonth() + 1);
7998
+ else if (bucket === "quarter") d.setUTCMonth(d.getUTCMonth() + 3);
7999
+ else d.setUTCFullYear(d.getUTCFullYear() + 1);
8000
+ return d;
8001
+ }
8002
+ function bucketRange(first, last, bucket, max = 500) {
8003
+ const start = bucketStart(first, bucket);
8004
+ const end = bucketStart(last, bucket);
8005
+ if (!start || !end || start > end) return null;
8006
+ const keys = [];
8007
+ for (let d = start; d <= end && keys.length <= max; d = nextBucket(d, bucket)) {
8008
+ keys.push(bucketOf(d.toISOString(), bucket));
8009
+ }
8010
+ return keys.length > max ? null : keys;
8011
+ }
8012
+ var isEmpty = (value) => value === null || value === void 0 || value === "" || Array.isArray(value) && !value.length;
8013
+ function groupKeys(value, field, bucket) {
8014
+ if (isEmpty(value)) return [""];
8015
+ if (Array.isArray(value)) {
8016
+ return [...new Set(value.map((v) => groupKeys(v, field, bucket)[0]))];
8017
+ }
8018
+ if (field.type === "date") return [bucketOf(value, bucket) ?? ""];
8019
+ if (typeof value === "boolean") return [value ? "Yes" : "No"];
8020
+ return [String(value)];
8021
+ }
8022
+ var lower = (v) => String(v).toLowerCase();
8023
+ function compare(value, filter, field) {
8024
+ const empty = isEmpty(value);
8025
+ if (filter.op === "empty") return empty;
8026
+ if (filter.op === "not_empty") return !empty;
8027
+ if (Array.isArray(value)) {
8028
+ const values = value;
8029
+ if (filter.op === "contains")
8030
+ return values.some((v) => lower(v).includes(lower(filter.value ?? "")));
8031
+ if (filter.op === "eq" || filter.op === "neq") {
8032
+ const hit = values.some((v) => lower(v) === lower(filter.value));
8033
+ return filter.op === "eq" ? hit : !hit;
8034
+ }
8035
+ return false;
8036
+ }
8037
+ const same = typeof value === "string" ? lower(value) === lower(filter.value) : value === filter.value;
8038
+ if (filter.op === "eq") return same;
8039
+ if (filter.op === "neq") return !same;
8040
+ if (filter.op === "contains") return !empty && lower(value).includes(lower(filter.value ?? ""));
8041
+ if (empty || filter.value === null || filter.value === void 0) return false;
8042
+ const [a, b] = field.type === "number" ? [Number(value), Number(filter.value)] : [String(value).slice(0, 19), String(filter.value).slice(0, 19)];
8043
+ return { gt: a > b, gte: a >= b, lt: a < b, lte: a <= b }[filter.op];
8044
+ }
8045
+ function recordsOf(dataset, query) {
8046
+ const rows = filterRows(dataset.rows, dataset.fields, query.filters);
8047
+ const order = query.orderBy;
8048
+ const field = order && dataset.fields.find((f) => f.id === order.field);
8049
+ if (order && field) {
8050
+ const dir = order.direction === "desc" ? -1 : 1;
8051
+ const key = (v) => Array.isArray(v) ? v.join(", ") : v;
8052
+ rows.sort((a, b) => {
8053
+ const x = key(a[field.id]);
8054
+ const y = key(b[field.id]);
8055
+ if (isEmpty(x) || isEmpty(y)) return isEmpty(x) === isEmpty(y) ? 0 : isEmpty(x) ? 1 : -1;
8056
+ if (typeof x === "number" && typeof y === "number") return dir * (x - y);
8057
+ return dir * String(x).localeCompare(String(y));
8058
+ });
8059
+ }
8060
+ return {
8061
+ fields: dataset.fields,
8062
+ rows: query.limit ? rows.slice(0, query.limit) : rows,
8063
+ totalRows: rows.length,
8064
+ truncated: !!query.limit && rows.length > query.limit
8065
+ };
8066
+ }
8067
+ function filterRows(rows, fields, filters = []) {
8068
+ if (!filters.length) return [...rows];
8069
+ const byId = new Map(fields.map((f) => [f.id, f]));
8070
+ return rows.filter(
8071
+ (row) => filters.every((filter) => {
8072
+ const field = byId.get(filter.field);
8073
+ return field ? compare(row[filter.field], filter, field) : false;
8074
+ })
8075
+ );
8076
+ }
8077
+ function measure(values, op, countRows) {
8078
+ if (op === "count") return countRows ? values.length : values.filter((v) => !isEmpty(v)).length;
8079
+ const numbers = values.filter((v) => typeof v === "number" && Number.isFinite(v));
8080
+ if (!numbers.length) return null;
8081
+ if (op === "sum") return numbers.reduce((a, b) => a + b, 0);
8082
+ if (op === "avg") return numbers.reduce((a, b) => a + b, 0) / numbers.length;
8083
+ return op === "min" ? Math.min(...numbers) : Math.max(...numbers);
8084
+ }
8085
+ function measureLabel(op, field) {
8086
+ return field ? `${op} of ${field.label}` : "count";
8087
+ }
8088
+ var labelOf = (key) => key === "" ? EMPTY_GROUP_LABEL : key;
8089
+ function aggregateFields(fields, query) {
8090
+ const byId = new Map(fields.map((f) => [f.id, f]));
8091
+ const group = query.groupBy ? byId.get(query.groupBy) : void 0;
8092
+ const split = query.splitBy ? byId.get(query.splitBy) : void 0;
8093
+ const op = query.measure?.op ?? "count";
8094
+ const value = query.measure?.field ? byId.get(query.measure.field) : void 0;
8095
+ return [
8096
+ { id: AGGREGATE_FIELDS.group, label: group?.label ?? "All", type: "string" },
8097
+ { id: AGGREGATE_FIELDS.key, label: group?.label ?? "All", type: "string" },
8098
+ ...split ? [{ id: AGGREGATE_FIELDS.series, label: split.label, type: "string" }] : [],
8099
+ {
8100
+ id: AGGREGATE_FIELDS.value,
8101
+ label: measureLabel(op, value),
8102
+ type: "number",
8103
+ ...value?.unit && op !== "count" ? { unit: value.unit } : {}
8104
+ }
8105
+ ];
8106
+ }
8107
+ function aggregateDataset(dataset, query) {
8108
+ const byId = new Map(dataset.fields.map((f) => [f.id, f]));
8109
+ const group = query.groupBy ? byId.get(query.groupBy) : void 0;
8110
+ const split = query.splitBy ? byId.get(query.splitBy) : void 0;
8111
+ const op = query.measure?.op ?? "count";
8112
+ const valueField = query.measure?.field ? byId.get(query.measure.field) : void 0;
8113
+ const bucket = query.bucket ?? "month";
8114
+ const fields = aggregateFields(dataset.fields, query);
8115
+ if (op !== "count" && valueField?.type !== "number") {
8116
+ throw new Error(`${op} needs a number field`);
8117
+ }
8118
+ const rows = filterRows(dataset.rows, dataset.fields, query.filters);
8119
+ const cells = /* @__PURE__ */ new Map();
8120
+ for (const row of rows) {
8121
+ const groups = group ? groupKeys(row[group.id], group, bucket) : ["All"];
8122
+ const splits = split ? groupKeys(row[split.id], split, bucket) : [""];
8123
+ const value = valueField ? row[valueField.id] ?? null : 1;
8124
+ for (const g of groups) {
8125
+ const bySplit = cells.get(g) ?? /* @__PURE__ */ new Map();
8126
+ cells.set(g, bySplit);
8127
+ for (const s of splits) bySplit.set(s, [...bySplit.get(s) ?? [], value]);
8128
+ }
8129
+ }
8130
+ const countRows = !valueField;
8131
+ const totals = new Map(
8132
+ [...cells].map(([g, bySplit]) => [g, measure([...bySplit.values()].flat(), op, countRows)])
8133
+ );
8134
+ const byLabel = (a, b) => a === "" ? 1 : b === "" ? -1 : a.localeCompare(b);
8135
+ const byValue = (dir) => (a, b) => a === "" !== (b === "") ? a === "" ? 1 : -1 : dir * ((totals.get(a) ?? 0) - (totals.get(b) ?? 0)) || byLabel(a, b);
8136
+ const sort = query.sort ?? (group?.type === "date" ? "label" : "value-desc");
8137
+ const keys = [...cells.keys()].sort(
8138
+ sort === "label" ? byLabel : byValue(sort === "value-asc" ? 1 : -1)
8139
+ );
8140
+ const limit = query.limit ?? DEFAULT_LIMIT;
8141
+ const kept = keys.slice(0, limit);
8142
+ let splitKeys = [""];
8143
+ if (split) {
8144
+ const splitTotals = /* @__PURE__ */ new Map();
8145
+ for (const g of kept) {
8146
+ for (const [s, values] of cells.get(g) ?? []) {
8147
+ splitTotals.set(s, (splitTotals.get(s) ?? 0) + (measure(values, op, countRows) ?? 0));
8148
+ }
8149
+ }
8150
+ splitKeys = [...splitTotals.keys()].sort(
8151
+ (a, b) => a === "" !== (b === "") ? a === "" ? 1 : -1 : (splitTotals.get(b) ?? 0) - (splitTotals.get(a) ?? 0) || byLabel(a, b)
8152
+ ).slice(0, MAX_SERIES);
8153
+ }
8154
+ const out = [];
8155
+ for (const g of kept) {
8156
+ for (const s of splitKeys) {
8157
+ const values = cells.get(g)?.get(s);
8158
+ out.push({
8159
+ [AGGREGATE_FIELDS.group]: labelOf(g),
8160
+ [AGGREGATE_FIELDS.key]: g,
8161
+ ...split ? { [AGGREGATE_FIELDS.series]: labelOf(s) } : {},
8162
+ [AGGREGATE_FIELDS.value]: values ? measure(values, op, countRows) : null
8163
+ });
8164
+ }
8165
+ }
8166
+ return { fields, rows: out, totalRows: rows.length, truncated: keys.length > limit };
8167
+ }
8168
+ function fillTimeGaps(dataset, bucket) {
8169
+ const keyId = AGGREGATE_FIELDS.key;
8170
+ const keys = [...new Set(dataset.rows.map((r) => String(r[keyId] ?? "")))].filter(Boolean);
8171
+ if (keys.length < 2) return dataset;
8172
+ const sorted = [...keys].sort();
8173
+ const range = bucketRange(sorted[0], sorted[sorted.length - 1], bucket);
8174
+ if (!range || range.length === keys.length) return dataset;
8175
+ const hasSeries = dataset.fields.some((f) => f.id === AGGREGATE_FIELDS.series);
8176
+ const seriesLabels = hasSeries ? [...new Set(dataset.rows.map((r) => String(r[AGGREGATE_FIELDS.series])))] : [null];
8177
+ const byKey = /* @__PURE__ */ new Map();
8178
+ for (const row of dataset.rows) {
8179
+ const k = String(row[keyId] ?? "");
8180
+ byKey.set(k, [...byKey.get(k) ?? [], row]);
8181
+ }
8182
+ const rows = [];
8183
+ for (const k of range) {
8184
+ const existing = byKey.get(k);
8185
+ if (existing) rows.push(...existing);
8186
+ else {
8187
+ for (const s of seriesLabels) {
8188
+ rows.push({
8189
+ [AGGREGATE_FIELDS.group]: k,
8190
+ [keyId]: k,
8191
+ ...hasSeries ? { [AGGREGATE_FIELDS.series]: s } : {},
8192
+ [AGGREGATE_FIELDS.value]: null
8193
+ });
8194
+ }
8195
+ }
8196
+ }
8197
+ rows.push(...byKey.get("") ?? []);
8198
+ return { ...dataset, rows };
8199
+ }
8200
+ function datasetOf(fields, rows, query) {
8201
+ return query.records ? recordsOf({ fields, rows }, query) : aggregateDataset({ fields, rows }, query);
8202
+ }
8203
+ function defineRowsSource(definition) {
8204
+ const { useFields, useRows } = definition;
8205
+ function useDataset(params, query, options) {
8206
+ const fields = useFields(params);
8207
+ const rows = useRows(params, options?.enabled ?? true);
8208
+ const result = useMemo(() => {
8209
+ if (!rows.rows) return { dataset: void 0, error: null };
8210
+ try {
8211
+ return { dataset: datasetOf(fields.fields, rows.rows, query), error: null };
8212
+ } catch (error) {
8213
+ return { dataset: void 0, error };
8214
+ }
8215
+ }, [fields.fields, rows.rows, query]);
8216
+ return {
8217
+ dataset: result.dataset,
8218
+ isLoading: rows.isLoading || fields.isLoading,
8219
+ error: rows.error ?? fields.error ?? result.error
8220
+ };
8221
+ }
8222
+ return {
8223
+ id: definition.id,
8224
+ label: definition.label,
8225
+ description: definition.description,
8226
+ params: definition.params,
8227
+ useFields,
8228
+ useDataset
8229
+ };
8230
+ }
8231
+ function staticFields(fields) {
8232
+ const state = { fields, isLoading: false, error: null };
8233
+ return () => state;
8234
+ }
8235
+ function queryOfChart(chart) {
8236
+ if (chart.type === "table" && !chart.x) {
8237
+ return {
8238
+ records: true,
8239
+ ...chart.filters?.length ? { filters: chart.filters } : {},
8240
+ ...chart.orderBy ? { orderBy: chart.orderBy } : {},
8241
+ ...chart.limit ? { limit: chart.limit } : {}
8242
+ };
8243
+ }
8244
+ const grouped = chart.type !== "metric";
8245
+ const split = grouped && chart.type !== "pie" && chart.type !== "donut" && chart.series;
8246
+ const op = chart.aggregate ?? "count";
8247
+ return {
8248
+ ...chart.filters?.length ? { filters: chart.filters } : {},
8249
+ ...grouped && chart.x ? { groupBy: chart.x, bucket: chart.bucket ?? "month" } : {},
8250
+ ...split ? { splitBy: chart.series } : {},
8251
+ measure: { op, ...chart.y ? { field: chart.y } : {} },
8252
+ ...chart.sort ? { sort: chart.sort } : {},
8253
+ ...chart.limit ? { limit: chart.limit } : {}
8254
+ };
8255
+ }
8256
+ var TRENDS = /* @__PURE__ */ new Set(["bar", "line", "area"]);
8257
+ function usePanelDataset(source, params, chart, options) {
8258
+ const paramsKey = JSON.stringify(params ?? {});
8259
+ const chartKey = JSON.stringify(chart);
8260
+ const stableParams = useMemo(() => JSON.parse(paramsKey), [paramsKey]);
8261
+ const query = useMemo(() => queryOfChart(JSON.parse(chartKey)), [chartKey]);
8262
+ const fields = source.useFields(stableParams);
8263
+ const state = source.useDataset(stableParams, query, options);
8264
+ const xField = fields.fields.find((f) => f.id === chart.x);
8265
+ const fillGaps = !!state.dataset && xField?.type === "date" && TRENDS.has(chart.type) && (chart.sort ?? "label") === "label";
8266
+ const dataset = useMemo(
8267
+ () => state.dataset && fillGaps ? fillTimeGaps(state.dataset, chart.bucket ?? "month") : state.dataset,
8268
+ [state.dataset, fillGaps, chart.bucket]
8269
+ );
8270
+ return { ...state, dataset, fields: fields.fields };
8271
+ }
8272
+ function namesOfWorkspaces(workspaces) {
8273
+ const names = /* @__PURE__ */ new Map();
8274
+ for (const w of workspaces ?? []) {
8275
+ if (w.name) names.set(w.external_id, w.name);
8276
+ for (const member of w.users ?? []) {
8277
+ const user = member.user;
8278
+ if (!user?.external_id || names.has(user.external_id)) continue;
8279
+ const name = [user.given_name, user.family_name].filter(Boolean).join(" ").trim();
8280
+ names.set(user.external_id, name || user.email || user.external_id);
8281
+ }
8282
+ }
8283
+ return names;
8284
+ }
8285
+ function useNames(enabled = true) {
8286
+ const { data } = useWorkspaces({ enabled });
8287
+ return useMemo(() => {
8288
+ const names = namesOfWorkspaces(data);
8289
+ return (id) => id ? names.get(id) ?? id : null;
8290
+ }, [data]);
8291
+ }
8292
+
8293
+ // src/datasets/sources/conversations.ts
8294
+ var DEFAULT_CONVERSATIONS_SOURCE_LABELS = {
8295
+ source: "Threads",
8296
+ description: "The threads and tasks of the open workspace: activity, status, owners, due dates.",
8297
+ title: "Title",
8298
+ created: "Started",
8299
+ lastActivity: "Last activity",
8300
+ due: "Due",
8301
+ completed: "Completed",
8302
+ kind: "Kind",
8303
+ thread: "Thread",
8304
+ task: "Task",
8305
+ status: "Status",
8306
+ statuses: { todo: "To do", generating: "Running", done: "Done" },
8307
+ overdue: "Overdue",
8308
+ owner: "Owner",
8309
+ messages: "Messages",
8310
+ shared: "Shared"
8311
+ };
8312
+ function createConversationsSource(labels) {
8313
+ const l = { ...DEFAULT_CONVERSATIONS_SOURCE_LABELS, ...labels };
8314
+ const fields = [
8315
+ { id: "title", label: l.title, type: "string" },
8316
+ { id: "created", label: l.created, type: "date" },
8317
+ { id: "lastActivity", label: l.lastActivity, type: "date" },
8318
+ { id: "due", label: l.due, type: "date" },
8319
+ { id: "completed", label: l.completed, type: "date" },
8320
+ { id: "kind", label: l.kind, type: "string", options: [l.thread, l.task] },
8321
+ { id: "status", label: l.status, type: "string", options: Object.values(l.statuses) },
8322
+ { id: "overdue", label: l.overdue, type: "boolean" },
8323
+ { id: "owner", label: l.owner, type: "string" },
8324
+ { id: "messages", label: l.messages, type: "number" },
8325
+ { id: "shared", label: l.shared, type: "boolean" }
8326
+ ];
8327
+ return defineRowsSource({
8328
+ id: "conversations",
8329
+ label: l.source,
8330
+ description: l.description,
8331
+ useFields: staticFields(fields),
8332
+ useRows(params, enabled) {
8333
+ const arbi = useArbi();
8334
+ const workspaceId = typeof params.workspaceId === "string" && params.workspaceId ? params.workspaceId : arbi.hasWorkspace ? arbi.getWorkspaceId() : void 0;
8335
+ const query = useConversations(workspaceId, { enabled });
8336
+ const nameOf = useNames(enabled);
8337
+ const rows = useMemo(() => {
8338
+ const now = (/* @__PURE__ */ new Date()).toISOString();
8339
+ return query.data?.map((c) => ({
8340
+ title: c.title || null,
8341
+ created: c.created_at ?? null,
8342
+ lastActivity: c.last_message_updated_at ?? c.updated_at ?? null,
8343
+ due: c.due_at ?? null,
8344
+ completed: c.completed_at ?? null,
8345
+ kind: c.status ? l.task : l.thread,
8346
+ status: c.status ? l.statuses[c.status] : null,
8347
+ overdue: Boolean(c.due_at && c.status !== "done" && c.due_at < now),
8348
+ owner: nameOf(c.owner_ext_id ?? c.created_by_ext_id),
8349
+ messages: c.message_count ?? null,
8350
+ shared: c.is_shared ?? null
8351
+ }));
8352
+ }, [query.data, nameOf]);
8353
+ return { rows, isLoading: query.isLoading && !!workspaceId, error: query.error };
8354
+ }
8355
+ });
8356
+ }
8357
+ var DEFAULT_DATABASE_SOURCE_LABELS = {
8358
+ source: "Database",
8359
+ description: "A database of the open workspace, or one of its saved views.",
8360
+ database: "Database",
8361
+ view: "Saved view",
8362
+ allColumns: "All columns"
8363
+ };
8364
+ var MULTI = /* @__PURE__ */ new Set(["document", "relation", "lookup", "tag"]);
8365
+ function fieldOfColumn(column) {
8366
+ const type = column.type === "number" || column.type === "rollup" ? "number" : column.type === "date" ? "date" : column.type === "checkbox" ? "boolean" : "string";
8367
+ return {
8368
+ id: column.id,
8369
+ label: column.name,
8370
+ type,
8371
+ ...column.options?.length ? { options: column.options } : {},
8372
+ ...MULTI.has(column.type) ? { multiple: true } : {}
8373
+ };
8374
+ }
8375
+ var text = (v) => typeof v === "string" && v ? v : void 0;
8376
+ function databaseFields(database, view) {
8377
+ const columns = database?.columns ?? [];
8378
+ if (!view?.columns?.length) return columns.map(fieldOfColumn);
8379
+ const byId = new Map(columns.map((c) => [c.id, c]));
8380
+ return view.columns.flatMap((id) => {
8381
+ const column = byId.get(id);
8382
+ return column ? [fieldOfColumn(column)] : [];
8383
+ });
8384
+ }
8385
+ function aggregateRequest(query) {
8386
+ return {
8387
+ group_by: query.groupBy ?? null,
8388
+ split_by: query.splitBy ?? null,
8389
+ time_bucket: query.bucket ?? "month",
8390
+ measure: { op: query.measure?.op ?? "count", column: query.measure?.field ?? null },
8391
+ filters: (query.filters ?? []).map((f) => ({ column: f.field, op: f.op, value: f.value })),
8392
+ limit: query.limit ?? 50
8393
+ };
8394
+ }
8395
+ function datasetOfAggregate(result, fields, query) {
8396
+ const split = Boolean(query.splitBy);
8397
+ let order = result.keys.map((_, i) => i);
8398
+ const total = (i) => result.series.reduce((sum, s) => sum + (s.values[i] ?? 0), 0);
8399
+ if (query.sort === "label") {
8400
+ order = [...order].sort(
8401
+ (a, b) => result.keys[a] === "" ? 1 : result.keys[b] === "" ? -1 : result.labels[a].localeCompare(result.labels[b])
8402
+ );
8403
+ } else if (query.sort === "value-asc") {
8404
+ order = [...order].sort((a, b) => total(a) - total(b));
8405
+ } else if (query.sort === "value-desc") {
8406
+ order = [...order].sort((a, b) => total(b) - total(a));
8407
+ }
8408
+ const rows = order.flatMap(
8409
+ (i) => result.series.map((s) => ({
8410
+ [AGGREGATE_FIELDS.group]: result.labels[i],
8411
+ [AGGREGATE_FIELDS.key]: result.keys[i],
8412
+ ...split ? { [AGGREGATE_FIELDS.series]: s.label } : {},
8413
+ [AGGREGATE_FIELDS.value]: s.values[i] ?? null
8414
+ }))
8415
+ );
8416
+ return {
8417
+ fields: aggregateFields(fields, query),
8418
+ rows,
8419
+ totalRows: result.total_rows,
8420
+ truncated: result.truncated
8421
+ };
8422
+ }
8423
+ function datasetRowOf(row, fields) {
8424
+ const titles = row.titles ?? {};
8425
+ const out = {};
8426
+ for (const field of fields) {
8427
+ const raw = row.values[field.id];
8428
+ if (raw === null || raw === void 0) out[field.id] = null;
8429
+ else if (Array.isArray(raw)) out[field.id] = raw.map((v) => titles[String(v)] ?? String(v));
8430
+ else if (typeof raw === "string")
8431
+ out[field.id] = field.type === "string" ? titles[raw] ?? raw : raw;
8432
+ else if (typeof raw === "number" || typeof raw === "boolean") out[field.id] = raw;
8433
+ else out[field.id] = String(raw);
8434
+ }
8435
+ return out;
8436
+ }
8437
+ function createDatabaseSource(labels) {
8438
+ const l = { ...DEFAULT_DATABASE_SOURCE_LABELS, ...labels };
8439
+ function useView(params) {
8440
+ const arbi = useArbi();
8441
+ const databaseId = text(params.databaseId);
8442
+ const viewName = text(params.view);
8443
+ const settings = useUserSettings({ enabled: Boolean(viewName) });
8444
+ const workspaceId = arbi.hasWorkspace ? arbi.getWorkspaceId() : null;
8445
+ return useMemo(
8446
+ () => viewName && databaseId ? viewsOfTable(settings.data?.tableviews, workspaceId, databaseId).find(
8447
+ (v) => v.name === viewName
8448
+ ) : void 0,
8449
+ [settings.data?.tableviews, workspaceId, databaseId, viewName]
8450
+ );
8451
+ }
8452
+ function useFields(params) {
8453
+ const databaseId = text(params.databaseId) ?? null;
8454
+ const database = useDatabase(databaseId);
8455
+ const view = useView(params);
8456
+ const fields = useMemo(() => databaseFields(database.data, view), [database.data, view]);
8457
+ return { fields, isLoading: database.isLoading && !!databaseId, error: database.error };
8458
+ }
8459
+ function useDataset(params, query, options) {
8460
+ const databaseId = text(params.databaseId) ?? null;
8461
+ const enabled = options?.enabled ?? true;
8462
+ const fields = useFields(params);
8463
+ const grouped = !query.records;
8464
+ const request = useMemo(() => grouped ? aggregateRequest(query) : {}, [grouped, query]);
8465
+ const aggregate = useDatabaseAggregate(databaseId, request, { enabled: enabled && grouped });
8466
+ const rows = useDatabaseRows(enabled && !grouped ? databaseId : null, "");
8467
+ const dataset = useMemo(() => {
8468
+ if (grouped) {
8469
+ return aggregate.data ? datasetOfAggregate(aggregate.data, fields.fields, query) : void 0;
8470
+ }
8471
+ if (!rows.data) return void 0;
8472
+ const records = rows.data.rows.map((r) => datasetRowOf(r, fields.fields));
8473
+ return recordsOf({ fields: fields.fields, rows: records }, query);
8474
+ }, [grouped, query, aggregate.data, rows.data, fields.fields]);
8475
+ const active = grouped ? aggregate : rows;
8476
+ return {
8477
+ dataset,
8478
+ isLoading: !!databaseId && (active.isLoading || fields.isLoading),
8479
+ error: active.error ?? fields.error
8480
+ };
8481
+ }
8482
+ return {
8483
+ id: "database",
8484
+ label: l.source,
8485
+ description: l.description,
8486
+ params: [
8487
+ {
8488
+ id: "databaseId",
8489
+ label: l.database,
8490
+ required: true,
8491
+ useOptions() {
8492
+ const databases = useDatabases();
8493
+ const options = useMemo(
8494
+ () => (databases.data ?? []).map((d) => ({ value: d.id, label: d.name })),
8495
+ [databases.data]
8496
+ );
8497
+ return { options, isLoading: databases.isLoading };
8498
+ }
8499
+ },
8500
+ {
8501
+ id: "view",
8502
+ label: l.view,
8503
+ placeholder: l.allColumns,
8504
+ useOptions(params) {
8505
+ const arbi = useArbi();
8506
+ const databaseId = text(params.databaseId);
8507
+ const settings = useUserSettings({ enabled: Boolean(databaseId) });
8508
+ const workspaceId = arbi.hasWorkspace ? arbi.getWorkspaceId() : null;
8509
+ const options = useMemo(
8510
+ () => databaseId ? viewsOfTable(settings.data?.tableviews, workspaceId, databaseId).map((v) => ({
8511
+ value: v.name,
8512
+ label: v.name
8513
+ })) : [],
8514
+ [settings.data?.tableviews, workspaceId, databaseId]
8515
+ );
8516
+ return { options, isLoading: settings.isLoading && !!databaseId };
8517
+ }
8518
+ }
8519
+ ],
8520
+ useFields,
8521
+ useDataset
8522
+ };
8523
+ }
8524
+ var DEFAULT_DOCUMENTS_SOURCE_LABELS = {
8525
+ source: "Documents",
8526
+ description: "The documents of the open workspace: type, folder, status, dates.",
8527
+ created: "Added",
8528
+ updated: "Updated",
8529
+ documentDate: "Document date",
8530
+ status: "Status",
8531
+ type: "Type",
8532
+ folder: "Folder",
8533
+ nature: "Kind of document",
8534
+ author: "Author",
8535
+ createdBy: "Added by",
8536
+ pages: "Pages",
8537
+ size: "Size",
8538
+ shared: "Shared"
8539
+ };
8540
+ var workspaceOf2 = (params) => typeof params.workspaceId === "string" && params.workspaceId ? params.workspaceId : void 0;
8541
+ function createDocumentsSource(labels) {
8542
+ const l = { ...DEFAULT_DOCUMENTS_SOURCE_LABELS, ...labels };
8543
+ const fields = [
8544
+ { id: "name", label: l.source, type: "string" },
8545
+ { id: "created", label: l.created, type: "date" },
8546
+ { id: "updated", label: l.updated, type: "date" },
8547
+ { id: "documentDate", label: l.documentDate, type: "date" },
8548
+ { id: "status", label: l.status, type: "string" },
8549
+ { id: "type", label: l.type, type: "string" },
8550
+ { id: "folder", label: l.folder, type: "string" },
8551
+ { id: "nature", label: l.nature, type: "string" },
8552
+ { id: "author", label: l.author, type: "string" },
8553
+ { id: "createdBy", label: l.createdBy, type: "string" },
8554
+ { id: "pages", label: l.pages, type: "number" },
8555
+ { id: "size", label: l.size, type: "number", unit: "bytes" },
8556
+ { id: "shared", label: l.shared, type: "boolean" }
8557
+ ];
8558
+ return defineRowsSource({
8559
+ id: "documents",
8560
+ label: l.source,
8561
+ description: l.description,
8562
+ useFields: staticFields(fields),
8563
+ useRows(params, enabled) {
8564
+ const query = useDocuments(workspaceOf2(params), { enabled });
8565
+ const nameOf = useNames(enabled);
8566
+ const rows = useMemo(
8567
+ () => query.data?.map((d) => ({
8568
+ name: d.doc_metadata?.title || d.file_name || d.external_id,
8569
+ created: d.created_at ?? null,
8570
+ updated: d.updated_at ?? null,
8571
+ documentDate: d.doc_metadata?.doc_date ?? null,
8572
+ status: d.status ?? null,
8573
+ type: friendlyFileType(d.file_type, d.file_name) || null,
8574
+ folder: d.folder || null,
8575
+ nature: d.doc_metadata?.doc_nature ?? null,
8576
+ author: d.doc_metadata?.doc_author ?? null,
8577
+ createdBy: nameOf(d.created_by_ext_id),
8578
+ pages: d.n_pages ?? null,
8579
+ size: d.file_size ?? null,
8580
+ shared: d.shared ?? null
8581
+ })),
8582
+ [query.data, nameOf]
8583
+ );
8584
+ return { rows, isLoading: query.isLoading, error: query.error };
8585
+ }
8586
+ });
8587
+ }
8588
+ var DEFAULT_PROJECTS_SOURCE_LABELS = {
8589
+ source: "Projects",
8590
+ description: "Your projects: stage, lead, client and their own fields; opened and closed.",
8591
+ name: "Name",
8592
+ opened: "Opened",
8593
+ stage: "Stage",
8594
+ stageChanged: "Stage changed",
8595
+ lead: "Lead",
8596
+ client: "Client",
8597
+ plan: "Plan",
8598
+ state: "Open or closed",
8599
+ open: "Open",
8600
+ closed: "Closed",
8601
+ closedAt: "Closed"
8602
+ };
8603
+ var FIELD_PREFIX = "field:";
8604
+ function hostField(entry) {
8605
+ const type = entry.type === "number" || entry.type === "rollup" ? "number" : entry.type === "date" ? "date" : entry.type === "checkbox" ? "boolean" : "string";
8606
+ return {
8607
+ id: `${FIELD_PREFIX}${entry.key}`,
8608
+ label: entry.label || entry.key,
8609
+ type,
8610
+ ...entry.options?.length ? { options: entry.options } : {}
8611
+ };
8612
+ }
8613
+ function hostValue(value, field) {
8614
+ if (value === null || value === void 0 || value === "") return null;
8615
+ if (Array.isArray(value)) return value.map(String);
8616
+ if (field.type === "number") return typeof value === "number" ? value : Number(value) || null;
8617
+ if (field.type === "boolean") return Boolean(value);
8618
+ return String(value);
8619
+ }
8620
+ function createProjectsSource(options = {}) {
8621
+ const l = { ...DEFAULT_PROJECTS_SOURCE_LABELS, ...options.labels };
8622
+ const closing = new Set((options.closedStages ?? []).map((s) => s.toLowerCase()));
8623
+ const base = [
8624
+ { id: "name", label: l.name, type: "string" },
8625
+ { id: "opened", label: l.opened, type: "date" },
8626
+ { id: "stage", label: l.stage, type: "string" },
8627
+ { id: "stageChanged", label: l.stageChanged, type: "date" },
8628
+ { id: "lead", label: l.lead, type: "string" },
8629
+ { id: "client", label: l.client, type: "string" },
8630
+ { id: "plan", label: l.plan, type: "string" },
8631
+ ...closing.size ? [
8632
+ { id: "state", label: l.state, type: "string", options: [l.open, l.closed] },
8633
+ { id: "closedAt", label: l.closedAt, type: "date" }
8634
+ ] : []
8635
+ ];
8636
+ function fieldsOf(projects) {
8637
+ const seen = /* @__PURE__ */ new Map();
8638
+ for (const p of projects ?? []) {
8639
+ for (const entry of p.field_schema ?? []) {
8640
+ if (!seen.has(entry.key)) seen.set(entry.key, hostField(entry));
8641
+ }
8642
+ }
8643
+ return [...base, ...seen.values()];
8644
+ }
8645
+ return defineRowsSource({
8646
+ id: "projects",
8647
+ label: l.source,
8648
+ description: l.description,
8649
+ useFields() {
8650
+ const query = useProjects();
8651
+ const fields = useMemo(
8652
+ () => fieldsOf(query.data),
8653
+ [query.data]
8654
+ );
8655
+ return { fields, isLoading: query.isLoading, error: query.error };
8656
+ },
8657
+ useRows(_params, enabled) {
8658
+ const query = useProjects({ enabled });
8659
+ const nameOf = useNames(enabled);
8660
+ const rows = useMemo(() => {
8661
+ const projects = query.data;
8662
+ if (!projects) return void 0;
8663
+ const host = fieldsOf(projects).filter((f) => f.id.startsWith(FIELD_PREFIX));
8664
+ const people = new Set(
8665
+ projects.flatMap(
8666
+ (p) => (p.field_schema ?? []).filter((e) => e.type === "person").map((e) => e.key)
8667
+ )
8668
+ );
8669
+ return projects.map((p) => {
8670
+ const closed = !!p.stage && closing.has(p.stage.toLowerCase());
8671
+ const row = {
8672
+ name: p.name,
8673
+ opened: p.created_at,
8674
+ stage: p.stage ?? null,
8675
+ stageChanged: p.stage_changed_at ?? null,
8676
+ lead: nameOf(p.lead_user),
8677
+ client: p.client ?? null,
8678
+ plan: p.subscription ?? null
8679
+ };
8680
+ if (closing.size) {
8681
+ row.state = closed ? l.closed : l.open;
8682
+ row.closedAt = closed ? p.stage_changed_at ?? null : null;
8683
+ }
8684
+ for (const field of host) {
8685
+ const key = field.id.slice(FIELD_PREFIX.length);
8686
+ const value = hostValue(p.fields?.[key], field);
8687
+ row[field.id] = people.has(key) && value !== null ? Array.isArray(value) ? value.map((id) => nameOf(id) ?? id) : nameOf(String(value)) : value;
8688
+ }
8689
+ return row;
8690
+ });
8691
+ }, [query.data, nameOf]);
8692
+ return { rows, isLoading: query.isLoading, error: query.error };
8693
+ }
8694
+ });
8695
+ }
8696
+ var MODEL_GROUP_LABELS = {
8697
+ "arbi-transcribe-diarized": "Transcription (diarized)",
8698
+ "arbi-transcribe": "Transcription"
8699
+ };
8700
+ var DEFAULT_USAGE_SOURCE_LABELS = {
8701
+ source: "AI usage",
8702
+ description: "AI usage of your projects by day and model: \xA3 (ex VAT), tokens and requests.",
8703
+ period: "Period",
8704
+ periods: { current: "This period", previous: "Last period" },
8705
+ day: "Day",
8706
+ project: "Project",
8707
+ model: "Model",
8708
+ spend: "AI usage (\xA3)",
8709
+ tokens: "Tokens",
8710
+ requests: "Requests"
8711
+ };
8712
+ var monthsBackOf = (params) => String(params.period ?? "0") === "1" ? 1 : 0;
8713
+ function usageRows(usage, project, modelLabel = (g) => MODEL_GROUP_LABELS[g] ?? g) {
8714
+ return (usage.daily ?? []).flatMap(
8715
+ (day) => Object.entries(day.model_groups ?? {}).map(([group, mg]) => ({
8716
+ day: day.date,
8717
+ project,
8718
+ model: modelLabel(group),
8719
+ spend: mg.spend ?? 0,
8720
+ tokens: mg.total_tokens ?? 0,
8721
+ requests: (mg.successful_requests ?? 0) + (mg.failed_requests ?? 0)
8722
+ }))
8723
+ );
8724
+ }
8725
+ function createUsageSource(labels) {
8726
+ const l = { ...DEFAULT_USAGE_SOURCE_LABELS, ...labels };
8727
+ const fields = [
8728
+ { id: "day", label: l.day, type: "date" },
8729
+ { id: "project", label: l.project, type: "string" },
8730
+ { id: "model", label: l.model, type: "string" },
8731
+ { id: "spend", label: l.spend, type: "number", unit: "gbp" },
8732
+ { id: "tokens", label: l.tokens, type: "number", unit: "tokens" },
8733
+ { id: "requests", label: l.requests, type: "number" }
8734
+ ];
8735
+ const periodOptions = {
8736
+ options: [
8737
+ { value: "0", label: l.periods.current },
8738
+ { value: "1", label: l.periods.previous }
8739
+ ],
8740
+ isLoading: false
8741
+ };
8742
+ return defineRowsSource({
8743
+ id: "usage",
8744
+ label: l.source,
8745
+ description: l.description,
8746
+ params: [
8747
+ {
8748
+ id: "period",
8749
+ label: l.period,
8750
+ placeholder: l.periods.current,
8751
+ useOptions: () => periodOptions
8752
+ }
8753
+ ],
8754
+ useFields: staticFields(fields),
8755
+ useRows(params, enabled) {
8756
+ const arbi = useArbi();
8757
+ const monthsBack = monthsBackOf(params);
8758
+ const projects = useProjects({ enabled });
8759
+ const list = projects.data ?? [];
8760
+ const results = useQueries({
8761
+ queries: list.map((p) => ({
8762
+ queryKey: arbiQueryKeys.projectUsage(p.external_id, monthsBack),
8763
+ queryFn: () => arbi.projects.usage(p.external_id, monthsBack),
8764
+ enabled: enabled && arbi.isLoggedIn
8765
+ }))
8766
+ });
8767
+ const signature = results.map((r) => `${r.status}:${r.dataUpdatedAt}`).join("|");
8768
+ const rows = useMemo(() => {
8769
+ if (!projects.data || results.some((r) => r.isLoading)) return void 0;
8770
+ return results.flatMap(
8771
+ (r, i) => r.data ? usageRows(r.data, list[i].name) : []
8772
+ );
8773
+ }, [projects.data, signature]);
8774
+ return {
8775
+ rows,
8776
+ isLoading: projects.isLoading || results.some((r) => r.isLoading),
8777
+ error: projects.error ?? results.find((r) => r.error)?.error ?? null
8778
+ };
8779
+ }
8780
+ });
8781
+ }
8782
+ var DEFAULT_WORKSPACES_SOURCE_LABELS = {
8783
+ source: "Workspaces",
8784
+ description: "Your workspaces: their project, documents, threads, members and storage.",
8785
+ name: "Workspace",
8786
+ project: "Project",
8787
+ documents: "Documents",
8788
+ threads: "Threads",
8789
+ members: "Members",
8790
+ storage: "Storage (MB)",
8791
+ created: "Created",
8792
+ updated: "Updated",
8793
+ shared: "Public"
8794
+ };
8795
+ function createWorkspacesSource(labels) {
8796
+ const l = { ...DEFAULT_WORKSPACES_SOURCE_LABELS, ...labels };
8797
+ const fields = [
8798
+ { id: "name", label: l.name, type: "string" },
8799
+ { id: "project", label: l.project, type: "string" },
8800
+ { id: "documents", label: l.documents, type: "number" },
8801
+ { id: "threads", label: l.threads, type: "number" },
8802
+ { id: "members", label: l.members, type: "number" },
8803
+ { id: "storage", label: l.storage, type: "number", unit: "MB" },
8804
+ { id: "created", label: l.created, type: "date" },
8805
+ { id: "updated", label: l.updated, type: "date" },
8806
+ { id: "shared", label: l.shared, type: "boolean" }
8807
+ ];
8808
+ return defineRowsSource({
8809
+ id: "workspaces",
8810
+ label: l.source,
8811
+ description: l.description,
8812
+ useFields: staticFields(fields),
8813
+ useRows(_params, enabled) {
8814
+ const workspaces = useWorkspaces({ enabled });
8815
+ const projects = useProjects({ enabled });
8816
+ const rows = useMemo(() => {
8817
+ const list = workspaces.data;
8818
+ if (!list) return void 0;
8819
+ const projectNames = new Map(
8820
+ (projects.data ?? []).map((p) => [
8821
+ p.external_id,
8822
+ p.name
8823
+ ])
8824
+ );
8825
+ return list.map((w) => ({
8826
+ name: w.name,
8827
+ project: w.project_ext_id ? projectNames.get(w.project_ext_id) ?? null : null,
8828
+ documents: (w.shared_document_count ?? 0) + (w.private_document_count ?? 0),
8829
+ threads: (w.shared_conversation_count ?? 0) + (w.private_conversation_count ?? 0),
8830
+ members: w.users?.length ?? 0,
8831
+ storage: Math.round((w.user_files_mb ?? 0) * 10) / 10,
8832
+ created: w.created_at ?? null,
8833
+ updated: w.updated_at ?? null,
8834
+ shared: w.is_public ?? null
8835
+ }));
8836
+ }, [workspaces.data, projects.data]);
8837
+ return { rows, isLoading: workspaces.isLoading, error: workspaces.error };
8838
+ }
8839
+ });
8840
+ }
8841
+
8842
+ // src/datasets/registry.ts
8843
+ var BUILTIN_DATA_SOURCES = [
8844
+ createUsageSource(),
8845
+ createDocumentsSource(),
8846
+ createConversationsSource(),
8847
+ createProjectsSource(),
8848
+ createWorkspacesSource(),
8849
+ createDatabaseSource()
8850
+ ];
8851
+ function createDataSourceRegistry(sources) {
8852
+ const byId = /* @__PURE__ */ new Map();
8853
+ for (const source of sources) byId.set(source.id, source);
8854
+ const list = [...byId.values()];
8855
+ return { list, get: (id) => byId.get(id) };
8856
+ }
8857
+ function useDataSources() {
8858
+ const { dashboards } = useArbiHost();
8859
+ return useMemo(
8860
+ () => createDataSourceRegistry([
8861
+ ...dashboards?.builtins === false ? [] : BUILTIN_DATA_SOURCES,
8862
+ ...dashboards?.sources ?? []
8863
+ ]),
8864
+ [dashboards]
8865
+ );
8866
+ }
8867
+ var MAX_DASHBOARD_SPEC_CHARS = 1e4;
8868
+ var isObject = (v) => typeof v === "object" && v !== null && !Array.isArray(v);
8869
+ function isPanel(v) {
8870
+ return isObject(v) && typeof v.id === "string" && typeof v.title === "string" && isObject(v.source) && typeof v.source.id === "string" && isObject(v.chart) && typeof v.chart.type === "string";
8871
+ }
8872
+ function parseDashboardSpec(value) {
8873
+ let parsed = value;
8874
+ if (typeof value === "string") {
8875
+ try {
8876
+ parsed = JSON.parse(value);
8877
+ } catch {
8878
+ return null;
8879
+ }
8880
+ }
8881
+ if (!isObject(parsed) || parsed.version !== 1 || typeof parsed.title !== "string") return null;
8882
+ const panels = Array.isArray(parsed.panels) ? parsed.panels.filter(isPanel) : [];
8883
+ return {
8884
+ version: 1,
8885
+ title: parsed.title,
8886
+ ...typeof parsed.description === "string" ? { description: parsed.description } : {},
8887
+ panels
8888
+ };
8889
+ }
8890
+ function serializeDashboardSpec(spec, max = MAX_DASHBOARD_SPEC_CHARS) {
8891
+ const json = JSON.stringify(spec);
8892
+ if (json.length > max) {
8893
+ throw new Error(
8894
+ `This dashboard is too large to save (${json.length.toLocaleString("en-GB")} characters, at most ${max.toLocaleString("en-GB")}). Remove a panel or split it into two dashboards.`
8895
+ );
8896
+ }
8897
+ return json;
8898
+ }
8899
+ function createMemoryDashboardStore(initial = [], scope = "memory") {
8900
+ let items = [...initial];
8901
+ let next = items.length + 1;
8902
+ return {
8903
+ scope,
8904
+ list: async () => items.map((d) => ({ ...d })),
8905
+ save: async ({ id, spec }) => {
8906
+ const saved = { id: id ?? `dash-${next++}`, spec, updatedAt: (/* @__PURE__ */ new Date()).toISOString() };
8907
+ items = id ? items.map((d) => d.id === id ? saved : d) : [...items, saved];
8908
+ return saved;
8909
+ },
8910
+ remove: async (id) => {
8911
+ items = items.filter((d) => d.id !== id);
8912
+ }
8913
+ };
8914
+ }
8915
+ var NAME_COLUMN = "Name";
8916
+ var SPEC_COLUMN = "Spec";
8917
+ function useDatabaseDashboardStore(options = {}) {
8918
+ const arbi = useArbi();
8919
+ const queryClient = useQueryClient();
8920
+ const name = options.name ?? "Dashboards";
8921
+ const workspaceId = arbi.hasWorkspace ? arbi.getWorkspaceId() : null;
8922
+ return useMemo(() => {
8923
+ async function find() {
8924
+ const all = await arbi.databases.list();
8925
+ return all.find(
8926
+ (d) => d.editable && d.workspace_id === workspaceId && d.name === name && (d.columns ?? []).some((c) => c.name === SPEC_COLUMN)
8927
+ );
8928
+ }
8929
+ async function ensure() {
8930
+ const found = await find();
8931
+ if (found) return found;
8932
+ const created = await arbi.databases.create({
8933
+ name,
8934
+ description: "Saved dashboards (written by the Dashboards page).",
8935
+ columns: [
8936
+ { name: NAME_COLUMN, type: "text" },
8937
+ { name: SPEC_COLUMN, type: "text" }
8938
+ ]
8939
+ });
8940
+ void queryClient.invalidateQueries({ queryKey: arbiQueryKeys.databaseList() });
8941
+ return created;
8942
+ }
8943
+ return {
8944
+ scope: workspaceId,
8945
+ async list() {
8946
+ const database = await find();
8947
+ if (!database) return [];
8948
+ const spec = database.columns?.find((c) => c.name === SPEC_COLUMN)?.id ?? SPEC_COLUMN;
8949
+ const page = await arbi.databases.rows(database.id, { limit: 1e3 });
8950
+ return page.rows.flatMap((row) => {
8951
+ const parsed = parseDashboardSpec(row.values[spec]);
8952
+ return parsed ? [{ id: row.id, spec: parsed, updatedAt: row.updated_at }] : [];
8953
+ });
8954
+ },
8955
+ async save({ id, spec }) {
8956
+ const values = { [NAME_COLUMN]: spec.title, [SPEC_COLUMN]: serializeDashboardSpec(spec) };
8957
+ const database = await ensure();
8958
+ const row = id ? await arbi.databases.updateRow(database.id, id, values) : (await arbi.databases.addRows(database.id, [{ values }]))[0];
8959
+ return { id: row.id, spec, updatedAt: row.updated_at };
8960
+ },
8961
+ async remove(id) {
8962
+ const database = await find();
8963
+ if (database) await arbi.databases.deleteRows(database.id, [id]);
8964
+ }
8965
+ };
8966
+ }, [arbi, queryClient, name, workspaceId]);
8967
+ }
8968
+ function useDashboardStore() {
8969
+ const { dashboards } = useArbiHost();
8970
+ return (dashboards?.useStore ?? useDatabaseDashboardStore)();
8971
+ }
8972
+ function useSavedDashboards(store) {
8973
+ return useQuery({
8974
+ queryKey: arbiQueryKeys.dashboards(store.scope ?? ""),
8975
+ queryFn: () => store.list(),
8976
+ enabled: store.scope !== null
8977
+ });
8978
+ }
8979
+ function useSaveDashboard(store) {
8980
+ const queryClient = useQueryClient();
8981
+ const key = arbiQueryKeys.dashboards(store.scope ?? "");
8982
+ return useMutation({
8983
+ mutationFn: (dashboard) => store.save(dashboard),
8984
+ onSuccess: (saved) => {
8985
+ queryClient.setQueryData(
8986
+ key,
8987
+ (old = []) => old.some((d) => d.id === saved.id) ? old.map((d) => d.id === saved.id ? saved : d) : [...old, saved]
8988
+ );
8989
+ void queryClient.invalidateQueries({ queryKey: arbiQueryKeys.databaseRows() });
8990
+ }
8991
+ });
8992
+ }
8993
+ function useDeleteDashboard(store) {
8994
+ const queryClient = useQueryClient();
8995
+ const key = arbiQueryKeys.dashboards(store.scope ?? "");
8996
+ return useMutation({
8997
+ mutationFn: (id) => store.remove(id),
8998
+ onSuccess: (_void, id) => {
8999
+ queryClient.setQueryData(key, (old = []) => old.filter((d) => d.id !== id));
9000
+ void queryClient.invalidateQueries({ queryKey: arbiQueryKeys.databaseRows() });
9001
+ }
9002
+ });
9003
+ }
7841
9004
  var PARSED_STALE_TIME = 5 * 60 * 1e3;
7842
9005
  function indexPassages(results) {
7843
9006
  const index = /* @__PURE__ */ new Map();
@@ -10048,7 +11211,7 @@ function useWorkspaceDocs(workspaceId) {
10048
11211
  function useAiTask() {
10049
11212
  const mutation = useAssistantQuery();
10050
11213
  const [status, setStatus] = useState("idle");
10051
- const [text, setText] = useState("");
11214
+ const [text2, setText] = useState("");
10052
11215
  const [stepCount, setStepCount] = useState(0);
10053
11216
  const [error, setError] = useState(null);
10054
11217
  const [responseId, setResponseId] = useState(null);
@@ -10128,7 +11291,7 @@ function useAiTask() {
10128
11291
  );
10129
11292
  return {
10130
11293
  status,
10131
- text,
11294
+ text: text2,
10132
11295
  stepCount,
10133
11296
  error,
10134
11297
  responseId,
@@ -10175,7 +11338,7 @@ function textToArtifact(title, content, opts) {
10175
11338
  }
10176
11339
  function AiAnswer({
10177
11340
  status,
10178
- text,
11341
+ text: text2,
10179
11342
  stepCount,
10180
11343
  error,
10181
11344
  className,
@@ -10186,9 +11349,9 @@ function AiAnswer({
10186
11349
  }) {
10187
11350
  const [copied, setCopied] = useState(false);
10188
11351
  const running = status === "running";
10189
- const hasText = text.trim().length > 0;
11352
+ const hasText = text2.trim().length > 0;
10190
11353
  const copy = async () => {
10191
- await navigator.clipboard.writeText(text);
11354
+ await navigator.clipboard.writeText(text2);
10192
11355
  setCopied(true);
10193
11356
  setTimeout(() => setCopied(false), 1600);
10194
11357
  };
@@ -10219,7 +11382,7 @@ function AiAnswer({
10219
11382
  }
10220
11383
  ),
10221
11384
  hasText && /* @__PURE__ */ jsxs(Fragment, { children: [
10222
- /* @__PURE__ */ jsx(AiMarkdown, { isStreaming: running, children: text }),
11385
+ /* @__PURE__ */ jsx(AiMarkdown, { isStreaming: running, children: text2 }),
10223
11386
  !running && /* @__PURE__ */ jsxs("div", { className: "flex items-center justify-between border-t border-border pt-2.5", children: [
10224
11387
  /* @__PURE__ */ jsxs("span", { className: "inline-flex items-center gap-1.5 text-xs text-muted-foreground", children: [
10225
11388
  /* @__PURE__ */ jsx(ShieldCheck, { className: "size-3.5 text-ai-accent" }),
@@ -10943,17 +12106,17 @@ var CitationPopover = ({
10943
12106
  useLayoutEffect(() => {
10944
12107
  if (!open) return;
10945
12108
  const edge = document.querySelector('[data-testid="message-input-container"]') ?? document.querySelector('main[data-testid^="conversation-"]') ?? document.body;
10946
- const measure = () => {
12109
+ const measure2 = () => {
10947
12110
  const rect = edge.getBoundingClientRect();
10948
12111
  setDock({ left: rect.left, top: rect.top, width: rect.width });
10949
12112
  };
10950
- measure();
10951
- const observer = new ResizeObserver(measure);
12113
+ measure2();
12114
+ const observer = new ResizeObserver(measure2);
10952
12115
  observer.observe(edge);
10953
- window.addEventListener("resize", measure);
12116
+ window.addEventListener("resize", measure2);
10954
12117
  return () => {
10955
12118
  observer.disconnect();
10956
- window.removeEventListener("resize", measure);
12119
+ window.removeEventListener("resize", measure2);
10957
12120
  };
10958
12121
  }, [open]);
10959
12122
  const handleOpen = useCallback(() => {
@@ -12254,17 +13417,17 @@ function DmComposer({
12254
13417
  setAttachError(null);
12255
13418
  };
12256
13419
  const submit = async () => {
12257
- const text = draft.trim();
12258
- if (!text && files.length === 0 || disabled || busy) return;
13420
+ const text2 = draft.trim();
13421
+ if (!text2 && files.length === 0 || disabled || busy) return;
12259
13422
  const sending = files;
12260
13423
  setDraft("");
12261
13424
  setFiles([]);
12262
13425
  setAttachError(null);
12263
13426
  try {
12264
- await onSend(text, sending);
13427
+ await onSend(text2, sending);
12265
13428
  inputRef.current?.focus();
12266
13429
  } catch {
12267
- setDraft(text);
13430
+ setDraft(text2);
12268
13431
  setFiles(sending);
12269
13432
  }
12270
13433
  };
@@ -13103,6 +14266,6 @@ function CommandPaletteProvider({
13103
14266
  ] });
13104
14267
  }
13105
14268
 
13106
- export { AGENT_CONTROL_COMMANDS, ALLOWED_PORTAL_ORIGINS, ARCHIVE_POLL_MS, ASSISTANT_MENTION_LABEL, AUTO_CHAT_MODEL, ActivityFeed, AiActionCard, AiAnswer, AppleIcon, ArbiBotIcon, ArbiHost2 as ArbiHost, ArbiWebSocketProvider, ArtifactCanvas, BOX_SEAT_REFUSED, BOX_SEAT_REFUSED_ACTION, BOX_SEAT_REFUSED_TITLE, CONVERSATION_SWITCH_MEASURE, ChatBubble, CitationRenderer, CommandPalette, CommandPaletteProvider, ConversationList, ConversationScope, DATABASE_RELATION_PICK_LIMIT, DATABASE_ROWS_PAGE, DEFAULT_ASPECT_OPTIONS, DEFAULT_PASSWORD_CHANGE_FORM_MESSAGES, DateSeparator, DmAvatar, DmComposer, DocQaPanel, DocSearch, DocumentCardMenu, DocumentReview, DraftTitleControls, FIRST_TOKEN_MEASURE, FileIcon, GitHubIcon, ImageCropModal, ImageCropper, LIVE_UPDATE_TYPES, LinkedInIcon, MAIL_DRAFT_REPLACED_EVENT, MIN_NARRATION_DWELL_MS, MailOfflineUnavailableError, MessageArtifactCard, PENDING_SYNC_PREDICATE, POLL_EVERY_MS, PhotoCapture, RUN_WINDOW_MS, SIGNATURE_NOTIFICATION_TYPES, SLOW_AFTER_MS, STILL_WORKING, StorageActionError, TRANSFER_POLL_MS, TaskThreadPendingError, TypingIndicator, UPLOAD_ACCEPT, UPLOAD_MAX_FILE_SIZE, VideoCapture, VoiceNoteRecorder, WORK_NOTIFICATION_LABELS, __resetPendingFinalCommitsForTests, __resetStreamingTokenBufferForTests, accountPath, addAssistantMessageToCache, addUserMessageToCache, adoptNewChatDocument, aliasTakenMessage, allConversationThreads, annotateThread, announceMailDraftReplaced, appendTokenToMessage, applyConversationEvent, applyFinalContextToMessage, applyLiveUpdate, applyNotificationRow, applyOptimisticDocumentEdit, applyOutputItemToMessage, applyTaskEvent, arbiMailClient, archiveName, archivedWorkspaceMessage, bindThreadDocument, boundDocumentOf, buildDocumentMetadataRows, buildMentionCandidates, buildPendingFirstTurn, buildPendingSyncItem, buildWorkspaceArchive, cacheThreadBinding, cachedAssistantMode, cachedMentionCandidates, cachedQuotaUsedUp, calendarNotificationMeta, callNotificationMeta, captureFrameAsBlob, clearLoadingState, clearUserInputRequest, commitFinalMessage, completeQueuedUserMessageByContent, connectOAuthCalendarAccount, connectorErrorStatus, connectorReturnTo, createMailClient, createSkillPack, createStreamHandlers, createWorkspaceSwitch, cropImage, dayKey, defaultMailAlias, deploymentUserMeta, describeActivity, describeCalendarNotification, describeServerNotification, discardStreamingTokensForMessage, disconnectAttachedRun, documentActivityMeta, documentActivityPhrase, documentDisplayName, docxMentionMeta, downloadRecoveryFile, ensureAssistantMessageLoading, extractZipFile, fallbackFileName, fileAttachment, filesFromDrop, flushStreamingTokens, forgetUploadedDocumentFolder, formatConfigValidationError, formatIdentityPrice, getInterjectionText, getNotificationTypeMeta, getOfflineDocument, getOrphanedLastMessage, getRelatedLabels, getRelatedTotal, getRunStartedAt, getThreadsQueryKey, getWorkspaceActionText, getWorkspaceKind, getWorkspaceSentPhrase, hasPendingFinalCommit, hasVideoTrack, identityStepFor, inputRequestTitle, invalidateCalendarEvents, invalidateCalendars, invalidateConversationActivity, isActivityKey, isAliasTakenError, isArchiveMoving, isCommentToPeople, isDeploymentAdmin, isDeploymentUserNotification, isFullConfig, isMessageRunning, isNotificationRow, isOfflineReadableArbiQuery, isOrphanedUserMessage, isQueuedCalendarWrite, isReplayableArbiMutation, isRestorableArbiQueryOnline, isSignatureNotificationType, isTransferFinished, isTransferResumable, isWorkspaceArchivedError, isWorkspaceNotificationType, isZipFile, loadOfflineDocument, mailDraftIdFromContent, mailJson, markMessageAsFailed, markNarrationSettled, migrateLegacyThreadDocuments, mountDiditVerification, nextAliasSuggestion, notificationUserName, openAccessRequest, parseActivityContent, parseDeleteAccountBlockers, pendingChatModelSave, peopleDirectory, personOfUser, pickRecentWorkspaces, prepareUploadFiles, redlineStats, refuseChatWhenOffline, registerArbiMutationDefaults, registerAttachedRun, removeSettledNarration, requestPersistentStorage, resetCalendarAccountSyncState, resetMessageContent, resolveActiveWorkspace, resolveConfigModel, resolveReplyTarget, rollbackOptimisticDocumentEdit, safePortalUrl, serverNotificationBellEntry, setMessageContent, setUserInputRequest, signatureNotificationPhrase, signatureRequestMeta, subscribeDocumentReads, supportsHouseTemplates, textToArtifact, threadBinding, threadEndingAtContains, titleFromQuestion, toChatCitations, toNotificationPreferences, toRedlineMarkdown, toShellWorkspace, updateMessageWithMetadata, updateUserMessageInCache, updateUserMessageStateInCache, uploadFolderOf, uploadedDocumentFolder, useActOnStep, useAddChatMembers, useAddDatabaseRows, useAddHolidayCalendar, useAddProjectAddonBlock, useAddWorkspaceMembers, useAddonQuote, useAgentChats, useAgentConfig, useAgentDmStatus, useAgentModels, useAgentRunControl, useAgentSession, useAgentWorkspaces, useAiTask, useAnswerAgentQuestion, useApplyChatModel, useArbiConnected, useArbiShellWorkspaces, useArbiWebSocket, useArbiWsContext, useArbiWsMessage, useArbiWsStatus, useArchiveProgressPolling, useArchiveWorkspace, useAskAgain, useAssignDocTags, useAuthorizeLimits, useAutoSendDraft, useBookingPages, useBranchNavigation, useCalDavProfiles, useCalendarAccounts, useCalendarEvent, useCalendarEventByUid, useCalendarEvents, useCalendarInvitations, useCalendarOutbox, useCalendarOverlays, useCalendarSettings, useCalendarShares, useCalendarSupport, useCalendars, useCameraStream, useCanEditShared, useCancelDriveSync, useCancelMailboxSync, useCancelManyPendingSync, useCancelProjectSubscription, useCancelWorkspaceTransfer, useChangeProjectPlan, useChargeWatch, useChatArrivals, useChatPost, useChatSummaries, useChatThread, useChatUnreadTotal, useChats, useClaimNativeAlias, useCloseAgentSession, useCommandPalette, useConfigSchema, useConfirmEmailChange, useConnectCalDavAccount, useConnectMailAccount, useConnectOAuthAccount, useConnectRunStream, useConnectorAutoSync, useConnectorCatalog, useConnectorVendorVisibility, useContacts, useConversation, useConversationActions, useConversationActivity, useConversationData, useConversationDocuments, useConversationIsShared, useConversationItems, useConversationPendingAuth, useConversationSearch, useConversationTurn, useConversationUsage, useCreateAgent, useCreateCalendar, useCreateContact, useCreateDatabase, useCreateEvent, useCreateFact, useCreateFacts, useCreateGroupChat, useCreateProject, useCreateProjectCheckout, useCreateRoom, useCreateWork, useCreateWorkflow, useCreateWorkspace, useCurrentSessionId, useDatabase, useDatabaseRows, useDatabases, useDecideCounter, useDeleteAccount, useDeleteAccountFlow, useDeleteBookingPage, useDeleteCalendar, useDeleteChatMessage, useDeleteConfig, useDeleteContact, useDeleteConversation, useDeleteDatabase, useDeleteDatabaseRows, useDeleteDocuments, useDeleteEvent, useDeleteFact, useDeleteMessage, useDeleteNotifications, useDeleteProject, useDeleteSkill, useDeleteWorkflow, useDeleteWorkspaces, useDisconnectCalendarAccount, useDisconnectConnector, useDisconnectMailAccount, useDisconnectSlack, useDismissedTips, useDocumentAutoAdd, useDocumentHostActions, useDocumentPendingSync, useDocumentThumbnails, useDocumentsSupport, useDownloadDocuments, useDriveFolderChildren, useDriveFolderDocCount, useDriveFolders, useDriveSyncEstimate, useDriveSyncProgress, useEmailChange, useEnableDriveSync, useEnableMailboxSync, useExportDatabase, useFacts, useFetchCalendarEvent, useFilteredProjects, useFinaliseTranslation, useFindTime, useFollowThread, useFreeBusy, useGenerateAgentAvatar, useGenerateDocTags, useGrantAgentAccess, useHolidayCountries, useHouseTemplateCandidates, useIdentityVerification, useIdentityVerificationFlow, useImportCalendar, useImportContacts, useImportDatabase, useImportDatabaseRows, useInstallSkillPack, useInvalidateAfterTransfer, useInvalidateProjects, useInvalidateStorage, useInviteContacts, useIsSlow, useIsWorkspaceOwner, useKeepDocumentsOffline, useLinkContact, useMailAccounts, useMailAttachmentText, useMailCache, useMailClient, useMailDraftCompose, useMailDraftEditor, useMailDraftReplaced, useMailFolders, useMailMessage, useMailMessages, useMailOnline, useMailPolicy, useMailProjects, useMailUnlock, useMailboxFolders, useMailboxSyncProgress, useMarkChatRead, useMarkDocumentShared, useMarkNotificationsRead, useMcpTools, useMentionCandidates, useMessageTimer, useMoveEvent, useMoveWorkspaceToProject, useMyConnectors, useNotificationPreferences, useNotifications, useNotifyConversation, useOfflineDocumentIds, useOpenSelectedWorkspace, useOpenViewerDocumentId, usePassageQuotes, usePasswordChange, usePasswordChangeForm, usePendingContacts, usePendingSyncCounts, usePendingSyncItems, usePeople, usePeopleSearch, usePlanQuote, usePlanWork, usePlanWorkspaceTransfer, usePreviewProjectPlanChange, useProcessingTask, useProcessingTasks, useProducts, useProjectBillingPortal, useProjectConversationUsage, useProjectEvents, usePublishCalendar, useRefreshCalendar, useRefreshConnectorsOnRunEnd, useRefreshProject, useRelatedDocuments, useRemoveChatMember, useRemoveDocTags, useRemoveDocumentsOffline, useRemoveWorkspaceMembers, useRenameChat, useRenameFolder, useRequestEmailChange, useRequestWorkspaceAccess, useRespondToEvent, useResumeCalendarAccountConnect, useResumeWorkspaceTransfer, useRevokeAgentAccess, useRooms, useRunConversation, useRunWorkflow, useSaveAgentConfig, useSaveBookingPage, useSaveCalendarSettings, useSaveConfig, useSaveConfigField, useSaveMailDraft, useSaveSkill, useSearchContacts, useSearchDatabaseRows, useSearchFacts, useSemanticSearch, useSendBackStep, useSendMail, useSessions, useSetDeploymentHouseTemplate, useSetSkillVisibility, useSetWorkspaceHouseTemplate, useSetWorkspaceMemberRoles, useShareCalendar, useShellWorkspaces, useSignOut, useSkillSource, useSkills, useSlackConnection, useStartAgentSession, useStartCalendarAccountOAuth, useStartTaskQuery, useStartWorkspaceTransfer, useStorageActions, useStorageItemNames, useStorageItems, useStorageProjects, useStorageSnapshots, useStreamHandlers, useSubscribeCalendar, useSwitchWorkspace, useSyncAccountsOnOpen, useSyncCalendarAccount, useTerminateSession, useThinkingContent, useThreadDocument, useTriggerDriveSync, useTriggerMailboxSync, useUnarchiveWorkspace, useUnreadByPeer, useUnshareCalendar, useUpdateCalendar, useUpdateCalendarAccount, useUpdateContact, useUpdateConversation, useUpdateDatabase, useUpdateDatabaseRow, useUpdateDocTag, useUpdateDocuments, useUpdateEvent, useUpdateFact, useUpdateMailMessage, useUpdateProjectAddonSettings, useUpdateProjectFields, useUpdateProjectNextPeriodAddons, useUpdateWorkflow, useUpdateWorkspace, useUploadDocuments, useUploadFiles, useUploadFromUrls, useUploadSkillFiles, useUploadUrls, useVideoRecorder, useWorkItems, useWorkNotifications, useWorkflowRuns, useWorkflows, useWorkspaceArchive, useWorkspaceDocs, useWorkspaceExportDownload, useWorkspaceNotificationLevel, useWorkspaceProcessing, useWorkspaceRole, useWorkspaceTransfer, useWorkspaceTransfers, useWorkspaceTrash, useWorkspaceUsers, userDisplayName, userInitials, waitForResponseId, wipeOfflineDocuments, withRelativePath, workflowStepOf, workspaceHouseTemplateId };
14269
+ export { AGENT_CONTROL_COMMANDS, AGGREGATE_FIELDS, ALLOWED_PORTAL_ORIGINS, ARCHIVE_POLL_MS, ASSISTANT_MENTION_LABEL, AUTO_CHAT_MODEL, ActivityFeed, AiActionCard, AiAnswer, AppleIcon, ArbiBotIcon, ArbiHost2 as ArbiHost, ArbiWebSocketProvider, ArtifactCanvas, BOX_SEAT_REFUSED, BOX_SEAT_REFUSED_ACTION, BOX_SEAT_REFUSED_TITLE, BUILTIN_DATA_SOURCES, CONVERSATION_SWITCH_MEASURE, ChatBubble, CitationRenderer, CommandPalette, CommandPaletteProvider, ConversationList, ConversationScope, DATABASE_RELATION_PICK_LIMIT, DATABASE_ROWS_PAGE, DEFAULT_ASPECT_OPTIONS, DEFAULT_CONVERSATIONS_SOURCE_LABELS, DEFAULT_DATABASE_SOURCE_LABELS, DEFAULT_DOCUMENTS_SOURCE_LABELS, DEFAULT_PASSWORD_CHANGE_FORM_MESSAGES, DEFAULT_PROJECTS_SOURCE_LABELS, DEFAULT_USAGE_SOURCE_LABELS, DEFAULT_WORKSPACES_SOURCE_LABELS, DateSeparator, DmAvatar, DmComposer, DocQaPanel, DocSearch, DocumentCardMenu, DocumentReview, DraftTitleControls, EMPTY_GROUP_LABEL, FIRST_TOKEN_MEASURE, FileIcon, GitHubIcon, ImageCropModal, ImageCropper, LIVE_UPDATE_TYPES, LinkedInIcon, MAIL_DRAFT_REPLACED_EVENT, MAX_DASHBOARD_SPEC_CHARS, MAX_SERIES, MIN_NARRATION_DWELL_MS, MODEL_GROUP_LABELS, MailOfflineUnavailableError, MessageArtifactCard, PENDING_SYNC_PREDICATE, POLL_EVERY_MS, PhotoCapture, RUN_WINDOW_MS, SIGNATURE_NOTIFICATION_TYPES, SLOW_AFTER_MS, STILL_WORKING, StorageActionError, TRANSFER_POLL_MS, TaskThreadPendingError, TypingIndicator, UPLOAD_ACCEPT, UPLOAD_MAX_FILE_SIZE, VideoCapture, VoiceNoteRecorder, WORK_NOTIFICATION_LABELS, __resetPendingFinalCommitsForTests, __resetStreamingTokenBufferForTests, accountPath, addAssistantMessageToCache, addUserMessageToCache, adoptNewChatDocument, aggregateDataset, aliasTakenMessage, allConversationThreads, annotateThread, announceMailDraftReplaced, appendTokenToMessage, applyConversationEvent, applyFinalContextToMessage, applyLiveUpdate, applyNotificationRow, applyOptimisticDocumentEdit, applyOutputItemToMessage, applyTaskEvent, arbiMailClient, archiveName, archivedWorkspaceMessage, bindThreadDocument, boundDocumentOf, bucketOf, bucketRange, buildDocumentMetadataRows, buildMentionCandidates, buildPendingFirstTurn, buildPendingSyncItem, buildWorkspaceArchive, cacheThreadBinding, cachedAssistantMode, cachedMentionCandidates, cachedQuotaUsedUp, calendarNotificationMeta, callNotificationMeta, captureFrameAsBlob, clearLoadingState, clearUserInputRequest, commitFinalMessage, completeQueuedUserMessageByContent, connectOAuthCalendarAccount, connectorErrorStatus, connectorReturnTo, createConversationsSource, createDataSourceRegistry, createDatabaseSource, createDocumentsSource, createMailClient, createMemoryDashboardStore, createProjectsSource, createSkillPack, createStreamHandlers, createUsageSource, createWorkspaceSwitch, createWorkspacesSource, cropImage, dayKey, defaultMailAlias, defineRowsSource, deploymentUserMeta, describeActivity, describeCalendarNotification, describeServerNotification, discardStreamingTokensForMessage, disconnectAttachedRun, documentActivityMeta, documentActivityPhrase, documentDisplayName, docxMentionMeta, downloadRecoveryFile, ensureAssistantMessageLoading, extractZipFile, fallbackFileName, fileAttachment, filesFromDrop, fillTimeGaps, filterRows, flushStreamingTokens, forgetUploadedDocumentFolder, formatConfigValidationError, formatIdentityPrice, getInterjectionText, getNotificationTypeMeta, getOfflineDocument, getOrphanedLastMessage, getRelatedLabels, getRelatedTotal, getRunStartedAt, getThreadsQueryKey, getWorkspaceActionText, getWorkspaceKind, getWorkspaceSentPhrase, hasPendingFinalCommit, hasVideoTrack, identityStepFor, inputRequestTitle, invalidateCalendarEvents, invalidateCalendars, invalidateConversationActivity, isActivityKey, isAliasTakenError, isArchiveMoving, isCommentToPeople, isDeploymentAdmin, isDeploymentUserNotification, isFullConfig, isMessageRunning, isNotificationRow, isOfflineReadableArbiQuery, isOrphanedUserMessage, isQueuedCalendarWrite, isReplayableArbiMutation, isRestorableArbiQueryOnline, isSignatureNotificationType, isTableViewOf, isTransferFinished, isTransferResumable, isWorkspaceArchivedError, isWorkspaceNotificationType, isZipFile, loadOfflineDocument, mailDraftIdFromContent, mailJson, markMessageAsFailed, markNarrationSettled, migrateLegacyThreadDocuments, mountDiditVerification, nextAliasSuggestion, notificationUserName, openAccessRequest, parseActivityContent, parseDashboardSpec, parseDeleteAccountBlockers, pendingChatModelSave, peopleDirectory, personOfUser, pickRecentWorkspaces, prepareUploadFiles, queryOfChart, recordsOf, redlineStats, refuseChatWhenOffline, registerArbiMutationDefaults, registerAttachedRun, removeSettledNarration, requestPersistentStorage, resetCalendarAccountSyncState, resetMessageContent, resolveActiveWorkspace, resolveConfigModel, resolveReplyTarget, rollbackOptimisticDocumentEdit, safePortalUrl, serializeDashboardSpec, serverNotificationBellEntry, setMessageContent, setUserInputRequest, signatureNotificationPhrase, signatureRequestMeta, subscribeDocumentReads, supportsHouseTemplates, textToArtifact, threadBinding, threadEndingAtContains, titleFromQuestion, toChatCitations, toNotificationPreferences, toRedlineMarkdown, toShellWorkspace, updateMessageWithMetadata, updateUserMessageInCache, updateUserMessageStateInCache, uploadFolderOf, uploadedDocumentFolder, useActOnStep, useActiveConfigId, useAddChatMembers, useAddDatabaseRows, useAddHolidayCalendar, useAddProjectAddonBlock, useAddWorkspaceMembers, useAddonQuote, useAgentChats, useAgentConfig, useAgentDmStatus, useAgentModels, useAgentRunControl, useAgentSession, useAgentWorkspaces, useAiTask, useAnswerAgentQuestion, useApplyChatModel, useArbiConnected, useArbiShellWorkspaces, useArbiWebSocket, useArbiWsContext, useArbiWsMessage, useArbiWsStatus, useArchiveProgressPolling, useArchiveWorkspace, useAskAgain, useAssignDocTags, useAuthorizeLimits, useAutoSendDraft, useBookingPages, useBranchNavigation, useCalDavProfiles, useCalendarAccounts, useCalendarEvent, useCalendarEventByUid, useCalendarEvents, useCalendarInvitations, useCalendarOutbox, useCalendarOverlays, useCalendarSettings, useCalendarShares, useCalendarSupport, useCalendars, useCameraStream, useCanEditShared, useCancelDriveSync, useCancelMailboxSync, useCancelManyPendingSync, useCancelProjectSubscription, useCancelWorkspaceTransfer, useChangeProjectPlan, useChargeWatch, useChatArrivals, useChatPost, useChatSummaries, useChatThread, useChatUnreadTotal, useChats, useClaimNativeAlias, useCloseAgentSession, useCommandPalette, useConfigSchema, useConfirmEmailChange, useConnectCalDavAccount, useConnectMailAccount, useConnectOAuthAccount, useConnectRunStream, useConnectorAutoSync, useConnectorCatalog, useConnectorVendorVisibility, useContacts, useConversation, useConversationActions, useConversationActivity, useConversationData, useConversationDocuments, useConversationIsShared, useConversationItems, useConversationPendingAuth, useConversationSearch, useConversationTurn, useConversationUsage, useCreateAgent, useCreateCalendar, useCreateContact, useCreateDatabase, useCreateEvent, useCreateFact, useCreateFacts, useCreateGroupChat, useCreateProject, useCreateProjectCheckout, useCreateRoom, useCreateWork, useCreateWorkflow, useCreateWorkspace, useCurrentSessionId, useCurrentWorkspace, useDashboardStore, useDataSources, useDatabase, useDatabaseAggregate, useDatabaseDashboardStore, useDatabaseRows, useDatabases, useDecideCounter, useDeleteAccount, useDeleteAccountFlow, useDeleteBookingPage, useDeleteCalendar, useDeleteChatMessage, useDeleteConfig, useDeleteContact, useDeleteConversation, useDeleteDashboard, useDeleteDatabase, useDeleteDatabaseRows, useDeleteDocuments, useDeleteEvent, useDeleteFact, useDeleteMessage, useDeleteNotifications, useDeleteProject, useDeleteSkill, useDeleteWorkflow, useDeleteWorkspaces, useDisconnectCalendarAccount, useDisconnectConnector, useDisconnectMailAccount, useDisconnectSlack, useDismissedTips, useDocumentAutoAdd, useDocumentHostActions, useDocumentPendingSync, useDocumentThumbnails, useDocumentsSupport, useDownloadDocuments, useDriveFolderChildren, useDriveFolderDocCount, useDriveFolders, useDriveSyncEstimate, useDriveSyncProgress, useEmailChange, useEnableDriveSync, useEnableMailboxSync, useExportDatabase, useFacts, useFetchCalendarEvent, useFilteredProjects, useFinaliseTranslation, useFindTime, useFollowThread, useFreeBusy, useGenerateAgentAvatar, useGenerateDocTags, useGrantAgentAccess, useHolidayCountries, useHouseTemplateCandidates, useIdentityVerification, useIdentityVerificationFlow, useImportCalendar, useImportContacts, useImportDatabase, useImportDatabaseRows, useInstallSkillPack, useInvalidateAfterTransfer, useInvalidateProjects, useInvalidateStorage, useInviteContacts, useIsSlow, useIsWorkspaceOwner, useKeepDocumentsOffline, useLinkContact, useMailAccounts, useMailAttachmentText, useMailCache, useMailClient, useMailDraftCompose, useMailDraftEditor, useMailDraftReplaced, useMailFolders, useMailMessage, useMailMessages, useMailOnline, useMailPolicy, useMailProjects, useMailUnlock, useMailboxFolders, useMailboxSyncProgress, useMarkChatRead, useMarkDocumentShared, useMarkNotificationsRead, useMcpTools, useMentionCandidates, useMessageTimer, useMoveEvent, useMoveWorkspaceToProject, useMyConnectors, useNotificationPreferences, useNotifications, useNotifyConversation, useOfflineDocumentIds, useOpenSelectedWorkspace, useOpenViewerDocumentId, usePanelDataset, usePassageQuotes, usePasswordChange, usePasswordChangeForm, usePendingContacts, usePendingSyncCounts, usePendingSyncItems, usePeople, usePeopleSearch, usePlanQuote, usePlanWork, usePlanWorkspaceTransfer, usePreviewProjectPlanChange, useProcessingTask, useProcessingTasks, useProducts, useProjectBillingPortal, useProjectConversationUsage, useProjectEvents, usePublishCalendar, useRefreshCalendar, useRefreshConnectorsOnRunEnd, useRefreshProject, useRelatedDocuments, useRemoveChatMember, useRemoveDocTags, useRemoveDocumentsOffline, useRemoveWorkspaceMembers, useRenameChat, useRenameFolder, useRequestEmailChange, useRequestWorkspaceAccess, useRespondToEvent, useResumeCalendarAccountConnect, useResumeWorkspaceTransfer, useRevokeAgentAccess, useRooms, useRunConversation, useRunWorkflow, useSaveAgentConfig, useSaveBookingPage, useSaveCalendarSettings, useSaveConfig, useSaveConfigField, useSaveDashboard, useSaveMailDraft, useSaveSkill, useSavedDashboards, useSearchContacts, useSearchDatabaseRows, useSearchFacts, useSemanticSearch, useSendBackStep, useSendMail, useSessions, useSetDeploymentHouseTemplate, useSetSkillVisibility, useSetWorkspaceHouseTemplate, useSetWorkspaceMemberRoles, useShareCalendar, useShellWorkspaces, useSignOut, useSkillSource, useSkills, useSlackConnection, useStartAgentSession, useStartCalendarAccountOAuth, useStartTaskQuery, useStartWorkspaceTransfer, useStorageActions, useStorageItemNames, useStorageItems, useStorageProjects, useStorageSnapshots, useStreamHandlers, useSubscribeCalendar, useSwitchWorkspace, useSyncAccountsOnOpen, useSyncCalendarAccount, useTerminateSession, useThinkingContent, useThreadDocument, useTriggerDriveSync, useTriggerMailboxSync, useUnarchiveWorkspace, useUnreadByPeer, useUnshareCalendar, useUpdateCalendar, useUpdateCalendarAccount, useUpdateContact, useUpdateConversation, useUpdateDatabase, useUpdateDatabaseRow, useUpdateDocTag, useUpdateDocuments, useUpdateEvent, useUpdateFact, useUpdateMailMessage, useUpdateProjectAddonSettings, useUpdateProjectFields, useUpdateProjectNextPeriodAddons, useUpdateWorkflow, useUpdateWorkspace, useUploadDocuments, useUploadFiles, useUploadFromUrls, useUploadSkillFiles, useUploadUrls, useVideoRecorder, useWorkItems, useWorkNotifications, useWorkflowRuns, useWorkflows, useWorkspaceArchive, useWorkspaceDocs, useWorkspaceExportDownload, useWorkspaceNotificationLevel, useWorkspaceProcessing, useWorkspaceRole, useWorkspaceTransfer, useWorkspaceTransfers, useWorkspaceTrash, useWorkspaceUsers, userDisplayName, userInitials, viewsOfTable, waitForResponseId, wipeOfflineDocuments, withRelativePath, workflowStepOf, workspaceHouseTemplateId };
13107
14270
  //# sourceMappingURL=index.js.map
13108
14271
  //# sourceMappingURL=index.js.map