@arbidocs/react 0.5.110 → 0.5.112
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/PdfViewerImpl-QUSDLNNM.cjs +380 -0
- package/dist/PdfViewerImpl-QUSDLNNM.cjs.map +1 -0
- package/dist/{PdfViewer.d-bQH9yxFg.d.cts → PdfViewerImpl.d-B28hLEuj.d.ts} +8 -1
- package/dist/account/client.js +96 -0
- package/dist/account/client.js.map +7 -0
- package/dist/account/delete.js +70 -0
- package/dist/account/delete.js.map +7 -0
- package/dist/account/didit.js +34 -0
- package/dist/account/didit.js.map +7 -0
- package/dist/account/dismissed-tips.js +33 -0
- package/dist/account/dismissed-tips.js.map +7 -0
- package/dist/account/email.js +84 -0
- package/dist/account/email.js.map +7 -0
- package/dist/account/entitlements.js +47 -0
- package/dist/account/entitlements.js.map +7 -0
- package/dist/account/identity.js +270 -0
- package/dist/account/identity.js.map +7 -0
- package/dist/account/index.js +93 -0
- package/dist/account/index.js.map +7 -0
- package/dist/account/notifications.js +59 -0
- package/dist/account/notifications.js.map +7 -0
- package/dist/account/password.js +103 -0
- package/dist/account/password.js.map +7 -0
- package/dist/account/profile.js +116 -0
- package/dist/account/profile.js.map +7 -0
- package/dist/account/recovery.js +13 -0
- package/dist/account/recovery.js.map +7 -0
- package/dist/account/relevance.js +82 -0
- package/dist/account/relevance.js.map +7 -0
- package/dist/account/sessions.js +37 -0
- package/dist/account/sessions.js.map +7 -0
- package/dist/account/settings.js +39 -0
- package/dist/account/settings.js.map +7 -0
- package/dist/account/table-views.js +16 -0
- package/dist/account/table-views.js.map +7 -0
- package/dist/ai/AiAnswer.js +83 -0
- package/dist/ai/AiAnswer.js.map +7 -0
- package/dist/ai/AiMarkdown.js +40 -0
- package/dist/ai/AiMarkdown.js.map +7 -0
- package/dist/ai/ArtifactCanvas.js +193 -0
- package/dist/ai/ArtifactCanvas.js.map +7 -0
- package/dist/ai/CitationRenderer.js +413 -0
- package/dist/ai/CitationRenderer.js.map +7 -0
- package/dist/{chunk-WL2Y2T47.js → ai/MarkdownRenderer.js} +35 -101
- package/dist/ai/MarkdownRenderer.js.map +7 -0
- package/dist/ai/MessageArtifactCard.js +75 -0
- package/dist/ai/MessageArtifactCard.js.map +7 -0
- package/dist/ai/PassageCard.js +79 -0
- package/dist/ai/PassageCard.js.map +7 -0
- package/dist/ai/engine.js +110 -0
- package/dist/ai/engine.js.map +7 -0
- package/dist/ai/index.js +63 -0
- package/dist/ai/index.js.map +7 -0
- package/dist/ai/markdown-base-components.js +37 -0
- package/dist/ai/markdown-base-components.js.map +7 -0
- package/dist/ai/markdown-streaming-context.js +6 -0
- package/dist/ai/markdown-streaming-context.js.map +7 -0
- package/dist/{chunk-VSCU7K4V.js → ai/normalize-citations.js} +12 -19
- package/dist/ai/normalize-citations.js.map +7 -0
- package/dist/ai/redline.js +41 -0
- package/dist/ai/redline.js.map +7 -0
- package/dist/ai/split-markdown-blocks.js +40 -0
- package/dist/ai/split-markdown-blocks.js.map +7 -0
- package/dist/{chunk-UW2SGTI5.js → ai/stored-markdown.js} +41 -93
- package/dist/ai/stored-markdown.js.map +7 -0
- package/dist/annotations/AnnotationPageOverlay.js +807 -0
- package/dist/annotations/AnnotationPageOverlay.js.map +7 -0
- package/dist/annotations/AnnotationToolbar.js +398 -0
- package/dist/annotations/AnnotationToolbar.js.map +7 -0
- package/dist/annotations/FreezeDialog.js +170 -0
- package/dist/annotations/FreezeDialog.js.map +7 -0
- package/dist/annotations/ProductionDialog.js +354 -0
- package/dist/annotations/ProductionDialog.js.map +7 -0
- package/dist/annotations/controller.js +49 -0
- package/dist/annotations/controller.js.map +7 -0
- package/dist/annotations/freeze/browser.js +21 -0
- package/dist/annotations/freeze/browser.js.map +7 -0
- package/dist/annotations/freeze/bundle.js +201 -0
- package/dist/annotations/freeze/bundle.js.map +7 -0
- package/dist/annotations/freeze/coords.js +37 -0
- package/dist/annotations/freeze/coords.js.map +7 -0
- package/dist/annotations/freeze/freeze.js +261 -0
- package/dist/annotations/freeze/freeze.js.map +7 -0
- package/dist/annotations/freeze/hash.js +28 -0
- package/dist/annotations/freeze/hash.js.map +7 -0
- package/dist/annotations/freeze/index-page.js +78 -0
- package/dist/annotations/freeze/index-page.js.map +7 -0
- package/dist/annotations/freeze/index.d.ts +1 -1
- package/dist/annotations/freeze/index.js +28 -22
- package/dist/annotations/freeze/index.js.map +7 -1
- package/dist/annotations/freeze/raster.js +208 -0
- package/dist/annotations/freeze/raster.js.map +7 -0
- package/dist/annotations/freeze/stamp.js +117 -0
- package/dist/annotations/freeze/stamp.js.map +7 -0
- package/dist/annotations/freeze/types.js +14 -0
- package/dist/annotations/freeze/types.js.map +7 -0
- package/dist/annotations/freeze/vector.js +283 -0
- package/dist/annotations/freeze/vector.js.map +7 -0
- package/dist/annotations/geometry.js +81 -0
- package/dist/annotations/geometry.js.map +7 -0
- package/dist/annotations/index.js +125 -6
- package/dist/annotations/index.js.map +7 -1
- package/dist/annotations/merge.js +53 -0
- package/dist/annotations/merge.js.map +7 -0
- package/dist/{chunk-T3USOSVN.js → annotations/model.js} +23 -16
- package/dist/annotations/model.js.map +7 -0
- package/dist/annotations/overlay-geometry.js +41 -0
- package/dist/annotations/overlay-geometry.js.map +7 -0
- package/dist/annotations/redaction-log.js +33 -0
- package/dist/annotations/redaction-log.js.map +7 -0
- package/dist/annotations/selection-marks.js +122 -0
- package/dist/annotations/selection-marks.js.map +7 -0
- package/dist/annotations/state.js +140 -0
- package/dist/annotations/state.js.map +7 -0
- package/dist/annotations/store.js +49 -0
- package/dist/annotations/store.js.map +7 -0
- package/dist/annotations/useAnnotationLayer.js +306 -0
- package/dist/annotations/useAnnotationLayer.js.map +7 -0
- package/dist/annotations/useAnnotationShortcuts.js +31 -0
- package/dist/annotations/useAnnotationShortcuts.js.map +7 -0
- package/dist/annotations/useTextSelectionMarks.js +100 -0
- package/dist/annotations/useTextSelectionMarks.js.map +7 -0
- package/dist/artifacts/artifact-kind.js +19 -0
- package/dist/artifacts/artifact-kind.js.map +7 -0
- package/dist/artifacts/index.cjs +13 -13
- package/dist/artifacts/index.js +89 -571
- package/dist/artifacts/index.js.map +7 -1
- package/dist/{chunk-WUTL62MC.js → artifacts/normalize-markdown.js} +12 -14
- package/dist/artifacts/normalize-markdown.js.map +7 -0
- package/dist/artifacts/redline-core.js +12 -3
- package/dist/artifacts/redline-core.js.map +7 -1
- package/dist/{chunk-74N436VK.js → artifacts/redline-diff.js} +10 -9
- package/dist/artifacts/redline-diff.js.map +7 -0
- package/dist/artifacts/redline-engine.js +14 -0
- package/dist/artifacts/redline-engine.js.map +7 -0
- package/dist/artifacts/renderArtifactMarkdown.js +9 -0
- package/dist/artifacts/renderArtifactMarkdown.js.map +7 -0
- package/dist/artifacts/useArtifactEditSession.js +183 -0
- package/dist/artifacts/useArtifactEditSession.js.map +7 -0
- package/dist/artifacts/useArtifactSession.js +173 -0
- package/dist/artifacts/useArtifactSession.js.map +7 -0
- package/dist/artifacts/useArtifactSource.js +16 -0
- package/dist/artifacts/useArtifactSource.js.map +7 -0
- package/dist/artifacts/useArtifactText.js +78 -0
- package/dist/artifacts/useArtifactText.js.map +7 -0
- package/dist/artifacts/useRedline.js +65 -0
- package/dist/artifacts/useRedline.js.map +7 -0
- package/dist/artifacts/useStreamedArtifact.js +74 -0
- package/dist/artifacts/useStreamedArtifact.js.map +7 -0
- package/dist/artifacts/versions.js +68 -0
- package/dist/artifacts/versions.js.map +7 -0
- package/dist/billing.js +200 -0
- package/dist/billing.js.map +7 -0
- package/dist/boot-timeout.js +19 -0
- package/dist/boot-timeout.js.map +7 -0
- package/dist/calendar/accounts.js +213 -0
- package/dist/calendar/accounts.js.map +7 -0
- package/dist/calendar/hooks.js +409 -0
- package/dist/calendar/hooks.js.map +7 -0
- package/dist/calendar/index.js +31 -0
- package/dist/calendar/index.js.map +7 -0
- package/dist/calendar/keys.js +5 -0
- package/dist/calendar/keys.js.map +7 -0
- package/dist/calendar/offline/outbox.js +231 -0
- package/dist/calendar/offline/outbox.js.map +7 -0
- package/dist/calendar/offline/runtime.js +109 -0
- package/dist/calendar/offline/runtime.js.map +7 -0
- package/dist/calendar/offline/support.js +41 -0
- package/dist/calendar/offline/support.js.map +7 -0
- package/dist/calendar/support.js +34 -0
- package/dist/calendar/support.js.map +7 -0
- package/dist/calls/actions.js +226 -0
- package/dist/calls/actions.js.map +7 -0
- package/dist/calls/events.js +138 -0
- package/dist/calls/events.js.map +7 -0
- package/dist/calls/gate.js +19 -0
- package/dist/calls/gate.js.map +7 -0
- package/dist/calls/hooks.js +115 -0
- package/dist/calls/hooks.js.map +7 -0
- package/dist/calls/in-call-chat.js +132 -0
- package/dist/calls/in-call-chat.js.map +7 -0
- package/dist/calls/index.js +24 -0
- package/dist/calls/index.js.map +7 -0
- package/dist/calls/keys.js +17 -0
- package/dist/calls/keys.js.map +7 -0
- package/dist/calls/livekit/index.cjs +48 -48
- package/dist/calls/livekit/index.js +6 -958
- package/dist/calls/livekit/index.js.map +7 -1
- package/dist/calls/livekit/room.js +98 -0
- package/dist/calls/livekit/room.js.map +7 -0
- package/dist/calls/livekit/useCallRecorder.js +219 -0
- package/dist/calls/livekit/useCallRecorder.js.map +7 -0
- package/dist/calls/livekit/useCallTranscriber.js +309 -0
- package/dist/calls/livekit/useCallTranscriber.js.map +7 -0
- package/dist/calls/livekit/useHostMuteNotice.js +29 -0
- package/dist/calls/livekit/useHostMuteNotice.js.map +7 -0
- package/dist/calls/livekit/useInCallChat.js +161 -0
- package/dist/calls/livekit/useInCallChat.js.map +7 -0
- package/dist/calls/livekit/useWebinar.js +239 -0
- package/dist/calls/livekit/useWebinar.js.map +7 -0
- package/dist/calls/meeting-chat.js +149 -0
- package/dist/calls/meeting-chat.js.map +7 -0
- package/dist/calls/moderation.js +50 -0
- package/dist/calls/moderation.js.map +7 -0
- package/dist/calls/open-meeting-chat.js +29 -0
- package/dist/calls/open-meeting-chat.js.map +7 -0
- package/dist/calls/read-only.js +24 -0
- package/dist/calls/read-only.js.map +7 -0
- package/dist/calls/recording-media.js +218 -0
- package/dist/calls/recording-media.js.map +7 -0
- package/dist/calls/recording-playback.js +260 -0
- package/dist/calls/recording-playback.js.map +7 -0
- package/dist/calls/recording.js +268 -0
- package/dist/calls/recording.js.map +7 -0
- package/dist/calls/save-to-thread.js +80 -0
- package/dist/calls/save-to-thread.js.map +7 -0
- package/dist/calls/session.js +134 -0
- package/dist/calls/session.js.map +7 -0
- package/dist/calls/transcript-format.js +147 -0
- package/dist/calls/transcript-format.js.map +7 -0
- package/dist/calls/transcription.js +101 -0
- package/dist/calls/transcription.js.map +7 -0
- package/dist/calls/webinar.js +71 -0
- package/dist/calls/webinar.js.map +7 -0
- package/dist/charge-watch.js +71 -0
- package/dist/charge-watch.js.map +7 -0
- package/dist/chat/ChatBubble.js +146 -0
- package/dist/chat/ChatBubble.js.map +7 -0
- package/dist/chat/ConversationScope.js +30 -0
- package/dist/chat/ConversationScope.js.map +7 -0
- package/dist/chat/active-config.js +20 -0
- package/dist/chat/active-config.js.map +7 -0
- package/dist/chat/agent-chat-owner.js +25 -0
- package/dist/chat/agent-chat-owner.js.map +7 -0
- package/dist/chat/chat-artifacts.js +64 -0
- package/dist/chat/chat-artifacts.js.map +7 -0
- package/dist/chat/citations.js +32 -0
- package/dist/chat/citations.js.map +7 -0
- package/dist/chat/config-model.js +10 -0
- package/dist/chat/config-model.js.map +7 -0
- package/dist/chat/conversation-cache.js +676 -0
- package/dist/chat/conversation-cache.js.map +7 -0
- package/dist/chat/conversation-events.js +57 -0
- package/dist/chat/conversation-events.js.map +7 -0
- package/dist/chat/conversation-mentions.js +58 -0
- package/dist/chat/conversation-mentions.js.map +7 -0
- package/dist/chat/conversation-workspace.js +58 -0
- package/dist/chat/conversation-workspace.js.map +7 -0
- package/dist/chat/mentions.js +116 -0
- package/dist/chat/mentions.js.map +7 -0
- package/dist/chat/open-document.js +106 -0
- package/dist/chat/open-document.js.map +7 -0
- package/dist/chat/orphaned.js +44 -0
- package/dist/chat/orphaned.js.map +7 -0
- package/dist/chat/pendingFirstTurn.js +30 -0
- package/dist/chat/pendingFirstTurn.js.map +7 -0
- package/dist/chat/reply-target.js +12 -0
- package/dist/chat/reply-target.js.map +7 -0
- package/dist/chat/run-finished.js +28 -0
- package/dist/chat/run-finished.js.map +7 -0
- package/dist/chat/run-state.js +91 -0
- package/dist/chat/run-state.js.map +7 -0
- package/dist/chat/stream-handlers.js +419 -0
- package/dist/chat/stream-handlers.js.map +7 -0
- package/dist/chat/thread-binding.js +76 -0
- package/dist/chat/thread-binding.js.map +7 -0
- package/dist/chat/thread-document.js +53 -0
- package/dist/chat/thread-document.js.map +7 -0
- package/dist/chat/turn-control.js +79 -0
- package/dist/chat/turn-control.js.map +7 -0
- package/dist/chat/useAgentRunControl.js +36 -0
- package/dist/chat/useAgentRunControl.js.map +7 -0
- package/dist/chat/useAnswerAgentQuestion.js +19 -0
- package/dist/chat/useAnswerAgentQuestion.js.map +7 -0
- package/dist/chat/useAskAgain.js +32 -0
- package/dist/chat/useAskAgain.js.map +7 -0
- package/dist/chat/useAutoSendDraft.js +17 -0
- package/dist/chat/useAutoSendDraft.js.map +7 -0
- package/dist/chat/useBranchNavigation.js +97 -0
- package/dist/chat/useBranchNavigation.js.map +7 -0
- package/dist/chat/useConnectRunStream.js +169 -0
- package/dist/chat/useConnectRunStream.js.map +7 -0
- package/dist/chat/useConversation.js +431 -0
- package/dist/chat/useConversation.js.map +7 -0
- package/dist/chat/useConversationActions.js +662 -0
- package/dist/chat/useConversationActions.js.map +7 -0
- package/dist/chat/useConversationData.js +143 -0
- package/dist/chat/useConversationData.js.map +7 -0
- package/dist/chat/useConversationDocuments.js +41 -0
- package/dist/chat/useConversationDocuments.js.map +7 -0
- package/dist/chat/useConversationSettings.js +78 -0
- package/dist/chat/useConversationSettings.js.map +7 -0
- package/dist/chat/useConversationTurn.js +31 -0
- package/dist/chat/useConversationTurn.js.map +7 -0
- package/dist/chat/useConversationWorkspace.js +12 -0
- package/dist/chat/useConversationWorkspace.js.map +7 -0
- package/dist/chat/useDeleteMessage.js +15 -0
- package/dist/chat/useDeleteMessage.js.map +7 -0
- package/dist/chat/useDocumentAutoAdd.js +73 -0
- package/dist/chat/useDocumentAutoAdd.js.map +7 -0
- package/dist/chat/useMessageTimer.js +39 -0
- package/dist/chat/useMessageTimer.js.map +7 -0
- package/dist/chat/useThinkingContent.js +67 -0
- package/dist/chat/useThinkingContent.js.map +7 -0
- package/dist/chat/useThreadDocument.js +61 -0
- package/dist/chat/useThreadDocument.js.map +7 -0
- package/dist/chat/workflow-run-titles.js +50 -0
- package/dist/chat/workflow-run-titles.js.map +7 -0
- package/dist/{chunk-W2FATOTX.cjs → chunk-3JAEX57E.cjs} +4 -4
- package/dist/{chunk-W2FATOTX.cjs.map → chunk-3JAEX57E.cjs.map} +1 -1
- package/dist/{chunk-HD5H2PPP.cjs → chunk-5TRUFWKT.cjs} +66 -66
- package/dist/{chunk-HD5H2PPP.cjs.map → chunk-5TRUFWKT.cjs.map} +1 -1
- package/dist/{chunk-Z3W4XFWB.cjs → chunk-C72FSQUE.cjs} +3 -3
- package/dist/{chunk-Z3W4XFWB.cjs.map → chunk-C72FSQUE.cjs.map} +1 -1
- package/dist/{chunk-LBAG7KL7.cjs → chunk-FQVNZCTD.cjs} +3 -3
- package/dist/{chunk-LBAG7KL7.cjs.map → chunk-FQVNZCTD.cjs.map} +1 -1
- package/dist/{chunk-RVUGSM65.cjs → chunk-GKGAPU6T.cjs} +44 -44
- package/dist/{chunk-RVUGSM65.cjs.map → chunk-GKGAPU6T.cjs.map} +1 -1
- package/dist/{chunk-7LIMHY56.cjs → chunk-O32T7XRD.cjs} +3 -3
- package/dist/{chunk-7LIMHY56.cjs.map → chunk-O32T7XRD.cjs.map} +1 -1
- package/dist/chunk-PWGSIM3F.cjs +291 -0
- package/dist/chunk-PWGSIM3F.cjs.map +1 -0
- package/dist/chunk-QP3WQSAA.cjs +23 -0
- package/dist/chunk-QP3WQSAA.cjs.map +1 -0
- package/dist/chunk-T5FZICXN.cjs +50 -0
- package/dist/chunk-T5FZICXN.cjs.map +1 -0
- package/dist/{chunk-QF2BW6HZ.cjs → chunk-UDDJIUHJ.cjs} +38 -38
- package/dist/{chunk-QF2BW6HZ.cjs.map → chunk-UDDJIUHJ.cjs.map} +1 -1
- package/dist/{chunk-5HDKL6XB.cjs → chunk-YMB6XUR2.cjs} +57 -57
- package/dist/{chunk-5HDKL6XB.cjs.map → chunk-YMB6XUR2.cjs.map} +1 -1
- package/dist/config/config-hooks.js +209 -0
- package/dist/config/config-hooks.js.map +7 -0
- package/dist/connectivity.js +72 -0
- package/dist/connectivity.js.map +7 -0
- package/dist/connectors/hooks.js +263 -0
- package/dist/connectors/hooks.js.map +7 -0
- package/dist/connectors/index.js +28 -0
- package/dist/connectors/index.js.map +7 -0
- package/dist/contacts.js +100 -0
- package/dist/contacts.js.map +7 -0
- package/dist/conversation-list.js +65 -0
- package/dist/conversation-list.js.map +7 -0
- package/dist/databases.js +195 -0
- package/dist/databases.js.map +7 -0
- package/dist/datasets/aggregate.js +281 -0
- package/dist/datasets/aggregate.js.map +7 -0
- package/dist/datasets/index.js +122 -0
- package/dist/datasets/index.js.map +7 -0
- package/dist/datasets/members.js +27 -0
- package/dist/datasets/members.js.map +7 -0
- package/dist/datasets/panel.js +44 -0
- package/dist/datasets/panel.js.map +7 -0
- package/dist/datasets/registry.js +47 -0
- package/dist/datasets/registry.js.map +7 -0
- package/dist/datasets/rows-source.js +44 -0
- package/dist/datasets/rows-source.js.map +7 -0
- package/dist/datasets/sources/activity.js +83 -0
- package/dist/datasets/sources/activity.js.map +7 -0
- package/dist/datasets/sources/conversations.js +74 -0
- package/dist/datasets/sources/conversations.js.map +7 -0
- package/dist/datasets/sources/database.js +209 -0
- package/dist/datasets/sources/database.js.map +7 -0
- package/dist/datasets/sources/documents.js +93 -0
- package/dist/datasets/sources/documents.js.map +7 -0
- package/dist/datasets/sources/facts.js +56 -0
- package/dist/datasets/sources/facts.js.map +7 -0
- package/dist/datasets/sources/projects.js +117 -0
- package/dist/datasets/sources/projects.js.map +7 -0
- package/dist/datasets/sources/tags.js +67 -0
- package/dist/datasets/sources/tags.js.map +7 -0
- package/dist/datasets/sources/usage.js +268 -0
- package/dist/datasets/sources/usage.js.map +7 -0
- package/dist/datasets/sources/workflows.js +91 -0
- package/dist/datasets/sources/workflows.js.map +7 -0
- package/dist/datasets/sources/workspaces.js +67 -0
- package/dist/datasets/sources/workspaces.js.map +7 -0
- package/dist/datasets/store.js +194 -0
- package/dist/datasets/store.js.map +7 -0
- package/dist/datasets/types.js +14 -0
- package/dist/datasets/types.js.map +7 -0
- package/dist/directmessages/ConversationList.js +148 -0
- package/dist/directmessages/ConversationList.js.map +7 -0
- package/dist/directmessages/DateSeparator.js +8 -0
- package/dist/directmessages/DateSeparator.js.map +7 -0
- package/dist/directmessages/DmAvatar.js +29 -0
- package/dist/directmessages/DmAvatar.js.map +7 -0
- package/dist/directmessages/DmComposer.js +201 -0
- package/dist/directmessages/DmComposer.js.map +7 -0
- package/dist/directmessages/arrivals.js +29 -0
- package/dist/directmessages/arrivals.js.map +7 -0
- package/dist/directmessages/chat-cache.js +192 -0
- package/dist/directmessages/chat-cache.js.map +7 -0
- package/dist/directmessages/grouping.js +26 -0
- package/dist/directmessages/grouping.js.map +7 -0
- package/dist/directmessages/index.js +81 -0
- package/dist/directmessages/index.js.map +7 -0
- package/dist/directmessages/useChats.js +266 -0
- package/dist/directmessages/useChats.js.map +7 -0
- package/dist/directmessages/utils.js +23 -0
- package/dist/directmessages/utils.js.map +7 -0
- package/dist/document-tools/can-annotate.js +7 -0
- package/dist/document-tools/can-annotate.js.map +7 -0
- package/dist/document-tools/core.cjs +99 -99
- package/dist/document-tools/core.d.ts +2 -2
- package/dist/document-tools/core.js +218 -12
- package/dist/document-tools/core.js.map +7 -1
- package/dist/document-tools/document-pdf.js +76 -0
- package/dist/document-tools/document-pdf.js.map +7 -0
- package/dist/document-tools/environment.js +136 -0
- package/dist/document-tools/environment.js.map +7 -0
- package/dist/document-tools/file-shares.js +112 -0
- package/dist/document-tools/file-shares.js.map +7 -0
- package/dist/document-tools/frozen-copy.js +27 -0
- package/dist/document-tools/frozen-copy.js.map +7 -0
- package/dist/document-tools/index.cjs +101 -101
- package/dist/document-tools/index.d.ts +1 -1
- package/dist/document-tools/index.js +26 -148
- package/dist/document-tools/index.js.map +7 -1
- package/dist/document-tools/markup-download.js +51 -0
- package/dist/document-tools/markup-download.js.map +7 -0
- package/dist/document-tools/markup-store.js +138 -0
- package/dist/document-tools/markup-store.js.map +7 -0
- package/dist/document-tools/markup-transfer.js +88 -0
- package/dist/document-tools/markup-transfer.js.map +7 -0
- package/dist/document-tools/production.js +147 -0
- package/dist/document-tools/production.js.map +7 -0
- package/dist/document-tools/saved-signature.js +90 -0
- package/dist/document-tools/saved-signature.js.map +7 -0
- package/dist/document-tools/signature-requests.js +310 -0
- package/dist/document-tools/signature-requests.js.map +7 -0
- package/dist/document-tools/signing.js +127 -0
- package/dist/document-tools/signing.js.map +7 -0
- package/dist/document-tools/useDocumentBytes.js +38 -0
- package/dist/document-tools/useDocumentBytes.js.map +7 -0
- package/dist/document-tools/useDocumentMarkup.js +154 -0
- package/dist/document-tools/useDocumentMarkup.js.map +7 -0
- package/dist/document-tools/useIsOnline.js +13 -0
- package/dist/document-tools/useIsOnline.js.map +7 -0
- package/dist/document-tools/verification.js +60 -0
- package/dist/document-tools/verification.js.map +7 -0
- package/dist/documents/DocumentReview.js +220 -0
- package/dist/documents/DocumentReview.js.map +7 -0
- package/dist/documents/DraftTitleControls.js +41 -0
- package/dist/documents/DraftTitleControls.js.map +7 -0
- package/dist/documents/InlineMicButton.js +90 -0
- package/dist/documents/InlineMicButton.js.map +7 -0
- package/dist/documents/MicRecordingOverlay.js +29 -0
- package/dist/documents/MicRecordingOverlay.js.map +7 -0
- package/dist/documents/MicWaveformIndicator.js +68 -0
- package/dist/documents/MicWaveformIndicator.js.map +7 -0
- package/dist/documents/PhotoCapture.js +120 -0
- package/dist/documents/PhotoCapture.js.map +7 -0
- package/dist/documents/VideoCapture.js +129 -0
- package/dist/documents/VideoCapture.js.map +7 -0
- package/dist/documents/VoiceNoteRecorder.js +166 -0
- package/dist/documents/VoiceNoteRecorder.js.map +7 -0
- package/dist/documents/audio-segmenter.js +63 -0
- package/dist/documents/audio-segmenter.js.map +7 -0
- package/dist/documents/capture-frame.js +21 -0
- package/dist/documents/capture-frame.js.map +7 -0
- package/dist/documents/chunked-recorder.js +190 -0
- package/dist/documents/chunked-recorder.js.map +7 -0
- package/dist/documents/document-download.js +53 -0
- package/dist/documents/document-download.js.map +7 -0
- package/dist/documents/document-fields.js +109 -0
- package/dist/documents/document-fields.js.map +7 -0
- package/dist/documents/documents-cache.js +110 -0
- package/dist/documents/documents-cache.js.map +7 -0
- package/dist/documents/documents-data.js +128 -0
- package/dist/documents/documents-data.js.map +7 -0
- package/dist/documents/documents-loader.js +113 -0
- package/dist/documents/documents-loader.js.map +7 -0
- package/dist/documents/documents-writes.js +448 -0
- package/dist/documents/documents-writes.js.map +7 -0
- package/dist/documents/format-elapsed.js +10 -0
- package/dist/documents/format-elapsed.js.map +7 -0
- package/dist/documents/has-video-track.js +26 -0
- package/dist/documents/has-video-track.js.map +7 -0
- package/dist/documents/index.js +266 -0
- package/dist/documents/index.js.map +7 -0
- package/dist/documents/media-error.js +18 -0
- package/dist/documents/media-error.js.map +7 -0
- package/dist/documents/offline-documents.js +160 -0
- package/dist/documents/offline-documents.js.map +7 -0
- package/dist/documents/pending-sync.js +210 -0
- package/dist/documents/pending-sync.js.map +7 -0
- package/dist/documents/processing-live.js +122 -0
- package/dist/documents/processing-live.js.map +7 -0
- package/dist/documents/processing-order.js +59 -0
- package/dist/documents/processing-order.js.map +7 -0
- package/dist/documents/processing-settle.js +21 -0
- package/dist/documents/processing-settle.js.map +7 -0
- package/dist/documents/related-documents.js +133 -0
- package/dist/documents/related-documents.js.map +7 -0
- package/dist/documents/support.js +29 -0
- package/dist/documents/support.js.map +7 -0
- package/dist/documents/upload-files.js +169 -0
- package/dist/documents/upload-files.js.map +7 -0
- package/dist/documents/useAudioRecorder.js +315 -0
- package/dist/documents/useAudioRecorder.js.map +7 -0
- package/dist/documents/useCameraStream.js +35 -0
- package/dist/documents/useCameraStream.js.map +7 -0
- package/dist/documents/useDocumentThumbnails.js +71 -0
- package/dist/documents/useDocumentThumbnails.js.map +7 -0
- package/dist/documents/useDownloadDocuments.js +90 -0
- package/dist/documents/useDownloadDocuments.js.map +7 -0
- package/dist/documents/usePassageQuotes.js +37 -0
- package/dist/documents/usePassageQuotes.js.map +7 -0
- package/dist/documents/useUploadFiles.js +165 -0
- package/dist/documents/useUploadFiles.js.map +7 -0
- package/dist/documents/useUploadFromUrls.js +63 -0
- package/dist/documents/useUploadFromUrls.js.map +7 -0
- package/dist/documents/useVideoRecorder.js +62 -0
- package/dist/documents/useVideoRecorder.js.map +7 -0
- package/dist/entities/AgentMarkers.js +61 -0
- package/dist/entities/AgentMarkers.js.map +7 -0
- package/dist/entities/DocumentEntity.js +125 -0
- package/dist/entities/DocumentEntity.js.map +7 -0
- package/dist/entities/EntityPill.js +250 -0
- package/dist/entities/EntityPill.js.map +7 -0
- package/dist/entities/ProjectEntity.js +61 -0
- package/dist/entities/ProjectEntity.js.map +7 -0
- package/dist/entities/ShieldIcon.js +49 -0
- package/dist/entities/ShieldIcon.js.map +7 -0
- package/dist/entities/TagEntity.js +79 -0
- package/dist/entities/TagEntity.js.map +7 -0
- package/dist/entities/ThreadVisibilityIcon.js +15 -0
- package/dist/entities/ThreadVisibilityIcon.js.map +7 -0
- package/dist/entities/UserEntity.js +211 -0
- package/dist/entities/UserEntity.js.map +7 -0
- package/dist/entities/VerifiedBadge.js +19 -0
- package/dist/entities/VerifiedBadge.js.map +7 -0
- package/dist/entities/agent-avatar-colors.js +26 -0
- package/dist/entities/agent-avatar-colors.js.map +7 -0
- package/dist/entities/colors.js +64 -0
- package/dist/entities/colors.js.map +7 -0
- package/dist/entities/file-type.js +151 -0
- package/dist/entities/file-type.js.map +7 -0
- package/dist/entities/index.js +100 -0
- package/dist/entities/index.js.map +7 -0
- package/dist/entities/media-type.js +61 -0
- package/dist/entities/media-type.js.map +7 -0
- package/dist/entities/registry.js +385 -0
- package/dist/entities/registry.js.map +7 -0
- package/dist/entities/status.js +43 -0
- package/dist/entities/status.js.map +7 -0
- package/dist/entities/tag-kinds.js +23 -0
- package/dist/entities/tag-kinds.js.map +7 -0
- package/dist/entities/tag-types.js +44 -0
- package/dist/entities/tag-types.js.map +7 -0
- package/dist/entities/vocabulary.js +12 -0
- package/dist/entities/vocabulary.js.map +7 -0
- package/dist/entity-extraction.js +25 -0
- package/dist/entity-extraction.js.map +7 -0
- package/dist/facts-search.js +57 -0
- package/dist/facts-search.js.map +7 -0
- package/dist/facts.js +69 -0
- package/dist/facts.js.map +7 -0
- package/dist/hooks.js +320 -0
- package/dist/hooks.js.map +7 -0
- package/dist/host/ArbiHost.js +24 -0
- package/dist/host/ArbiHost.js.map +7 -0
- package/dist/host/assistant-copy.js +54 -0
- package/dist/host/assistant-copy.js.map +7 -0
- package/dist/host/config.js +9 -0
- package/dist/host/config.js.map +7 -0
- package/dist/host/context.js +10 -0
- package/dist/host/context.js.map +7 -0
- package/dist/host/features.js +144 -0
- package/dist/host/features.js.map +7 -0
- package/dist/host/index.js +12 -0
- package/dist/host/index.js.map +7 -0
- package/dist/{chunk-DPYBZDJB.js → host/merge.js} +7 -7
- package/dist/host/merge.js.map +7 -0
- package/dist/house-template.js +40 -0
- package/dist/house-template.js.map +7 -0
- package/dist/icons/AppleIcon.js +25 -0
- package/dist/icons/AppleIcon.js.map +7 -0
- package/dist/icons/ArbiBotHeadIcon.js +46 -0
- package/dist/icons/ArbiBotHeadIcon.js.map +7 -0
- package/dist/icons/ArbiIcon.js +24 -0
- package/dist/icons/ArbiIcon.js.map +7 -0
- package/dist/icons/AudIcon.js +56 -0
- package/dist/icons/AudIcon.js.map +7 -0
- package/dist/icons/ClaudeIcon.js +28 -0
- package/dist/icons/ClaudeIcon.js.map +7 -0
- package/dist/icons/DocIcon.js +56 -0
- package/dist/icons/DocIcon.js.map +7 -0
- package/dist/icons/EmlIcon.js +57 -0
- package/dist/icons/EmlIcon.js.map +7 -0
- package/dist/icons/FireworksIcon.js +47 -0
- package/dist/icons/FireworksIcon.js.map +7 -0
- package/dist/icons/GeminiIcon.js +37 -0
- package/dist/icons/GeminiIcon.js.map +7 -0
- package/dist/icons/GitHubIcon.js +32 -0
- package/dist/icons/GitHubIcon.js.map +7 -0
- package/dist/icons/GoogleIcon.js +53 -0
- package/dist/icons/GoogleIcon.js.map +7 -0
- package/dist/icons/HtmlIcon.js +56 -0
- package/dist/icons/HtmlIcon.js.map +7 -0
- package/dist/icons/ImgIcon.js +56 -0
- package/dist/icons/ImgIcon.js.map +7 -0
- package/dist/icons/LinkedInIcon.js +25 -0
- package/dist/icons/LinkedInIcon.js.map +7 -0
- package/dist/icons/OpenAIIcon.js +28 -0
- package/dist/icons/OpenAIIcon.js.map +7 -0
- package/dist/icons/PdfIcon.js +56 -0
- package/dist/icons/PdfIcon.js.map +7 -0
- package/dist/icons/ProviderIcon.js +42 -0
- package/dist/icons/ProviderIcon.js.map +7 -0
- package/dist/icons/TxtIcon.js +56 -0
- package/dist/icons/TxtIcon.js.map +7 -0
- package/dist/icons/VidIcon.js +56 -0
- package/dist/icons/VidIcon.js.map +7 -0
- package/dist/icons/XlsIcon.js +56 -0
- package/dist/icons/XlsIcon.js.map +7 -0
- package/dist/icons/arbi-mark.js +5 -0
- package/dist/icons/arbi-mark.js.map +7 -0
- package/dist/icons/colors.js +31 -0
- package/dist/icons/colors.js.map +7 -0
- package/dist/icons/file-type.js +105 -0
- package/dist/icons/file-type.js.map +7 -0
- package/dist/icons/index.js +55 -0
- package/dist/icons/index.js.map +7 -0
- package/dist/imagecrop/ImageCropModal.js +56 -0
- package/dist/imagecrop/ImageCropModal.js.map +7 -0
- package/dist/imagecrop/ImageCropper.js +100 -0
- package/dist/imagecrop/ImageCropper.js.map +7 -0
- package/dist/imagecrop/cropImage.js +43 -0
- package/dist/imagecrop/cropImage.js.map +7 -0
- package/dist/imagecrop/index.js +13 -0
- package/dist/imagecrop/index.js.map +7 -0
- package/dist/index.cjs +1689 -1619
- package/dist/index.cjs.map +1 -1
- package/dist/{index.d-BMhTH98a.d.ts → index.d-CYXcTKYt.d.ts} +1 -0
- package/dist/index.d.ts +38 -8
- package/dist/index.js +702 -17060
- package/dist/index.js.map +7 -1
- package/dist/lazy-chunk.d-B6YDLMKI.d.ts +31 -0
- package/dist/lazy-chunk.js +46 -0
- package/dist/lazy-chunk.js.map +7 -0
- package/dist/lib/collision-padding.js +13 -0
- package/dist/lib/collision-padding.js.map +7 -0
- package/dist/lib/format-friendly-date.js +55 -0
- package/dist/lib/format-friendly-date.js.map +7 -0
- package/dist/lib/format-relative-time.js +52 -0
- package/dist/lib/format-relative-time.js.map +7 -0
- package/dist/lib/markdown-to-text.js +35 -0
- package/dist/lib/markdown-to-text.js.map +7 -0
- package/dist/lib/toast-interaction.js +9 -0
- package/dist/lib/toast-interaction.js.map +7 -0
- package/dist/lib/utils.js +9 -0
- package/dist/lib/utils.js.map +7 -0
- package/dist/mail/client.js +103 -0
- package/dist/mail/client.js.map +7 -0
- package/dist/mail/document-attachment.js +38 -0
- package/dist/mail/document-attachment.js.map +7 -0
- package/dist/mail/filing.js +132 -0
- package/dist/mail/filing.js.map +7 -0
- package/dist/mail/hooks.js +393 -0
- package/dist/mail/hooks.js.map +7 -0
- package/dist/mail/index.js +120 -0
- package/dist/mail/index.js.map +7 -0
- package/dist/mail/offline/changes.js +258 -0
- package/dist/mail/offline/changes.js.map +7 -0
- package/dist/mail/offline/confirm-sign-out.js +37 -0
- package/dist/mail/offline/confirm-sign-out.js.map +7 -0
- package/dist/mail/offline/crypto.js +26 -0
- package/dist/mail/offline/crypto.js.map +7 -0
- package/dist/mail/offline/drafts.js +69 -0
- package/dist/mail/offline/drafts.js.map +7 -0
- package/dist/mail/offline/hooks.js +104 -0
- package/dist/mail/offline/hooks.js.map +7 -0
- package/dist/mail/offline/index.js +48 -0
- package/dist/mail/offline/index.js.map +7 -0
- package/dist/mail/offline/live.js +233 -0
- package/dist/mail/offline/live.js.map +7 -0
- package/dist/mail/offline/mailbox.js +191 -0
- package/dist/mail/offline/mailbox.js.map +7 -0
- package/dist/mail/offline/outbox.js +167 -0
- package/dist/mail/offline/outbox.js.map +7 -0
- package/dist/mail/offline/reads.js +159 -0
- package/dist/mail/offline/reads.js.map +7 -0
- package/dist/mail/offline/runtime.js +100 -0
- package/dist/mail/offline/runtime.js.map +7 -0
- package/dist/mail/offline/settings.js +84 -0
- package/dist/mail/offline/settings.js.map +7 -0
- package/dist/mail/offline/store.js +29 -0
- package/dist/mail/offline/store.js.map +7 -0
- package/dist/mail/offline/sync.js +251 -0
- package/dist/mail/offline/sync.js.map +7 -0
- package/dist/mail/offline/wipe.js +19 -0
- package/dist/mail/offline/wipe.js.map +7 -0
- package/dist/mail/thread-keys.js +53 -0
- package/dist/mail/thread-keys.js.map +7 -0
- package/dist/mail/threads.js +71 -0
- package/dist/mail/threads.js.map +7 -0
- package/dist/mail/useMailClient.js +42 -0
- package/dist/mail/useMailClient.js.map +7 -0
- package/dist/model-connections.js +58 -0
- package/dist/model-connections.js.map +7 -0
- package/dist/notifications/ActivityFeed.js +70 -0
- package/dist/notifications/ActivityFeed.js.map +7 -0
- package/dist/notifications/NotificationBell.js +200 -0
- package/dist/notifications/NotificationBell.js.map +7 -0
- package/dist/notifications/Toaster.js +24 -0
- package/dist/notifications/Toaster.js.map +7 -0
- package/dist/notifications/activity-types.js +65 -0
- package/dist/notifications/activity-types.js.map +7 -0
- package/dist/notifications/bell.js +24 -0
- package/dist/notifications/bell.js.map +7 -0
- package/dist/notifications/calendar-notifications.js +79 -0
- package/dist/notifications/calendar-notifications.js.map +7 -0
- package/dist/notifications/index.js +108 -0
- package/dist/notifications/index.js.map +7 -0
- package/dist/notifications/live.js +28 -0
- package/dist/notifications/live.js.map +7 -0
- package/dist/notifications/notification-types.js +127 -0
- package/dist/notifications/notification-types.js.map +7 -0
- package/dist/{chunk-BF5KW5ZI.js → notifications/notify-store.js} +24 -74
- package/dist/notifications/notify-store.js.map +7 -0
- package/dist/notifications/server-notifications.js +452 -0
- package/dist/notifications/server-notifications.js.map +7 -0
- package/dist/notifications/useNotifications.js +34 -0
- package/dist/notifications/useNotifications.js.map +7 -0
- package/dist/offline-store/network.js +11 -0
- package/dist/offline-store/network.js.map +7 -0
- package/dist/offline-store/store.js +136 -0
- package/dist/offline-store/store.js.map +7 -0
- package/dist/offline-store/wipe.js +8 -0
- package/dist/offline-store/wipe.js.map +7 -0
- package/dist/offline.js +58 -0
- package/dist/offline.js.map +7 -0
- package/dist/people.js +122 -0
- package/dist/people.js.map +7 -0
- package/dist/projects.js +30 -0
- package/dist/projects.js.map +7 -0
- package/dist/query-client.js +63 -0
- package/dist/query-client.js.map +7 -0
- package/dist/{query-keys.d-ChgpJLPF.d.ts → query-keys.d-B1Am9tIF.d.ts} +1 -1
- package/dist/{chunk-6H3O63TQ.js → query-keys.js} +19 -32
- package/dist/query-keys.js.map +7 -0
- package/dist/query-persist.js +66 -0
- package/dist/query-persist.js.map +7 -0
- package/dist/queued-writes.js +59 -0
- package/dist/queued-writes.js.map +7 -0
- package/dist/remote-control.js +67 -0
- package/dist/remote-control.js.map +7 -0
- package/dist/search/index.js +23 -0
- package/dist/search/index.js.map +7 -0
- package/dist/search/session.js +58 -0
- package/dist/search/session.js.map +7 -0
- package/dist/search/useSemanticSearch.js +82 -0
- package/dist/search/useSemanticSearch.js.map +7 -0
- package/dist/session/chat.js +512 -0
- package/dist/session/chat.js.map +7 -0
- package/dist/session/documents.js +196 -0
- package/dist/session/documents.js.map +7 -0
- package/dist/session/drafts.js +103 -0
- package/dist/session/drafts.js.map +7 -0
- package/dist/session/index.js +123 -0
- package/dist/session/index.js.map +7 -0
- package/dist/session/layout.js +339 -0
- package/dist/session/layout.js.map +7 -0
- package/dist/session/persist.js +106 -0
- package/dist/session/persist.js.map +7 -0
- package/dist/session/session-hooks.js +53 -0
- package/dist/session/session-hooks.js.map +7 -0
- package/dist/session/signed-in.js +36 -0
- package/dist/session/signed-in.js.map +7 -0
- package/dist/session/store.js +166 -0
- package/dist/session/store.js.map +7 -0
- package/dist/session/thread-tabs.js +121 -0
- package/dist/session/thread-tabs.js.map +7 -0
- package/dist/session/ui-state-storage.js +76 -0
- package/dist/session/ui-state-storage.js.map +7 -0
- package/dist/session/workspace.js +77 -0
- package/dist/session/workspace.js.map +7 -0
- package/dist/shell/index.cjs +37 -37
- package/dist/shell/index.js +43 -10
- package/dist/shell/index.js.map +7 -1
- package/dist/skill-pack.js +111 -0
- package/dist/skill-pack.js.map +7 -0
- package/dist/storage.js +186 -0
- package/dist/storage.js.map +7 -0
- package/dist/support/index.js +35 -0
- package/dist/support/index.js.map +7 -0
- package/dist/tags.js +204 -0
- package/dist/tags.js.map +7 -0
- package/dist/ui/DebouncedInput.js +109 -0
- package/dist/ui/DebouncedInput.js.map +7 -0
- package/dist/ui/DictateContext.js +8 -0
- package/dist/ui/DictateContext.js.map +7 -0
- package/dist/ui/IconToggle.js +79 -0
- package/dist/ui/IconToggle.js.map +7 -0
- package/dist/ui/VerifiedToggle.js +38 -0
- package/dist/ui/VerifiedToggle.js.map +7 -0
- package/dist/ui/VisibilityToggle.js +103 -0
- package/dist/ui/VisibilityToggle.js.map +7 -0
- package/dist/ui/avatar.js +40 -0
- package/dist/ui/avatar.js.map +7 -0
- package/dist/ui/badge.js +28 -0
- package/dist/ui/badge.js.map +7 -0
- package/dist/ui/button.js +48 -0
- package/dist/ui/button.js.map +7 -0
- package/dist/ui/card.js +90 -0
- package/dist/ui/card.js.map +7 -0
- package/dist/ui/checkbox.js +22 -0
- package/dist/ui/checkbox.js.map +7 -0
- package/dist/ui/collapsible.js +10 -0
- package/dist/ui/collapsible.js.map +7 -0
- package/dist/ui/command.js +103 -0
- package/dist/ui/command.js.map +7 -0
- package/dist/{chunk-YNNAJJ5Z.js → ui/dialog.js} +30 -68
- package/dist/ui/dialog.js.map +7 -0
- package/dist/{chunk-47CCGUWR.js → ui/dropdown-menu.js} +40 -45
- package/dist/ui/dropdown-menu.js.map +7 -0
- package/dist/ui/hover-card.js +36 -0
- package/dist/ui/hover-card.js.map +7 -0
- package/dist/ui/index.cjs +167 -154
- package/dist/ui/index.d.ts +2 -1
- package/dist/ui/index.js +290 -9
- package/dist/ui/index.js.map +7 -1
- package/dist/ui/input.js +65 -0
- package/dist/ui/input.js.map +7 -0
- package/dist/ui/label.js +16 -0
- package/dist/ui/label.js.map +7 -0
- package/dist/ui/mark-menu.js +300 -0
- package/dist/ui/mark-menu.js.map +7 -0
- package/dist/ui/popover.js +40 -0
- package/dist/ui/popover.js.map +7 -0
- package/dist/ui/portal-container.js +17 -0
- package/dist/ui/portal-container.js.map +7 -0
- package/dist/ui/progress.js +24 -0
- package/dist/ui/progress.js.map +7 -0
- package/dist/ui/radio-group.js +29 -0
- package/dist/ui/radio-group.js.map +7 -0
- package/dist/ui/scroll-area.js +39 -0
- package/dist/ui/scroll-area.js.map +7 -0
- package/dist/ui/select.js +130 -0
- package/dist/ui/select.js.map +7 -0
- package/dist/ui/separator.js +23 -0
- package/dist/ui/separator.js.map +7 -0
- package/dist/ui/slider.js +23 -0
- package/dist/ui/slider.js.map +7 -0
- package/dist/ui/switch.js +28 -0
- package/dist/ui/switch.js.map +7 -0
- package/dist/ui/table.js +75 -0
- package/dist/ui/table.js.map +7 -0
- package/dist/ui/tabs.js +48 -0
- package/dist/ui/tabs.js.map +7 -0
- package/dist/ui/textarea.js +63 -0
- package/dist/ui/textarea.js.map +7 -0
- package/dist/ui/toggle-group.js +43 -0
- package/dist/ui/toggle-group.js.map +7 -0
- package/dist/ui/toggle.js +40 -0
- package/dist/ui/toggle.js.map +7 -0
- package/dist/ui/tooltip.js +215 -0
- package/dist/ui/tooltip.js.map +7 -0
- package/dist/usage-metered.js +8 -0
- package/dist/usage-metered.js.map +7 -0
- package/dist/useArbi.js +16 -0
- package/dist/useArbi.js.map +7 -0
- package/dist/useInstallSkillPack.js +81 -0
- package/dist/useInstallSkillPack.js.map +7 -0
- package/dist/usermenu/UserMenu.js +188 -0
- package/dist/usermenu/UserMenu.js.map +7 -0
- package/dist/usermenu/index.js +5 -0
- package/dist/usermenu/index.js.map +7 -0
- package/dist/users/index.js +15 -0
- package/dist/users/index.js.map +7 -0
- package/dist/users/user-display.js +60 -0
- package/dist/users/user-display.js.map +7 -0
- package/dist/viewers/AudioViewer.js +23 -0
- package/dist/viewers/AudioViewer.js.map +7 -0
- package/dist/viewers/DocxViewer.js +81 -0
- package/dist/viewers/DocxViewer.js.map +7 -0
- package/dist/viewers/ImageViewer.js +31 -0
- package/dist/viewers/ImageViewer.js.map +7 -0
- package/dist/viewers/PdfViewer.cjs +17 -0
- package/dist/viewers/PdfViewer.cjs.map +1 -0
- package/dist/viewers/PdfViewer.d.ts +9 -0
- package/dist/viewers/PdfViewer.js +20 -0
- package/dist/viewers/PdfViewer.js.map +7 -0
- package/dist/viewers/PdfViewerImpl.js +384 -0
- package/dist/viewers/PdfViewerImpl.js.map +7 -0
- package/dist/viewers/VideoViewer.js +31 -0
- package/dist/viewers/VideoViewer.js.map +7 -0
- package/dist/viewers/XlsxViewer.js +102 -0
- package/dist/viewers/XlsxViewer.js.map +7 -0
- package/dist/viewers/index.cjs +79 -653
- package/dist/viewers/index.cjs.map +1 -1
- package/dist/viewers/index.d.ts +3 -1
- package/dist/viewers/index.js +60 -903
- package/dist/viewers/index.js.map +7 -1
- package/dist/viewers/page-scroll.js +59 -0
- package/dist/viewers/page-scroll.js.map +7 -0
- package/dist/viewers/pdf-viewer-constants.js +9 -0
- package/dist/viewers/pdf-viewer-constants.js.map +7 -0
- package/dist/{chunk-PTOP7OHG.js → viewers/pdfjs-polyfills.js} +5 -6
- package/dist/viewers/pdfjs-polyfills.js.map +7 -0
- package/dist/viewers/selection-runs.js +38 -0
- package/dist/viewers/selection-runs.js.map +7 -0
- package/dist/viewers/usePageIntersectionObserver.js +68 -0
- package/dist/viewers/usePageIntersectionObserver.js.map +7 -0
- package/dist/viewers/useProcessedChunks.js +58 -0
- package/dist/viewers/useProcessedChunks.js.map +7 -0
- package/dist/viewers/viewer-zoom.js +163 -0
- package/dist/viewers/viewer-zoom.js.map +7 -0
- package/dist/websocket/ArbiWebSocketProvider.js +207 -0
- package/dist/websocket/ArbiWebSocketProvider.js.map +7 -0
- package/dist/websocket/context.js +14 -0
- package/dist/websocket/context.js.map +7 -0
- package/dist/websocket/hooks.js +30 -0
- package/dist/websocket/hooks.js.map +7 -0
- package/dist/websocket/index.js +22 -0
- package/dist/websocket/index.js.map +7 -0
- package/dist/websocket/live-updates.js +38 -0
- package/dist/websocket/live-updates.js.map +7 -0
- package/dist/websocket/reconnect.js +13 -0
- package/dist/websocket/reconnect.js.map +7 -0
- package/dist/websocket/store.js +58 -0
- package/dist/websocket/store.js.map +7 -0
- package/dist/workforce.js +607 -0
- package/dist/workforce.js.map +7 -0
- package/dist/workspaces/access-request.js +35 -0
- package/dist/workspaces/access-request.js.map +7 -0
- package/dist/workspaces/archive.js +59 -0
- package/dist/workspaces/archive.js.map +7 -0
- package/dist/workspaces/current.js +20 -0
- package/dist/workspaces/current.js.map +7 -0
- package/dist/workspaces/delete-workspaces.js +15 -0
- package/dist/workspaces/delete-workspaces.js.map +7 -0
- package/dist/workspaces/export-archive.js +40 -0
- package/dist/workspaces/export-archive.js.map +7 -0
- package/dist/workspaces/index.js +99 -0
- package/dist/workspaces/index.js.map +7 -0
- package/dist/workspaces/settings.js +45 -0
- package/dist/workspaces/settings.js.map +7 -0
- package/dist/workspaces/shell-workspaces.js +49 -0
- package/dist/workspaces/shell-workspaces.js.map +7 -0
- package/dist/workspaces/switch.js +234 -0
- package/dist/workspaces/switch.js.map +7 -0
- package/dist/workspaces/transfer.js +170 -0
- package/dist/workspaces/transfer.js.map +7 -0
- package/dist/workspaces/useShellWorkspaces.js +86 -0
- package/dist/workspaces/useShellWorkspaces.js.map +7 -0
- package/dist/workspaces/workspace-users.js +65 -0
- package/dist/workspaces/workspace-users.js.map +7 -0
- package/package.json +12 -4
- package/dist/PdfViewer.d-bQH9yxFg.d.ts +0 -55
- package/dist/ProductionDialog.d-CpzslFn0.d.cts +0 -51
- package/dist/annotations/freeze/index.d.cts +0 -205
- package/dist/annotations/index.d.cts +0 -360
- package/dist/artifacts/index.d.cts +0 -476
- package/dist/artifacts/redline-core.d.cts +0 -39
- package/dist/bundle-YNOX7VIL.js +0 -5
- package/dist/bundle-YNOX7VIL.js.map +0 -1
- package/dist/bundle.d-BnCSbHy2.d.cts +0 -85
- package/dist/calls/livekit/index.d.cts +0 -280
- package/dist/chunk-47CCGUWR.js.map +0 -1
- package/dist/chunk-6H3O63TQ.js.map +0 -1
- package/dist/chunk-74N436VK.js.map +0 -1
- package/dist/chunk-APZZQZ6P.js +0 -147
- package/dist/chunk-APZZQZ6P.js.map +0 -1
- package/dist/chunk-BF5KW5ZI.js.map +0 -1
- package/dist/chunk-CPQ3CU4B.js +0 -246
- package/dist/chunk-CPQ3CU4B.js.map +0 -1
- package/dist/chunk-DPYBZDJB.js.map +0 -1
- package/dist/chunk-DQALOQPI.js +0 -2766
- package/dist/chunk-DQALOQPI.js.map +0 -1
- package/dist/chunk-FZJMA32S.js +0 -1011
- package/dist/chunk-FZJMA32S.js.map +0 -1
- package/dist/chunk-H5M7FXLB.js +0 -2057
- package/dist/chunk-H5M7FXLB.js.map +0 -1
- package/dist/chunk-HDCRPPBW.js +0 -75
- package/dist/chunk-HDCRPPBW.js.map +0 -1
- package/dist/chunk-NIKPG4PW.js +0 -1128
- package/dist/chunk-NIKPG4PW.js.map +0 -1
- package/dist/chunk-NNAJLY6B.js +0 -4974
- package/dist/chunk-NNAJLY6B.js.map +0 -1
- package/dist/chunk-OYPKKHXY.js +0 -559
- package/dist/chunk-OYPKKHXY.js.map +0 -1
- package/dist/chunk-P6WLV5UY.js +0 -644
- package/dist/chunk-P6WLV5UY.js.map +0 -1
- package/dist/chunk-PTOP7OHG.js.map +0 -1
- package/dist/chunk-SN5YV6FF.js +0 -11
- package/dist/chunk-SN5YV6FF.js.map +0 -1
- package/dist/chunk-T3USOSVN.js.map +0 -1
- package/dist/chunk-T4CLW3DN.js +0 -2560
- package/dist/chunk-T4CLW3DN.js.map +0 -1
- package/dist/chunk-UW2SGTI5.js.map +0 -1
- package/dist/chunk-VSCU7K4V.js.map +0 -1
- package/dist/chunk-WL2Y2T47.js.map +0 -1
- package/dist/chunk-WUTL62MC.js.map +0 -1
- package/dist/chunk-Y3MTRA7D.js +0 -97
- package/dist/chunk-Y3MTRA7D.js.map +0 -1
- package/dist/chunk-YNNAJJ5Z.js.map +0 -1
- package/dist/document-tools/core.d.cts +0 -883
- package/dist/document-tools/index.d.cts +0 -90
- package/dist/index.d-BMhTH98a.d.cts +0 -2035
- package/dist/index.d-oR5FKZpJ.d.cts +0 -579
- package/dist/index.d.cts +0 -15893
- package/dist/model.d-CNtRWKVK.d.cts +0 -110
- package/dist/query-keys.d-ChgpJLPF.d.cts +0 -337
- package/dist/shell/index.d.cts +0 -6
- package/dist/store.d-GADDvC7w.d.cts +0 -35
- package/dist/stored-markdown.d-Bp18vrbr.d.cts +0 -125
- package/dist/ui/index.d.cts +0 -25
- package/dist/useAudioRecorder.d-B9rlMI_E.d.cts +0 -778
- package/dist/viewers/index.d.cts +0 -260
|
@@ -0,0 +1,73 @@
|
|
|
1
|
+
import { useEffect, useRef } from "react";
|
|
2
|
+
import { notify } from "../shell/index.js";
|
|
3
|
+
import { useArbiSessionState, useArbiSessionStore } from "../session/index.js";
|
|
4
|
+
function useDocumentAutoAdd({
|
|
5
|
+
selectedWorkspaceId,
|
|
6
|
+
allWorkspaceDocuments,
|
|
7
|
+
hasContent = false
|
|
8
|
+
}) {
|
|
9
|
+
const session = useArbiSessionStore();
|
|
10
|
+
const currentConversationId = useArbiSessionState((state) => state.conversationId);
|
|
11
|
+
const convKey = currentConversationId || "new";
|
|
12
|
+
const observedRef = useRef(null);
|
|
13
|
+
const offeredRef = useRef(/* @__PURE__ */ new Set());
|
|
14
|
+
useEffect(() => {
|
|
15
|
+
if (!selectedWorkspaceId) return;
|
|
16
|
+
const docs = (allWorkspaceDocuments ?? []).filter((doc) => doc?.external_id);
|
|
17
|
+
if (!docs.length) return;
|
|
18
|
+
const state = session.getState();
|
|
19
|
+
const current = state.conversationDocuments[convKey];
|
|
20
|
+
const autoAdd = state.conversationDocumentAutoAdd[convKey];
|
|
21
|
+
const key = `${selectedWorkspaceId}:${convKey}`;
|
|
22
|
+
const previous = observedRef.current;
|
|
23
|
+
const arrivals = previous?.key === key ? docs.filter((doc) => !previous.ids.has(doc.external_id)) : [];
|
|
24
|
+
observedRef.current = { key, ids: new Set(docs.map((doc) => doc.external_id)) };
|
|
25
|
+
const selected = new Set((current ?? []).map((doc) => doc.docId));
|
|
26
|
+
const missing = docs.filter((doc) => !selected.has(doc.external_id));
|
|
27
|
+
const legacySelection = autoAdd === void 0 && current !== void 0;
|
|
28
|
+
if (hasContent || legacySelection || autoAdd === false) {
|
|
29
|
+
const available = (legacySelection && !hasContent ? missing : arrivals).filter(
|
|
30
|
+
(doc) => !selected.has(doc.external_id)
|
|
31
|
+
);
|
|
32
|
+
const offerKey = `${key}:${available.map((doc) => doc.external_id).sort().join(",")}`;
|
|
33
|
+
if (available.length && (convKey !== "new" || current !== void 0) && !offeredRef.current.has(offerKey)) {
|
|
34
|
+
offeredRef.current.add(offerKey);
|
|
35
|
+
notify.info(
|
|
36
|
+
`${available.length} workspace document${available.length === 1 ? "" : "s"} available to add`,
|
|
37
|
+
{
|
|
38
|
+
record: false,
|
|
39
|
+
workspaceId: selectedWorkspaceId,
|
|
40
|
+
duration: 1e4,
|
|
41
|
+
action: {
|
|
42
|
+
label: "Add to chat",
|
|
43
|
+
onClick: () => {
|
|
44
|
+
const latest = session.getState();
|
|
45
|
+
if (latest.workspaceId !== selectedWorkspaceId || (latest.conversationId || "new") !== convKey || // The 'new' slot is reused after sending. Its immutable selection
|
|
46
|
+
// object identifies the draft this offer was actually made for.
|
|
47
|
+
convKey === "new" && latest.conversationDocuments.new !== current)
|
|
48
|
+
return;
|
|
49
|
+
const existing = latest.conversationDocuments[convKey] ?? [];
|
|
50
|
+
const included = new Set(existing.map((doc) => doc.docId));
|
|
51
|
+
session.setConversationDocuments(convKey, [
|
|
52
|
+
...existing,
|
|
53
|
+
...available.filter((doc) => !included.has(doc.external_id)).map((doc) => ({ docId: doc.external_id, isPinned: false }))
|
|
54
|
+
]);
|
|
55
|
+
}
|
|
56
|
+
}
|
|
57
|
+
}
|
|
58
|
+
);
|
|
59
|
+
}
|
|
60
|
+
return;
|
|
61
|
+
}
|
|
62
|
+
if (autoAdd && !missing.length) return;
|
|
63
|
+
session.setConversationDocuments(
|
|
64
|
+
convKey,
|
|
65
|
+
[...current ?? [], ...missing.map((doc) => ({ docId: doc.external_id, isPinned: false }))],
|
|
66
|
+
true
|
|
67
|
+
);
|
|
68
|
+
}, [selectedWorkspaceId, convKey, allWorkspaceDocuments, hasContent, session]);
|
|
69
|
+
}
|
|
70
|
+
export {
|
|
71
|
+
useDocumentAutoAdd
|
|
72
|
+
};
|
|
73
|
+
//# sourceMappingURL=useDocumentAutoAdd.js.map
|
|
@@ -0,0 +1,7 @@
|
|
|
1
|
+
{
|
|
2
|
+
"version": 3,
|
|
3
|
+
"sources": ["../../src/chat/useDocumentAutoAdd.ts"],
|
|
4
|
+
"sourcesContent": ["/**\n * useDocumentAutoAdd Hook\n *\n * Automatically adds all documents to conversation context\n * while the chat is empty. Populated chats keep their chosen sources.\n */\n\nimport { useEffect, useRef } from 'react'\nimport { notify } from '../shell'\nimport { useArbiSessionState, useArbiSessionStore } from '../session'\n\n/** A document the conversation may read: only its id matters here. */\ntype Doc = { external_id: string }\n\ninterface UseDocumentAutoAddOptions {\n selectedWorkspaceId: string | null\n allWorkspaceDocuments: Doc[]\n /** Existing messages (including a saved conversation still loading) freeze auto-add. */\n hasContent?: boolean\n}\n\nexport function useDocumentAutoAdd({\n selectedWorkspaceId,\n allWorkspaceDocuments,\n hasContent = false,\n}: UseDocumentAutoAddOptions) {\n const session = useArbiSessionStore()\n const currentConversationId = useArbiSessionState((state) => state.conversationId)\n\n const convKey = currentConversationId || 'new'\n const observedRef = useRef<{ key: string; ids: Set<string> } | null>(null)\n const offeredRef = useRef(new Set<string>())\n\n useEffect(() => {\n if (!selectedWorkspaceId) return\n const docs = (allWorkspaceDocuments ?? []).filter((doc) => doc?.external_id)\n if (!docs.length) return\n\n const state = session.getState()\n const current = state.conversationDocuments[convKey]\n const autoAdd = state.conversationDocumentAutoAdd[convKey]\n const key = `${selectedWorkspaceId}:${convKey}`\n const previous = observedRef.current\n const arrivals =\n previous?.key === key ? docs.filter((doc) => !previous.ids.has(doc.external_id)) : []\n observedRef.current = { key, ids: new Set(docs.map((doc) => doc.external_id)) }\n const selected = new Set((current ?? []).map((doc) => doc.docId))\n const missing = docs.filter((doc) => !selected.has(doc.external_id))\n const legacySelection = autoAdd === undefined && current !== undefined\n\n // Old drafts have no selection provenance. Offer the missing sources; never\n // guess whether an old partial/empty selection was automatic or deliberate.\n if (hasContent || legacySelection || autoAdd === false) {\n const available = (legacySelection && !hasContent ? missing : arrivals).filter(\n (doc) => !selected.has(doc.external_id)\n )\n const offerKey = `${key}:${available\n .map((doc) => doc.external_id)\n .sort()\n .join(',')}`\n if (\n available.length &&\n (convKey !== 'new' || current !== undefined) &&\n !offeredRef.current.has(offerKey)\n ) {\n offeredRef.current.add(offerKey)\n notify.info(\n `${available.length} workspace document${available.length === 1 ? '' : 's'} available to add`,\n {\n record: false,\n workspaceId: selectedWorkspaceId,\n duration: 10000,\n action: {\n label: 'Add to chat',\n onClick: () => {\n const latest = session.getState()\n if (\n latest.workspaceId !== selectedWorkspaceId ||\n (latest.conversationId || 'new') !== convKey ||\n // The 'new' slot is reused after sending. Its immutable selection\n // object identifies the draft this offer was actually made for.\n (convKey === 'new' && latest.conversationDocuments.new !== current)\n )\n return\n const existing = latest.conversationDocuments[convKey] ?? []\n const included = new Set(existing.map((doc) => doc.docId))\n session.setConversationDocuments(convKey, [\n ...existing,\n ...available\n .filter((doc) => !included.has(doc.external_id))\n .map((doc) => ({ docId: doc.external_id, isPinned: false })),\n ])\n },\n },\n }\n )\n }\n return\n }\n if (autoAdd && !missing.length) return\n session.setConversationDocuments(\n convKey,\n [...(current ?? []), ...missing.map((doc) => ({ docId: doc.external_id, isPinned: false }))],\n true\n )\n }, [selectedWorkspaceId, convKey, allWorkspaceDocuments, hasContent, session])\n}\n"],
|
|
5
|
+
"mappings": "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",
|
|
6
|
+
"names": []
|
|
7
|
+
}
|
|
@@ -0,0 +1,39 @@
|
|
|
1
|
+
import { useEffect, useRef, useState } from "react";
|
|
2
|
+
import { useArbiSessionState, useArbiSessionStore } from "../session/index.js";
|
|
3
|
+
function useMessageTimer({
|
|
4
|
+
conversationId,
|
|
5
|
+
messageId,
|
|
6
|
+
isUser,
|
|
7
|
+
isGenerating
|
|
8
|
+
}) {
|
|
9
|
+
const session = useArbiSessionStore();
|
|
10
|
+
const convId = conversationId || "new";
|
|
11
|
+
const timerKey = `${convId}:${messageId}`;
|
|
12
|
+
const generationStartTime = useArbiSessionState((s) => s.generating[convId]?.startTime ?? null);
|
|
13
|
+
const storedElapsed = useArbiSessionState((s) => s.messageTimers[timerKey]?.elapsedTime);
|
|
14
|
+
const [elapsedTime, setElapsedTime] = useState(0);
|
|
15
|
+
const lastElapsedRef = useRef(0);
|
|
16
|
+
useEffect(() => {
|
|
17
|
+
if (!isUser && !isGenerating && storedElapsed) setElapsedTime(storedElapsed);
|
|
18
|
+
}, [isUser, isGenerating, storedElapsed]);
|
|
19
|
+
useEffect(() => {
|
|
20
|
+
if (isUser || !isGenerating || !generationStartTime) return;
|
|
21
|
+
const startTime = generationStartTime;
|
|
22
|
+
const key = timerKey;
|
|
23
|
+
const interval = setInterval(() => {
|
|
24
|
+
const elapsed = (Date.now() - startTime) / 1e3;
|
|
25
|
+
lastElapsedRef.current = elapsed;
|
|
26
|
+
setElapsedTime(elapsed);
|
|
27
|
+
}, 100);
|
|
28
|
+
return () => {
|
|
29
|
+
clearInterval(interval);
|
|
30
|
+
const finalElapsed = lastElapsedRef.current || (Date.now() - startTime) / 1e3;
|
|
31
|
+
session.setMessageTimer(key, { startTime, elapsedTime: finalElapsed });
|
|
32
|
+
};
|
|
33
|
+
}, [isUser, isGenerating, generationStartTime, timerKey, session]);
|
|
34
|
+
return { elapsedTime };
|
|
35
|
+
}
|
|
36
|
+
export {
|
|
37
|
+
useMessageTimer
|
|
38
|
+
};
|
|
39
|
+
//# sourceMappingURL=useMessageTimer.js.map
|
|
@@ -0,0 +1,7 @@
|
|
|
1
|
+
{
|
|
2
|
+
"version": 3,
|
|
3
|
+
"sources": ["../../src/chat/useMessageTimer.ts"],
|
|
4
|
+
"sourcesContent": ["/**\n * The time an answer has taken: counted on the client while its turn runs (separately from the\n * server's step times), and saved when it stops showing, so a finished answer keeps its time and a\n * re-attached run keeps counting from its real start.\n */\n\nimport { useEffect, useRef, useState } from 'react'\nimport { useArbiSessionState, useArbiSessionStore } from '../session'\n\nexport interface UseMessageTimerOptions {\n conversationId: string | undefined\n messageId: string | undefined\n isUser: boolean\n isGenerating: boolean\n}\n\nexport interface MessageTimerResult {\n /** Seconds. */\n elapsedTime: number\n}\n\nexport function useMessageTimer({\n conversationId,\n messageId,\n isUser,\n isGenerating,\n}: UseMessageTimerOptions): MessageTimerResult {\n const session = useArbiSessionStore()\n const convId = conversationId || 'new'\n const timerKey = `${convId}:${messageId}`\n\n const generationStartTime = useArbiSessionState((s) => s.generating[convId]?.startTime ?? null)\n const storedElapsed = useArbiSessionState((s) => s.messageTimers[timerKey]?.elapsedTime)\n\n const [elapsedTime, setElapsedTime] = useState(0)\n // The latest elapsed time, for the cleanup to save without depending on it.\n const lastElapsedRef = useRef(0)\n\n // A finished answer shows its saved time.\n useEffect(() => {\n if (!isUser && !isGenerating && storedElapsed) setElapsedTime(storedElapsed)\n }, [isUser, isGenerating, storedElapsed])\n\n // Count while the turn runs. The cleanup saves the final time through the store's current state,\n // so the saved timer is not a dependency (saving would re-run the effect, which saves again...).\n useEffect(() => {\n if (isUser || !isGenerating || !generationStartTime) return\n const startTime = generationStartTime\n const key = timerKey\n const interval = setInterval(() => {\n const elapsed = (Date.now() - startTime) / 1000\n lastElapsedRef.current = elapsed\n setElapsedTime(elapsed)\n }, 100)\n return () => {\n clearInterval(interval)\n const finalElapsed = lastElapsedRef.current || (Date.now() - startTime) / 1000\n session.setMessageTimer(key, { startTime, elapsedTime: finalElapsed })\n }\n }, [isUser, isGenerating, generationStartTime, timerKey, session])\n\n return { elapsedTime }\n}\n"],
|
|
5
|
+
"mappings": "AAMA,SAAS,WAAW,QAAQ,gBAAgB;AAC5C,SAAS,qBAAqB,2BAA2B;AAclD,SAAS,gBAAgB;AAAA,EAC9B;AAAA,EACA;AAAA,EACA;AAAA,EACA;AACF,GAA+C;AAC7C,QAAM,UAAU,oBAAoB;AACpC,QAAM,SAAS,kBAAkB;AACjC,QAAM,WAAW,GAAG,MAAM,IAAI,SAAS;AAEvC,QAAM,sBAAsB,oBAAoB,CAAC,MAAM,EAAE,WAAW,MAAM,GAAG,aAAa,IAAI;AAC9F,QAAM,gBAAgB,oBAAoB,CAAC,MAAM,EAAE,cAAc,QAAQ,GAAG,WAAW;AAEvF,QAAM,CAAC,aAAa,cAAc,IAAI,SAAS,CAAC;AAEhD,QAAM,iBAAiB,OAAO,CAAC;AAG/B,YAAU,MAAM;AACd,QAAI,CAAC,UAAU,CAAC,gBAAgB,cAAe,gBAAe,aAAa;AAAA,EAC7E,GAAG,CAAC,QAAQ,cAAc,aAAa,CAAC;AAIxC,YAAU,MAAM;AACd,QAAI,UAAU,CAAC,gBAAgB,CAAC,oBAAqB;AACrD,UAAM,YAAY;AAClB,UAAM,MAAM;AACZ,UAAM,WAAW,YAAY,MAAM;AACjC,YAAM,WAAW,KAAK,IAAI,IAAI,aAAa;AAC3C,qBAAe,UAAU;AACzB,qBAAe,OAAO;AAAA,IACxB,GAAG,GAAG;AACN,WAAO,MAAM;AACX,oBAAc,QAAQ;AACtB,YAAM,eAAe,eAAe,YAAY,KAAK,IAAI,IAAI,aAAa;AAC1E,cAAQ,gBAAgB,KAAK,EAAE,WAAW,aAAa,aAAa,CAAC;AAAA,IACvE;AAAA,EACF,GAAG,CAAC,QAAQ,cAAc,qBAAqB,UAAU,OAAO,CAAC;AAEjE,SAAO,EAAE,YAAY;AACvB;",
|
|
6
|
+
"names": []
|
|
7
|
+
}
|
|
@@ -0,0 +1,67 @@
|
|
|
1
|
+
import { useMemo } from "react";
|
|
2
|
+
function useThinkingContent({
|
|
3
|
+
content,
|
|
4
|
+
modelName,
|
|
5
|
+
isUser,
|
|
6
|
+
isGenerating
|
|
7
|
+
}) {
|
|
8
|
+
return useMemo(() => {
|
|
9
|
+
if (isUser || !content) {
|
|
10
|
+
return {
|
|
11
|
+
responseContent: content || "",
|
|
12
|
+
thinkingContent: "",
|
|
13
|
+
isThinking: false,
|
|
14
|
+
hasThinkTag: false
|
|
15
|
+
};
|
|
16
|
+
}
|
|
17
|
+
const isQ235TModel = modelName === "Q235T@ARBICITY";
|
|
18
|
+
const hasCloseThinkTag = content.includes("</think>");
|
|
19
|
+
const closeThinkIndex = content.indexOf("</think>");
|
|
20
|
+
let responseContent = content;
|
|
21
|
+
let thinkingContent = "";
|
|
22
|
+
let isThinking = false;
|
|
23
|
+
let hasThinkTag = false;
|
|
24
|
+
let thinkStartPos = -1;
|
|
25
|
+
let beforeThinkContent = "";
|
|
26
|
+
if (isQ235TModel) {
|
|
27
|
+
hasThinkTag = true;
|
|
28
|
+
thinkStartPos = 0;
|
|
29
|
+
} else if (content.includes("<think>")) {
|
|
30
|
+
hasThinkTag = true;
|
|
31
|
+
const thinkIndex = content.indexOf("<think>");
|
|
32
|
+
thinkStartPos = thinkIndex + 7;
|
|
33
|
+
beforeThinkContent = content.substring(0, thinkIndex).trim();
|
|
34
|
+
}
|
|
35
|
+
if (hasThinkTag && thinkStartPos >= 0) {
|
|
36
|
+
if (hasCloseThinkTag) {
|
|
37
|
+
thinkingContent = content.substring(thinkStartPos, closeThinkIndex).trim();
|
|
38
|
+
responseContent = beforeThinkContent;
|
|
39
|
+
const afterThinking = content.substring(closeThinkIndex + 8).trim();
|
|
40
|
+
if (afterThinking) {
|
|
41
|
+
responseContent = responseContent + (responseContent ? " " : "") + afterThinking;
|
|
42
|
+
}
|
|
43
|
+
} else {
|
|
44
|
+
thinkingContent = content.substring(thinkStartPos).trim();
|
|
45
|
+
responseContent = beforeThinkContent;
|
|
46
|
+
isThinking = isGenerating && thinkingContent.length > 0;
|
|
47
|
+
}
|
|
48
|
+
} else if (hasCloseThinkTag) {
|
|
49
|
+
const lastClose = content.lastIndexOf("</think>");
|
|
50
|
+
hasThinkTag = true;
|
|
51
|
+
thinkingContent = content.substring(0, lastClose).trim();
|
|
52
|
+
responseContent = content.substring(lastClose + 8).trim();
|
|
53
|
+
}
|
|
54
|
+
responseContent = responseContent.replace(/<\/?think>/gi, "").trim();
|
|
55
|
+
thinkingContent = thinkingContent.replace(/<\/?think>/gi, "").trim();
|
|
56
|
+
return {
|
|
57
|
+
responseContent,
|
|
58
|
+
thinkingContent,
|
|
59
|
+
isThinking,
|
|
60
|
+
hasThinkTag
|
|
61
|
+
};
|
|
62
|
+
}, [content, modelName, isUser, isGenerating]);
|
|
63
|
+
}
|
|
64
|
+
export {
|
|
65
|
+
useThinkingContent
|
|
66
|
+
};
|
|
67
|
+
//# sourceMappingURL=useThinkingContent.js.map
|
|
@@ -0,0 +1,7 @@
|
|
|
1
|
+
{
|
|
2
|
+
"version": 3,
|
|
3
|
+
"sources": ["../../src/chat/useThinkingContent.ts"],
|
|
4
|
+
"sourcesContent": ["/**\n * useThinkingContent Hook\n *\n * Extracts thinking content from AI message responses.\n * Handles both explicit <think> tags and model-specific thinking patterns.\n * Returns parsed thinking content and response content separately.\n */\n\nimport { useMemo } from 'react'\n\ninterface ThinkingContentResult {\n /** The main response content (without thinking tags) */\n responseContent: string\n /** The extracted thinking/reasoning content */\n thinkingContent: string\n /** Whether the model is currently in thinking mode */\n isThinking: boolean\n /** Whether the message contains thinking content */\n hasThinkTag: boolean\n}\n\ninterface UseThinkingContentOptions {\n /** The raw message content */\n content: string\n /** The model name to check for model-specific behavior */\n modelName: string | null\n /** Whether the message is from the user (skip processing) */\n isUser: boolean\n /** Whether the message is currently being generated */\n isGenerating: boolean\n}\n\n/**\n * Hook to extract thinking content from AI responses.\n * Some models use explicit <think></think> tags, while others\n * (like Q235T@ARBICITY) start with thinking content implicitly.\n */\nexport function useThinkingContent({\n content,\n modelName,\n isUser,\n isGenerating,\n}: UseThinkingContentOptions): ThinkingContentResult {\n return useMemo(() => {\n // Default values for user messages or empty content\n if (isUser || !content) {\n return {\n responseContent: content || '',\n thinkingContent: '',\n isThinking: false,\n hasThinkTag: false,\n }\n }\n\n const isQ235TModel = modelName === 'Q235T@ARBICITY'\n const hasCloseThinkTag = content.includes('</think>')\n const closeThinkIndex = content.indexOf('</think>')\n\n let responseContent = content\n let thinkingContent = ''\n let isThinking = false\n let hasThinkTag = false\n\n // Determine thinking start position\n let thinkStartPos = -1\n let beforeThinkContent = ''\n\n if (isQ235TModel) {\n // Q235T@ARBICITY: No <think> tag, content starts as thinking at position 0\n hasThinkTag = true\n thinkStartPos = 0\n } else if (content.includes('<think>')) {\n // Other models: Look for explicit <think> tag\n hasThinkTag = true\n const thinkIndex = content.indexOf('<think>')\n thinkStartPos = thinkIndex + 7\n beforeThinkContent = content.substring(0, thinkIndex).trim()\n }\n\n // Process thinking content if we have thinking\n if (hasThinkTag && thinkStartPos >= 0) {\n if (hasCloseThinkTag) {\n // Complete thinking block\n thinkingContent = content.substring(thinkStartPos, closeThinkIndex).trim()\n responseContent = beforeThinkContent\n const afterThinking = content.substring(closeThinkIndex + 8).trim()\n if (afterThinking) {\n responseContent = responseContent + (responseContent ? ' ' : '') + afterThinking\n }\n } else {\n // Still thinking - only if actively generating\n thinkingContent = content.substring(thinkStartPos).trim()\n responseContent = beforeThinkContent\n // Only mark as \"thinking\" if actively generating (not aborted/stopped)\n isThinking = isGenerating && thinkingContent.length > 0\n }\n } else if (hasCloseThinkTag) {\n // Orphan `</think>` with no matching `<think>` \u2014 vLLM's qwen3 reasoning\n // parser sometimes strips the opening tag while leaving the closing one\n // (and a model may emit several closing tags). Treat everything up to\n // the LAST `</think>` as leaked reasoning and surface what follows as\n // the real answer, so users don't see raw `</think>` in their replies.\n const lastClose = content.lastIndexOf('</think>')\n hasThinkTag = true\n thinkingContent = content.substring(0, lastClose).trim()\n responseContent = content.substring(lastClose + 8).trim()\n }\n\n // Final defensive sweep: strip any stray <think>/</think> tags that\n // survived the parsing above (e.g. extra opening or closing tags from a\n // model that emitted nested or unbalanced reasoning markers).\n responseContent = responseContent.replace(/<\\/?think>/gi, '').trim()\n thinkingContent = thinkingContent.replace(/<\\/?think>/gi, '').trim()\n\n return {\n responseContent,\n thinkingContent,\n isThinking,\n hasThinkTag,\n }\n }, [content, modelName, isUser, isGenerating])\n}\n"],
|
|
5
|
+
"mappings": "AAQA,SAAS,eAAe;AA6BjB,SAAS,mBAAmB;AAAA,EACjC;AAAA,EACA;AAAA,EACA;AAAA,EACA;AACF,GAAqD;AACnD,SAAO,QAAQ,MAAM;AAEnB,QAAI,UAAU,CAAC,SAAS;AACtB,aAAO;AAAA,QACL,iBAAiB,WAAW;AAAA,QAC5B,iBAAiB;AAAA,QACjB,YAAY;AAAA,QACZ,aAAa;AAAA,MACf;AAAA,IACF;AAEA,UAAM,eAAe,cAAc;AACnC,UAAM,mBAAmB,QAAQ,SAAS,UAAU;AACpD,UAAM,kBAAkB,QAAQ,QAAQ,UAAU;AAElD,QAAI,kBAAkB;AACtB,QAAI,kBAAkB;AACtB,QAAI,aAAa;AACjB,QAAI,cAAc;AAGlB,QAAI,gBAAgB;AACpB,QAAI,qBAAqB;AAEzB,QAAI,cAAc;AAEhB,oBAAc;AACd,sBAAgB;AAAA,IAClB,WAAW,QAAQ,SAAS,SAAS,GAAG;AAEtC,oBAAc;AACd,YAAM,aAAa,QAAQ,QAAQ,SAAS;AAC5C,sBAAgB,aAAa;AAC7B,2BAAqB,QAAQ,UAAU,GAAG,UAAU,EAAE,KAAK;AAAA,IAC7D;AAGA,QAAI,eAAe,iBAAiB,GAAG;AACrC,UAAI,kBAAkB;AAEpB,0BAAkB,QAAQ,UAAU,eAAe,eAAe,EAAE,KAAK;AACzE,0BAAkB;AAClB,cAAM,gBAAgB,QAAQ,UAAU,kBAAkB,CAAC,EAAE,KAAK;AAClE,YAAI,eAAe;AACjB,4BAAkB,mBAAmB,kBAAkB,MAAM,MAAM;AAAA,QACrE;AAAA,MACF,OAAO;AAEL,0BAAkB,QAAQ,UAAU,aAAa,EAAE,KAAK;AACxD,0BAAkB;AAElB,qBAAa,gBAAgB,gBAAgB,SAAS;AAAA,MACxD;AAAA,IACF,WAAW,kBAAkB;AAM3B,YAAM,YAAY,QAAQ,YAAY,UAAU;AAChD,oBAAc;AACd,wBAAkB,QAAQ,UAAU,GAAG,SAAS,EAAE,KAAK;AACvD,wBAAkB,QAAQ,UAAU,YAAY,CAAC,EAAE,KAAK;AAAA,IAC1D;AAKA,sBAAkB,gBAAgB,QAAQ,gBAAgB,EAAE,EAAE,KAAK;AACnE,sBAAkB,gBAAgB,QAAQ,gBAAgB,EAAE,EAAE,KAAK;AAEnE,WAAO;AAAA,MACL;AAAA,MACA;AAAA,MACA;AAAA,MACA;AAAA,IACF;AAAA,EACF,GAAG,CAAC,SAAS,WAAW,QAAQ,YAAY,CAAC;AAC/C;",
|
|
6
|
+
"names": []
|
|
7
|
+
}
|
|
@@ -0,0 +1,61 @@
|
|
|
1
|
+
import { useCallback, useEffect, useSyncExternalStore } from "react";
|
|
2
|
+
import { useQueryClient } from "@tanstack/react-query";
|
|
3
|
+
import { notify } from "../shell/index.js";
|
|
4
|
+
import { useConversations } from "../hooks.js";
|
|
5
|
+
import { useArbi } from "../useArbi.js";
|
|
6
|
+
import { useArbiSessionState, useArbiSessionStore } from "../session/index.js";
|
|
7
|
+
import { bindThreadDocument, migrateLegacyThreadDocuments, threadBinding } from "./thread-binding.js";
|
|
8
|
+
const migratedWorkspaces = /* @__PURE__ */ new Set();
|
|
9
|
+
function useThreadDocument() {
|
|
10
|
+
const arbi = useArbi();
|
|
11
|
+
const queryClient = useQueryClient();
|
|
12
|
+
const session = useArbiSessionStore();
|
|
13
|
+
const conversationId = useArbiSessionState((s) => s.conversationId);
|
|
14
|
+
const workspaceId = useArbiSessionState((s) => s.workspaceId);
|
|
15
|
+
const newChatDocumentId = useArbiSessionState((s) => s.newChatDocumentId);
|
|
16
|
+
const subscribe = useCallback(
|
|
17
|
+
(onChange) => queryClient.getQueryCache().subscribe(onChange),
|
|
18
|
+
[queryClient]
|
|
19
|
+
);
|
|
20
|
+
const savedDocumentId = useSyncExternalStore(
|
|
21
|
+
subscribe,
|
|
22
|
+
() => threadBinding(queryClient, conversationId).documentId,
|
|
23
|
+
() => null
|
|
24
|
+
);
|
|
25
|
+
const unavailable = useSyncExternalStore(
|
|
26
|
+
subscribe,
|
|
27
|
+
() => threadBinding(queryClient, conversationId).unavailable,
|
|
28
|
+
() => false
|
|
29
|
+
);
|
|
30
|
+
const { data: conversations, isPlaceholderData } = useConversations(workspaceId ?? void 0);
|
|
31
|
+
useEffect(() => {
|
|
32
|
+
if (!workspaceId || !conversations || isPlaceholderData || migratedWorkspaces.has(workspaceId))
|
|
33
|
+
return;
|
|
34
|
+
migratedWorkspaces.add(workspaceId);
|
|
35
|
+
void migrateLegacyThreadDocuments(arbi, queryClient, conversations);
|
|
36
|
+
}, [arbi, queryClient, workspaceId, conversations, isPlaceholderData]);
|
|
37
|
+
const bind = useCallback(
|
|
38
|
+
(documentId) => {
|
|
39
|
+
const { conversationId: open } = session.getState();
|
|
40
|
+
if (!open) {
|
|
41
|
+
session.setNewChatDocumentId(documentId);
|
|
42
|
+
return;
|
|
43
|
+
}
|
|
44
|
+
bindThreadDocument(arbi, queryClient, open, documentId).catch(
|
|
45
|
+
() => notify.error(
|
|
46
|
+
documentId ? "Could not attach the document to this thread" : "Could not unbind the document"
|
|
47
|
+
)
|
|
48
|
+
);
|
|
49
|
+
},
|
|
50
|
+
[arbi, queryClient, session]
|
|
51
|
+
);
|
|
52
|
+
return {
|
|
53
|
+
documentId: conversationId ? savedDocumentId : newChatDocumentId,
|
|
54
|
+
unavailable: conversationId ? unavailable : false,
|
|
55
|
+
bind
|
|
56
|
+
};
|
|
57
|
+
}
|
|
58
|
+
export {
|
|
59
|
+
useThreadDocument
|
|
60
|
+
};
|
|
61
|
+
//# sourceMappingURL=useThreadDocument.js.map
|
|
@@ -0,0 +1,7 @@
|
|
|
1
|
+
{
|
|
2
|
+
"version": 3,
|
|
3
|
+
"sources": ["../../src/chat/useThreadDocument.ts"],
|
|
4
|
+
"sourcesContent": ["import { useCallback, useEffect, useSyncExternalStore } from 'react'\nimport { useQueryClient } from '@tanstack/react-query'\nimport { notify } from '../shell'\nimport { useConversations } from '../hooks'\nimport { useArbi } from '../useArbi'\nimport { useArbiSessionState, useArbiSessionStore } from '../session'\nimport { bindThreadDocument, migrateLegacyThreadDocuments, threadBinding } from './thread-binding'\n\n/** The workspaces whose locally kept bindings were moved to the server in this visit. */\nconst migratedWorkspaces = new Set<string>()\n\n/**\n * The open conversation's bound document, and how to bind or (null) unbind it. A saved thread's\n * binding is the server's (attach and unbind write it there); a new chat's is the session's until\n * its first turn. `unavailable`: the thread is bound to a document this person cannot open.\n */\nexport function useThreadDocument(): {\n documentId: string | null\n unavailable: boolean\n bind: (documentId: string | null) => void\n} {\n const arbi = useArbi()\n const queryClient = useQueryClient()\n const session = useArbiSessionStore()\n const conversationId = useArbiSessionState((s) => s.conversationId)\n const workspaceId = useArbiSessionState((s) => s.workspaceId)\n const newChatDocumentId = useArbiSessionState((s) => s.newChatDocumentId)\n const subscribe = useCallback(\n (onChange: () => void) => queryClient.getQueryCache().subscribe(onChange),\n [queryClient]\n )\n const savedDocumentId = useSyncExternalStore(\n subscribe,\n () => threadBinding(queryClient, conversationId).documentId,\n () => null\n )\n const unavailable = useSyncExternalStore(\n subscribe,\n () => threadBinding(queryClient, conversationId).unavailable,\n () => false\n )\n\n // Bindings kept on this device before the server held them move there once.\n // (Never from the previous workspace's list, shown while this one loads.)\n const { data: conversations, isPlaceholderData } = useConversations(workspaceId ?? undefined)\n useEffect(() => {\n if (!workspaceId || !conversations || isPlaceholderData || migratedWorkspaces.has(workspaceId))\n return\n migratedWorkspaces.add(workspaceId)\n void migrateLegacyThreadDocuments(arbi, queryClient, conversations)\n }, [arbi, queryClient, workspaceId, conversations, isPlaceholderData])\n\n const bind = useCallback(\n (documentId: string | null) => {\n const { conversationId: open } = session.getState()\n if (!open) {\n session.setNewChatDocumentId(documentId)\n return\n }\n bindThreadDocument(arbi, queryClient, open, documentId).catch(() =>\n notify.error(\n documentId\n ? 'Could not attach the document to this thread'\n : 'Could not unbind the document'\n )\n )\n },\n [arbi, queryClient, session]\n )\n return {\n documentId: conversationId ? savedDocumentId : newChatDocumentId,\n unavailable: conversationId ? unavailable : false,\n bind,\n }\n}\n"],
|
|
5
|
+
"mappings": "AAAA,SAAS,aAAa,WAAW,4BAA4B;AAC7D,SAAS,sBAAsB;AAC/B,SAAS,cAAc;AACvB,SAAS,wBAAwB;AACjC,SAAS,eAAe;AACxB,SAAS,qBAAqB,2BAA2B;AACzD,SAAS,oBAAoB,8BAA8B,qBAAqB;AAGhF,MAAM,qBAAqB,oBAAI,IAAY;AAOpC,SAAS,oBAId;AACA,QAAM,OAAO,QAAQ;AACrB,QAAM,cAAc,eAAe;AACnC,QAAM,UAAU,oBAAoB;AACpC,QAAM,iBAAiB,oBAAoB,CAAC,MAAM,EAAE,cAAc;AAClE,QAAM,cAAc,oBAAoB,CAAC,MAAM,EAAE,WAAW;AAC5D,QAAM,oBAAoB,oBAAoB,CAAC,MAAM,EAAE,iBAAiB;AACxE,QAAM,YAAY;AAAA,IAChB,CAAC,aAAyB,YAAY,cAAc,EAAE,UAAU,QAAQ;AAAA,IACxE,CAAC,WAAW;AAAA,EACd;AACA,QAAM,kBAAkB;AAAA,IACtB;AAAA,IACA,MAAM,cAAc,aAAa,cAAc,EAAE;AAAA,IACjD,MAAM;AAAA,EACR;AACA,QAAM,cAAc;AAAA,IAClB;AAAA,IACA,MAAM,cAAc,aAAa,cAAc,EAAE;AAAA,IACjD,MAAM;AAAA,EACR;AAIA,QAAM,EAAE,MAAM,eAAe,kBAAkB,IAAI,iBAAiB,eAAe,MAAS;AAC5F,YAAU,MAAM;AACd,QAAI,CAAC,eAAe,CAAC,iBAAiB,qBAAqB,mBAAmB,IAAI,WAAW;AAC3F;AACF,uBAAmB,IAAI,WAAW;AAClC,SAAK,6BAA6B,MAAM,aAAa,aAAa;AAAA,EACpE,GAAG,CAAC,MAAM,aAAa,aAAa,eAAe,iBAAiB,CAAC;AAErE,QAAM,OAAO;AAAA,IACX,CAAC,eAA8B;AAC7B,YAAM,EAAE,gBAAgB,KAAK,IAAI,QAAQ,SAAS;AAClD,UAAI,CAAC,MAAM;AACT,gBAAQ,qBAAqB,UAAU;AACvC;AAAA,MACF;AACA,yBAAmB,MAAM,aAAa,MAAM,UAAU,EAAE;AAAA,QAAM,MAC5D,OAAO;AAAA,UACL,aACI,iDACA;AAAA,QACN;AAAA,MACF;AAAA,IACF;AAAA,IACA,CAAC,MAAM,aAAa,OAAO;AAAA,EAC7B;AACA,SAAO;AAAA,IACL,YAAY,iBAAiB,kBAAkB;AAAA,IAC/C,aAAa,iBAAiB,cAAc;AAAA,IAC5C;AAAA,EACF;AACF;",
|
|
6
|
+
"names": []
|
|
7
|
+
}
|
|
@@ -0,0 +1,50 @@
|
|
|
1
|
+
import { useEffect, useMemo, useRef } from "react";
|
|
2
|
+
import { useQueryClient } from "@tanstack/react-query";
|
|
3
|
+
import { arbiQueryKeys } from "../hooks.js";
|
|
4
|
+
import { useArbi } from "../useArbi.js";
|
|
5
|
+
import { useCanEditShared, useUpdateConversation, useWorkflows } from "../workforce.js";
|
|
6
|
+
function workflowRunTitle(workflowName, createdAt) {
|
|
7
|
+
const day = new Date(createdAt).toLocaleDateString(void 0, { day: "numeric", month: "short" });
|
|
8
|
+
return `${workflowName} \u2014 ${day}`;
|
|
9
|
+
}
|
|
10
|
+
function useWorkflowRunTitles(conversations, openId, workspaceId) {
|
|
11
|
+
const hasUntitledRun = conversations.some((c) => !c.title && c.workflow_ext_id && c.created_at);
|
|
12
|
+
const { data: workflows } = useWorkflows({ enabled: hasUntitledRun });
|
|
13
|
+
const titles = useMemo(() => {
|
|
14
|
+
const names = new Map((workflows ?? []).map((w) => [w.external_id, w.name]));
|
|
15
|
+
const out = {};
|
|
16
|
+
for (const c of conversations) {
|
|
17
|
+
const name = !c.title && c.workflow_ext_id ? names.get(c.workflow_ext_id) : void 0;
|
|
18
|
+
if (name && c.created_at) out[c.external_id] = workflowRunTitle(name, c.created_at);
|
|
19
|
+
}
|
|
20
|
+
return out;
|
|
21
|
+
}, [workflows, conversations]);
|
|
22
|
+
const arbi = useArbi();
|
|
23
|
+
const queryClient = useQueryClient();
|
|
24
|
+
const canEditShared = useCanEditShared();
|
|
25
|
+
const { mutateAsync: rename } = useUpdateConversation();
|
|
26
|
+
const titled = useRef(/* @__PURE__ */ new Set());
|
|
27
|
+
const open = openId ? conversations.find((c) => c.external_id === openId) : void 0;
|
|
28
|
+
const openTitle = openId ? titles[openId] : void 0;
|
|
29
|
+
const mayEdit = !!open && (open.is_owner === true || open.is_shared === true && canEditShared);
|
|
30
|
+
useEffect(() => {
|
|
31
|
+
if (!openId || !openTitle || !mayEdit || !workspaceId || titled.current.has(openId)) return;
|
|
32
|
+
titled.current.add(openId);
|
|
33
|
+
void (async () => {
|
|
34
|
+
const fresh = await queryClient.fetchQuery({
|
|
35
|
+
queryKey: arbiQueryKeys.conversations(workspaceId),
|
|
36
|
+
queryFn: () => arbi.conversations.list({ workspaceId }),
|
|
37
|
+
staleTime: 0
|
|
38
|
+
});
|
|
39
|
+
if (fresh.find((c) => c.external_id === openId)?.title) return;
|
|
40
|
+
await rename({ conversationId: openId, patch: { title: openTitle } });
|
|
41
|
+
})().catch(() => {
|
|
42
|
+
});
|
|
43
|
+
}, [openId, openTitle, mayEdit, workspaceId, arbi, queryClient, rename]);
|
|
44
|
+
return titles;
|
|
45
|
+
}
|
|
46
|
+
export {
|
|
47
|
+
useWorkflowRunTitles,
|
|
48
|
+
workflowRunTitle
|
|
49
|
+
};
|
|
50
|
+
//# sourceMappingURL=workflow-run-titles.js.map
|
|
@@ -0,0 +1,7 @@
|
|
|
1
|
+
{
|
|
2
|
+
"version": 3,
|
|
3
|
+
"sources": ["../../src/chat/workflow-run-titles.ts"],
|
|
4
|
+
"sourcesContent": ["/**\n * A saved workflow's run (a thread its trigger or \"Run now\" started on the server) starts\n * untitled: the server holds no workspace key to write a title, and there is no question of the\n * person's to name it after. Thread lists name it after its workflow and the day it started, and\n * the open one is titled so on the server once, so every other list shows the same name.\n */\n\nimport { useEffect, useMemo, useRef } from 'react'\nimport { useQueryClient } from '@tanstack/react-query'\nimport { arbiQueryKeys } from '../hooks'\nimport { useArbi } from '../useArbi'\nimport { useCanEditShared, useUpdateConversation, useWorkflows } from '../workforce'\n\n/** An untitled run's name: the workflow and the day it started (\"Weekly review \u2014 28 Oct\"). */\nexport function workflowRunTitle(workflowName: string, createdAt: string): string {\n const day = new Date(createdAt).toLocaleDateString(undefined, { day: 'numeric', month: 'short' })\n return `${workflowName} \u2014 ${day}`\n}\n\n/** What a run's name is made from (a conversation list's row). */\nexport interface WorkflowRunRow {\n external_id: string\n title?: string | null\n workflow_ext_id?: string | null\n created_at?: string | null\n is_owner?: boolean\n is_shared?: boolean\n}\n\n/**\n * Names for the untitled saved-workflow runs among `conversations` (the list of `workspaceId`),\n * by id (runs of a workflow the caller cannot list keep no name). The open one (`openId`) is\n * titled with its name on the server, when the viewer may edit it (its owner, or an editor of a\n * shared one) and it is still untitled when the list is read again just before (a rename in\n * another tab wins).\n */\nexport function useWorkflowRunTitles(\n conversations: readonly WorkflowRunRow[],\n openId: string | null,\n workspaceId: string | undefined\n): Record<string, string> {\n const hasUntitledRun = conversations.some((c) => !c.title && c.workflow_ext_id && c.created_at)\n const { data: workflows } = useWorkflows({ enabled: hasUntitledRun })\n const titles = useMemo(() => {\n const names = new Map((workflows ?? []).map((w) => [w.external_id, w.name]))\n const out: Record<string, string> = {}\n for (const c of conversations) {\n const name = !c.title && c.workflow_ext_id ? names.get(c.workflow_ext_id) : undefined\n if (name && c.created_at) out[c.external_id] = workflowRunTitle(name, c.created_at)\n }\n return out\n }, [workflows, conversations])\n\n const arbi = useArbi()\n const queryClient = useQueryClient()\n const canEditShared = useCanEditShared()\n const { mutateAsync: rename } = useUpdateConversation()\n const titled = useRef(new Set<string>())\n const open = openId ? conversations.find((c) => c.external_id === openId) : undefined\n const openTitle = openId ? titles[openId] : undefined\n const mayEdit = !!open && (open.is_owner === true || (open.is_shared === true && canEditShared))\n useEffect(() => {\n if (!openId || !openTitle || !mayEdit || !workspaceId || titled.current.has(openId)) return\n titled.current.add(openId)\n void (async () => {\n // The list as the server has it now, not as cached: a title given meanwhile is kept.\n const fresh = await queryClient.fetchQuery({\n queryKey: arbiQueryKeys.conversations(workspaceId),\n queryFn: () => arbi.conversations.list({ workspaceId }),\n staleTime: 0,\n })\n if (fresh.find((c) => c.external_id === openId)?.title) return\n await rename({ conversationId: openId, patch: { title: openTitle } })\n })().catch(() => {\n // Naming is a courtesy: the list keeps showing the name either way.\n })\n }, [openId, openTitle, mayEdit, workspaceId, arbi, queryClient, rename])\n return titles\n}\n"],
|
|
5
|
+
"mappings": "AAOA,SAAS,WAAW,SAAS,cAAc;AAC3C,SAAS,sBAAsB;AAC/B,SAAS,qBAAqB;AAC9B,SAAS,eAAe;AACxB,SAAS,kBAAkB,uBAAuB,oBAAoB;AAG/D,SAAS,iBAAiB,cAAsB,WAA2B;AAChF,QAAM,MAAM,IAAI,KAAK,SAAS,EAAE,mBAAmB,QAAW,EAAE,KAAK,WAAW,OAAO,QAAQ,CAAC;AAChG,SAAO,GAAG,YAAY,WAAM,GAAG;AACjC;AAmBO,SAAS,qBACd,eACA,QACA,aACwB;AACxB,QAAM,iBAAiB,cAAc,KAAK,CAAC,MAAM,CAAC,EAAE,SAAS,EAAE,mBAAmB,EAAE,UAAU;AAC9F,QAAM,EAAE,MAAM,UAAU,IAAI,aAAa,EAAE,SAAS,eAAe,CAAC;AACpE,QAAM,SAAS,QAAQ,MAAM;AAC3B,UAAM,QAAQ,IAAI,KAAK,aAAa,CAAC,GAAG,IAAI,CAAC,MAAM,CAAC,EAAE,aAAa,EAAE,IAAI,CAAC,CAAC;AAC3E,UAAM,MAA8B,CAAC;AACrC,eAAW,KAAK,eAAe;AAC7B,YAAM,OAAO,CAAC,EAAE,SAAS,EAAE,kBAAkB,MAAM,IAAI,EAAE,eAAe,IAAI;AAC5E,UAAI,QAAQ,EAAE,WAAY,KAAI,EAAE,WAAW,IAAI,iBAAiB,MAAM,EAAE,UAAU;AAAA,IACpF;AACA,WAAO;AAAA,EACT,GAAG,CAAC,WAAW,aAAa,CAAC;AAE7B,QAAM,OAAO,QAAQ;AACrB,QAAM,cAAc,eAAe;AACnC,QAAM,gBAAgB,iBAAiB;AACvC,QAAM,EAAE,aAAa,OAAO,IAAI,sBAAsB;AACtD,QAAM,SAAS,OAAO,oBAAI,IAAY,CAAC;AACvC,QAAM,OAAO,SAAS,cAAc,KAAK,CAAC,MAAM,EAAE,gBAAgB,MAAM,IAAI;AAC5E,QAAM,YAAY,SAAS,OAAO,MAAM,IAAI;AAC5C,QAAM,UAAU,CAAC,CAAC,SAAS,KAAK,aAAa,QAAS,KAAK,cAAc,QAAQ;AACjF,YAAU,MAAM;AACd,QAAI,CAAC,UAAU,CAAC,aAAa,CAAC,WAAW,CAAC,eAAe,OAAO,QAAQ,IAAI,MAAM,EAAG;AACrF,WAAO,QAAQ,IAAI,MAAM;AACzB,UAAM,YAAY;AAEhB,YAAM,QAAQ,MAAM,YAAY,WAAW;AAAA,QACzC,UAAU,cAAc,cAAc,WAAW;AAAA,QACjD,SAAS,MAAM,KAAK,cAAc,KAAK,EAAE,YAAY,CAAC;AAAA,QACtD,WAAW;AAAA,MACb,CAAC;AACD,UAAI,MAAM,KAAK,CAAC,MAAM,EAAE,gBAAgB,MAAM,GAAG,MAAO;AACxD,YAAM,OAAO,EAAE,gBAAgB,QAAQ,OAAO,EAAE,OAAO,UAAU,EAAE,CAAC;AAAA,IACtE,GAAG,EAAE,MAAM,MAAM;AAAA,IAEjB,CAAC;AAAA,EACH,GAAG,CAAC,QAAQ,WAAW,SAAS,aAAa,MAAM,aAAa,MAAM,CAAC;AACvE,SAAO;AACT;",
|
|
6
|
+
"names": []
|
|
7
|
+
}
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
'use strict';
|
|
2
2
|
|
|
3
|
-
var
|
|
3
|
+
var chunkO32T7XRD_cjs = require('./chunk-O32T7XRD.cjs');
|
|
4
4
|
var chunkNDIKMOBJ_cjs = require('./chunk-NDIKMOBJ.cjs');
|
|
5
5
|
var react = require('react');
|
|
6
6
|
var jsxRuntime = require('react/jsx-runtime');
|
|
@@ -47,7 +47,7 @@ function certificateLink(signature, certificateUrl) {
|
|
|
47
47
|
}
|
|
48
48
|
var DocumentToolsContext = react.createContext(null);
|
|
49
49
|
function DocumentToolsProvider({ children, ...env }) {
|
|
50
|
-
const arbiDeploymentDomain =
|
|
50
|
+
const arbiDeploymentDomain = chunkO32T7XRD_cjs.useDeploymentDomain();
|
|
51
51
|
const guards = react.useRef(/* @__PURE__ */ new Map());
|
|
52
52
|
const pendingFlushes = react.useRef(/* @__PURE__ */ new Map());
|
|
53
53
|
const registerBeforeFileShare = react.useCallback((id, flush) => {
|
|
@@ -260,5 +260,5 @@ exports.isSignedVersion = isSignedVersion;
|
|
|
260
260
|
exports.uploadQueryString = uploadQueryString;
|
|
261
261
|
exports.useDocumentTools = useDocumentTools;
|
|
262
262
|
exports.useOptionalDocumentTools = useOptionalDocumentTools;
|
|
263
|
-
//# sourceMappingURL=chunk-
|
|
264
|
-
//# sourceMappingURL=chunk-
|
|
263
|
+
//# sourceMappingURL=chunk-3JAEX57E.cjs.map
|
|
264
|
+
//# sourceMappingURL=chunk-3JAEX57E.cjs.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"sources":["../src/document-tools/environment.tsx","../src/document-tools/document-pdf.ts","../src/document-tools/markup-download.ts"],"names":["createContext","useDeploymentDomain","useRef","useCallback","useMemo","jsx","useContext","parseVersionRef"],"mappings":"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","file":"chunk-W2FATOTX.cjs","sourcesContent":["/**\n * The host app's side of the document tools (markup, freeze, e-signing, versions): the one place\n * the tools reach the app. They never import a store, a router, a toast library or app API code;\n * the host passes what it has to `<DocumentToolsProvider>` and every optional field has a default.\n *\n * `client` is an openapi-fetch client for the ARBI API (`ArbiClient['fetch']` from\n * `@arbidocs/client`, or `arbi.getClient().fetch` from an `@arbidocs/sdk` `Arbi`), signed in with the\n * user's session; it carries the auth.\n */\n\nimport { createContext, useCallback, useContext, useMemo, useRef, type ReactNode } from 'react'\nimport type { ArbiClient, operations } from '@arbidocs/client'\nimport { useDeploymentDomain } from '../useArbi'\n\nexport type DocumentToolsClient = ArbiClient['fetch']\n\nexport type DocumentToolsNoticeKind = 'success' | 'error' | 'info' | 'warning'\n\nexport interface DocumentToolsNoticeOptions {\n /** A second line under the message. */\n description?: string\n /** One action button on the notice (\"Email it\"). */\n action?: { label: string; onClick: () => void }\n}\n\nexport type DocumentToolsNotify = (\n message: string,\n kind: DocumentToolsNoticeKind,\n options?: DocumentToolsNoticeOptions\n) => void\n\nexport interface DocumentToolsUser {\n /** The name marks are authored as and the signer's name is prefilled with. */\n name: string\n /** The sign-in email: signing re-derives the user's key from it and the password. */\n email?: string | null\n /** The user's id (usr-*): which fields of a signature request are theirs. */\n externalId?: string | null\n}\n\n/** What changed about a document, so the host can refresh its own lists and caches. */\nexport type DocumentChange =\n /** A version's markup got its first mark or lost its last one. */\n | 'markup'\n /** A signature was added: the document has a new current version. */\n | 'signed'\n /** A new document was made from it (a frozen copy). The ids are the NEW documents. */\n | 'copy'\n /** A new version was saved (the Word editor's Save version): the document's current version. */\n | 'version'\n\n/**\n * The `/v1/document/upload` query, typed from the API schema: `derived_from` is a list (a\n * production set is derived from every document in it), `shared` a boolean.\n */\nexport type DocumentUploadQuery = NonNullable<operations['upload_documents']['parameters']['query']>\n\nexport interface DocumentUploadRequest {\n file: File\n /** `/v1/document/upload` query: `derived_from`, `derived_role`, `shared`, `folder`. */\n query: DocumentUploadQuery\n}\n\n/**\n * The upload query as a URL query string, for a host that posts the upload itself (an XHR with\n * progress): a list repeats its key (`derived_from=a&derived_from=b`), empty values are left out.\n */\nexport function uploadQueryString(query: DocumentUploadQuery): string {\n const params = new URLSearchParams()\n for (const [key, value] of Object.entries(query)) {\n if (value === null || value === undefined) continue\n for (const item of Array.isArray(value) ? value : [value]) params.append(key, String(item))\n }\n return params.toString()\n}\n\nexport interface DocumentToolsEnvironment {\n client: DocumentToolsClient\n /**\n * The deployment domain the user's keys are derived for. Needed for signing. Default: the one\n * the host's `Arbi` computes (`arbi.getDeploymentDomain()`), if any.\n */\n deploymentDomain?: string\n /** The signed-in user; marks are authored as \"You\" without one, and signing is unavailable. */\n user?: DocumentToolsUser | null\n /** Surface a transient message. Default: none (errors still show inline where they can). */\n notify?: DocumentToolsNotify\n /** Open a document or a version reference (`doc-…@v2`): the copy just made, the signed copy. */\n openDocument?: (documentRef: string) => void\n /**\n * Documents changed on the server (see {@link DocumentChange}); refresh the host's lists. The\n * tools wait for it before opening the document, so a copy is listed when it opens.\n */\n onDocumentsChanged?: (documentIds: string[], change: DocumentChange) => void | Promise<void>\n /** Upload a derived copy. Default: `POST /v1/document/upload` through `client`. */\n uploadDocument?: (\n request: DocumentUploadRequest\n ) => Promise<{ doc_ext_ids?: string[] } | undefined>\n /** Save a file to the user's computer. Default: a temporary download link. */\n saveFile?: (blob: Blob, fileName: string) => void\n /** Email a document (offered once it is signed). Omitted: no \"Email it\". */\n emailDocument?: (documentRef: string) => void\n /**\n * The public page that checks a signature (the certificate) in this app. When given, \"View\n * certificate\" opens it in preference to the backend's `certificate_url` (which is on the\n * deployment domain, like the link embedded in the signed PDF). Without it: the backend's\n * `certificate_url`, else `/verify/{reference}` on this origin.\n */\n certificateUrl?: (reference: string) => string\n}\n\n/** The environment with every default filled in. */\nexport interface ResolvedDocumentToolsEnvironment extends DocumentToolsEnvironment {\n prepareFileShare: (documentId: string) => Promise<void>\n registerBeforeFileShare: (documentId: string, flush: () => Promise<void>) => () => void\n notify: DocumentToolsNotify\n saveFile: (blob: Blob, fileName: string) => void\n uploadDocument: (\n request: DocumentUploadRequest\n ) => Promise<{ doc_ext_ids?: string[] } | undefined>\n}\n\n/**\n * Save a blob through a temporary `<a download>`. The object URL is revoked a minute later, not at\n * once: revoking straight after `click()` can cancel the download (Safari, and large files\n * elsewhere) before the browser has read the blob.\n */\nexport function downloadBlob(blob: Blob, fileName: string): void {\n const url = URL.createObjectURL(blob)\n const a = document.createElement('a')\n a.href = url\n a.download = fileName\n document.body.appendChild(a)\n a.click()\n a.remove()\n setTimeout(() => URL.revokeObjectURL(url), 60_000)\n}\n\n/** The default upload: multipart `files` to `/v1/document/upload` through the API client. */\nexport function clientUpload(client: DocumentToolsClient) {\n return async ({ file, query }: DocumentUploadRequest) => {\n const formData = new FormData()\n formData.append('files', file)\n const { data, response } = await client.POST('/v1/document/upload', {\n params: { query },\n // The schema types the multipart body as `{ files: string[] }`; the FormData is sent as is.\n body: formData as unknown as { files: string[] },\n bodySerializer: () => formData,\n })\n if (!response.ok) throw new Error(`Upload failed with status ${response.status}`)\n return data\n }\n}\n\nexport function defaultCertificateUrl(reference: string): string {\n const origin = typeof location === 'undefined' ? '' : location.origin\n return `${origin}/verify/${encodeURIComponent(reference)}`\n}\n\n/**\n * Where \"View certificate\" goes for a signature: the host's `certificateUrl(reference)` when it\n * gives one, else the `certificate_url` the backend returned, else `/verify/{reference}` here.\n */\nexport function certificateLink(\n signature: { reference: string; certificate_url?: string | null },\n certificateUrl?: (reference: string) => string\n): string {\n if (certificateUrl) return certificateUrl(signature.reference)\n return signature.certificate_url || defaultCertificateUrl(signature.reference)\n}\n\nconst DocumentToolsContext = createContext<ResolvedDocumentToolsEnvironment | null>(null)\n\nexport interface DocumentToolsProviderProps extends DocumentToolsEnvironment {\n children: ReactNode\n}\n\nexport function DocumentToolsProvider({ children, ...env }: DocumentToolsProviderProps) {\n const arbiDeploymentDomain = useDeploymentDomain()\n const guards = useRef(new Map<string, () => Promise<void>>())\n const pendingFlushes = useRef(new Map<string, Promise<void>>())\n const registerBeforeFileShare = useCallback((id: string, flush: () => Promise<void>) => {\n guards.current.set(id, flush)\n return () => {\n if (guards.current.get(id) !== flush) return\n guards.current.delete(id)\n const pending = flush()\n pendingFlushes.current.set(id, pending)\n void pending.then(\n () => {\n if (pendingFlushes.current.get(id) === pending) pendingFlushes.current.delete(id)\n },\n () => {}\n )\n }\n }, [])\n const prepareFileShare = useCallback(async (id: string) => {\n const guard = guards.current.get(id)\n if (guard) {\n await guard()\n pendingFlushes.current.delete(id)\n } else await pendingFlushes.current.get(id)\n }, [])\n const {\n client,\n deploymentDomain,\n user,\n notify,\n openDocument,\n onDocumentsChanged,\n uploadDocument,\n saveFile,\n emailDocument,\n certificateUrl,\n } = env\n const value = useMemo<ResolvedDocumentToolsEnvironment>(\n () => ({\n client,\n prepareFileShare,\n registerBeforeFileShare,\n deploymentDomain: deploymentDomain ?? arbiDeploymentDomain,\n user,\n openDocument,\n onDocumentsChanged,\n emailDocument,\n notify: notify ?? (() => {}),\n saveFile: saveFile ?? downloadBlob,\n uploadDocument: uploadDocument ?? clientUpload(client),\n certificateUrl,\n }),\n [\n client,\n prepareFileShare,\n registerBeforeFileShare,\n deploymentDomain,\n arbiDeploymentDomain,\n user,\n notify,\n openDocument,\n onDocumentsChanged,\n uploadDocument,\n saveFile,\n emailDocument,\n certificateUrl,\n ]\n )\n return <DocumentToolsContext.Provider value={value}>{children}</DocumentToolsContext.Provider>\n}\n\n/** The host's environment, or `null` outside a `<DocumentToolsProvider>`. */\nexport function useOptionalDocumentTools(): ResolvedDocumentToolsEnvironment | null {\n return useContext(DocumentToolsContext)\n}\n\n/** The host's environment; throws outside a `<DocumentToolsProvider>`. */\nexport function useDocumentTools(): ResolvedDocumentToolsEnvironment {\n const env = useContext(DocumentToolsContext)\n if (!env) throw new Error('The document tools must be used within a <DocumentToolsProvider>')\n return env\n}\n","/**\n * A document's bytes, through the host's API client: the PDF the viewer and the tools draw on\n * (`/view`: the file itself for a PDF, its PDF rendering for a Word or text file) and the stored\n * file (`/download`). Either takes a document id or a version reference `doc-…@v{n}`.\n */\n\nimport { parseVersionRef } from '../artifacts/versions'\nimport type { DocumentToolsClient } from './environment'\n\nexport interface DocumentFetchOptions {\n /** The version to fetch. Default: the one `documentRef` names, else the current version. */\n version?: number | null\n workspaceExtId?: string\n signal?: AbortSignal\n}\n\n/** A document's bytes could not be fetched; `status` is the HTTP status. */\nexport class DocumentFetchError extends Error {\n readonly status: number\n constructor(message: string, status: number) {\n super(message)\n this.name = 'DocumentFetchError'\n this.status = status\n }\n}\n\nasync function fetchDocumentBytes(\n client: DocumentToolsClient,\n endpoint: '/v1/document/{document_ext_id}/view' | '/v1/document/{document_ext_id}/download',\n documentRef: string,\n options: DocumentFetchOptions,\n headers: Record<string, string>,\n what: string\n): Promise<{ blob: Blob; response: Response }> {\n const ref = parseVersionRef(documentRef)\n const version = options.version ?? ref.version\n const { data, response } = await client.GET(endpoint, {\n params: {\n path: { document_ext_id: ref.docId },\n query: {\n ...(version ? { version } : {}),\n ...(options.workspaceExtId ? { workspace_ext_id: options.workspaceExtId } : {}),\n },\n },\n headers,\n parseAs: 'blob',\n signal: options.signal,\n })\n if (!response.ok || !(data instanceof Blob)) {\n throw new DocumentFetchError(\n `${what} could not be loaded (${response.status})`,\n response.status\n )\n }\n return { blob: data, response }\n}\n\n/**\n * The file name a `Content-Disposition` header gives, or `undefined`. Prefers the RFC 5987\n * `filename*=UTF-8''…` form (percent-encoded, any script) over the plain `filename=`.\n */\nexport function contentDispositionFileName(header: string | null | undefined): string | undefined {\n if (!header) return undefined\n const extended = /filename\\*\\s*=\\s*(?:[\\w-]+)?'[^']*'([^;]+)/i.exec(header)\n if (extended) {\n try {\n return decodeURIComponent(extended[1].trim().replace(/^\"|\"$/g, '')) || undefined\n } catch {\n // A malformed escape: fall back to the plain parameter.\n }\n }\n const plain = /filename\\s*=\\s*(\"((?:[^\"\\\\]|\\\\.)*)\"|[^;]+)/i.exec(header)\n if (!plain) return undefined\n const name = plain[2] !== undefined ? plain[2].replace(/\\\\(.)/g, '$1') : plain[1].trim()\n return name || undefined\n}\n\n/**\n * The PDF of a document version: `GET /v1/document/{id}/view?version=` with\n * `Accept: application/pdf`. Throws a {@link DocumentFetchError} when there is none (yet).\n */\nexport async function fetchDocumentPdf(\n client: DocumentToolsClient,\n documentRef: string,\n options: DocumentFetchOptions = {}\n): Promise<Blob> {\n const { blob } = await fetchDocumentBytes(\n client,\n '/v1/document/{document_ext_id}/view',\n documentRef,\n options,\n { Accept: 'application/pdf' },\n 'The PDF'\n )\n return blob\n}\n\n/**\n * The stored file of a document version, as uploaded: `GET /v1/document/{id}/download`. When the\n * server names the file (`Content-Disposition`), the result is a `File` carrying that name.\n */\nexport async function fetchDocumentFile(\n client: DocumentToolsClient,\n documentRef: string,\n options: DocumentFetchOptions = {}\n): Promise<Blob | File> {\n const { blob, response } = await fetchDocumentBytes(\n client,\n '/v1/document/{document_ext_id}/download',\n documentRef,\n options,\n {},\n 'The file'\n )\n const name = contentDispositionFileName(response.headers.get('Content-Disposition'))\n return name ? new File([blob], name, { type: blob.type }) : blob\n}\n","/**\n * \"Download with markup\": a document version's markup PDF, the PDF with its annotations as native\n * PDF annotations (comments, highlights, stamps, unapplied redactions), which Acrobat and Preview\n * show. The plain Download serves the original. Kept apart from the annotation layer code so a\n * documents list can offer it without loading the annotation tools.\n *\n * A SIGNED version is locked: nothing but a further signature changes it. Its markup stays in the\n * separate markup layer (a title beside the signature, say) and is never written into its PDF, so\n * it has no \"Download with markup\"; the plain Download is the signed file as it is.\n */\n\nimport type { DocumentToolsClient } from './environment'\n\ninterface DocumentVersions {\n current_version?: number | null\n versions?: Array<{ n: number; markup_count?: number | null; reason?: string | null }> | null\n}\n\n/** Why \"Download with markup\" is off for a signed version. */\nexport const SIGNED_LOCKED_REASON =\n \"Signed documents can't be changed — download the signed file instead\"\n\n/** Whether a version (default: the current one) is a signed copy, per its version entry. */\nexport function isSignedVersion(doc: DocumentVersions, version?: number): boolean {\n const n = version ?? doc.current_version ?? 1\n return (doc.versions ?? []).some((v) => v.n === n && v.reason === 'signed')\n}\n\nexport class MarkupDownloadError extends Error {\n constructor(\n message: string,\n readonly status?: number\n ) {\n super(message)\n this.name = 'MarkupDownloadError'\n }\n}\n\n/** Whether a document's current version has markup (per its version entries). */\nexport function currentHasMarkup(doc: DocumentVersions): boolean {\n const n = doc.current_version ?? 1\n return (doc.versions ?? []).some((v) => v.n === n && (v.markup_count ?? 0) > 0)\n}\n\n/** Fetch a version's markup PDF (default: the current version's). */\nexport async function fetchMarkupPdf(\n client: DocumentToolsClient,\n documentId: string,\n version?: number,\n workspaceExtId?: string\n): Promise<{ blob: Blob; fileName: string }> {\n const { data, response } = await client.GET('/v1/document/{document_ext_id}/markup/pdf', {\n params: {\n path: { document_ext_id: documentId },\n query: {\n ...(version ? { version } : {}),\n ...(workspaceExtId ? { workspace_ext_id: workspaceExtId } : {}),\n },\n },\n parseAs: 'blob',\n })\n if (!response.ok || !data) {\n throw new MarkupDownloadError(\n response.status === 404\n ? 'This document has no markup yet'\n : // The server refuses a signed version: its PDF takes no more changes.\n response.status === 409\n ? SIGNED_LOCKED_REASON\n : 'The markup could not be downloaded',\n response.status\n )\n }\n const disposition = response.headers.get('content-disposition') ?? ''\n const utf8 = /filename\\*=UTF-8''([^;]+)/i.exec(disposition)?.[1]\n const plain = /filename=\"([^\"]+)\"/i.exec(disposition)?.[1]\n const fileName = utf8 ? decodeURIComponent(utf8) : (plain ?? 'markup.pdf')\n return { blob: data as Blob, fileName }\n}\n"]}
|
|
1
|
+
{"version":3,"sources":["../src/document-tools/environment.tsx","../src/document-tools/document-pdf.ts","../src/document-tools/markup-download.ts"],"names":["createContext","useDeploymentDomain","useRef","useCallback","useMemo","jsx","useContext","parseVersionRef"],"mappings":"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","file":"chunk-3JAEX57E.cjs","sourcesContent":["/**\n * The host app's side of the document tools (markup, freeze, e-signing, versions): the one place\n * the tools reach the app. They never import a store, a router, a toast library or app API code;\n * the host passes what it has to `<DocumentToolsProvider>` and every optional field has a default.\n *\n * `client` is an openapi-fetch client for the ARBI API (`ArbiClient['fetch']` from\n * `@arbidocs/client`, or `arbi.getClient().fetch` from an `@arbidocs/sdk` `Arbi`), signed in with the\n * user's session; it carries the auth.\n */\n\nimport { createContext, useCallback, useContext, useMemo, useRef, type ReactNode } from 'react'\nimport type { ArbiClient, operations } from '@arbidocs/client'\nimport { useDeploymentDomain } from '../useArbi'\n\nexport type DocumentToolsClient = ArbiClient['fetch']\n\nexport type DocumentToolsNoticeKind = 'success' | 'error' | 'info' | 'warning'\n\nexport interface DocumentToolsNoticeOptions {\n /** A second line under the message. */\n description?: string\n /** One action button on the notice (\"Email it\"). */\n action?: { label: string; onClick: () => void }\n}\n\nexport type DocumentToolsNotify = (\n message: string,\n kind: DocumentToolsNoticeKind,\n options?: DocumentToolsNoticeOptions\n) => void\n\nexport interface DocumentToolsUser {\n /** The name marks are authored as and the signer's name is prefilled with. */\n name: string\n /** The sign-in email: signing re-derives the user's key from it and the password. */\n email?: string | null\n /** The user's id (usr-*): which fields of a signature request are theirs. */\n externalId?: string | null\n}\n\n/** What changed about a document, so the host can refresh its own lists and caches. */\nexport type DocumentChange =\n /** A version's markup got its first mark or lost its last one. */\n | 'markup'\n /** A signature was added: the document has a new current version. */\n | 'signed'\n /** A new document was made from it (a frozen copy). The ids are the NEW documents. */\n | 'copy'\n /** A new version was saved (the Word editor's Save version): the document's current version. */\n | 'version'\n\n/**\n * The `/v1/document/upload` query, typed from the API schema: `derived_from` is a list (a\n * production set is derived from every document in it), `shared` a boolean.\n */\nexport type DocumentUploadQuery = NonNullable<operations['upload_documents']['parameters']['query']>\n\nexport interface DocumentUploadRequest {\n file: File\n /** `/v1/document/upload` query: `derived_from`, `derived_role`, `shared`, `folder`. */\n query: DocumentUploadQuery\n}\n\n/**\n * The upload query as a URL query string, for a host that posts the upload itself (an XHR with\n * progress): a list repeats its key (`derived_from=a&derived_from=b`), empty values are left out.\n */\nexport function uploadQueryString(query: DocumentUploadQuery): string {\n const params = new URLSearchParams()\n for (const [key, value] of Object.entries(query)) {\n if (value === null || value === undefined) continue\n for (const item of Array.isArray(value) ? value : [value]) params.append(key, String(item))\n }\n return params.toString()\n}\n\nexport interface DocumentToolsEnvironment {\n client: DocumentToolsClient\n /**\n * The deployment domain the user's keys are derived for. Needed for signing. Default: the one\n * the host's `Arbi` computes (`arbi.getDeploymentDomain()`), if any.\n */\n deploymentDomain?: string\n /** The signed-in user; marks are authored as \"You\" without one, and signing is unavailable. */\n user?: DocumentToolsUser | null\n /** Surface a transient message. Default: none (errors still show inline where they can). */\n notify?: DocumentToolsNotify\n /** Open a document or a version reference (`doc-…@v2`): the copy just made, the signed copy. */\n openDocument?: (documentRef: string) => void\n /**\n * Documents changed on the server (see {@link DocumentChange}); refresh the host's lists. The\n * tools wait for it before opening the document, so a copy is listed when it opens.\n */\n onDocumentsChanged?: (documentIds: string[], change: DocumentChange) => void | Promise<void>\n /** Upload a derived copy. Default: `POST /v1/document/upload` through `client`. */\n uploadDocument?: (\n request: DocumentUploadRequest\n ) => Promise<{ doc_ext_ids?: string[] } | undefined>\n /** Save a file to the user's computer. Default: a temporary download link. */\n saveFile?: (blob: Blob, fileName: string) => void\n /** Email a document (offered once it is signed). Omitted: no \"Email it\". */\n emailDocument?: (documentRef: string) => void\n /**\n * The public page that checks a signature (the certificate) in this app. When given, \"View\n * certificate\" opens it in preference to the backend's `certificate_url` (which is on the\n * deployment domain, like the link embedded in the signed PDF). Without it: the backend's\n * `certificate_url`, else `/verify/{reference}` on this origin.\n */\n certificateUrl?: (reference: string) => string\n}\n\n/** The environment with every default filled in. */\nexport interface ResolvedDocumentToolsEnvironment extends DocumentToolsEnvironment {\n prepareFileShare: (documentId: string) => Promise<void>\n registerBeforeFileShare: (documentId: string, flush: () => Promise<void>) => () => void\n notify: DocumentToolsNotify\n saveFile: (blob: Blob, fileName: string) => void\n uploadDocument: (\n request: DocumentUploadRequest\n ) => Promise<{ doc_ext_ids?: string[] } | undefined>\n}\n\n/**\n * Save a blob through a temporary `<a download>`. The object URL is revoked a minute later, not at\n * once: revoking straight after `click()` can cancel the download (Safari, and large files\n * elsewhere) before the browser has read the blob.\n */\nexport function downloadBlob(blob: Blob, fileName: string): void {\n const url = URL.createObjectURL(blob)\n const a = document.createElement('a')\n a.href = url\n a.download = fileName\n document.body.appendChild(a)\n a.click()\n a.remove()\n setTimeout(() => URL.revokeObjectURL(url), 60_000)\n}\n\n/** The default upload: multipart `files` to `/v1/document/upload` through the API client. */\nexport function clientUpload(client: DocumentToolsClient) {\n return async ({ file, query }: DocumentUploadRequest) => {\n const formData = new FormData()\n formData.append('files', file)\n const { data, response } = await client.POST('/v1/document/upload', {\n params: { query },\n // The schema types the multipart body as `{ files: string[] }`; the FormData is sent as is.\n body: formData as unknown as { files: string[] },\n bodySerializer: () => formData,\n })\n if (!response.ok) throw new Error(`Upload failed with status ${response.status}`)\n return data\n }\n}\n\nexport function defaultCertificateUrl(reference: string): string {\n const origin = typeof location === 'undefined' ? '' : location.origin\n return `${origin}/verify/${encodeURIComponent(reference)}`\n}\n\n/**\n * Where \"View certificate\" goes for a signature: the host's `certificateUrl(reference)` when it\n * gives one, else the `certificate_url` the backend returned, else `/verify/{reference}` here.\n */\nexport function certificateLink(\n signature: { reference: string; certificate_url?: string | null },\n certificateUrl?: (reference: string) => string\n): string {\n if (certificateUrl) return certificateUrl(signature.reference)\n return signature.certificate_url || defaultCertificateUrl(signature.reference)\n}\n\nconst DocumentToolsContext = createContext<ResolvedDocumentToolsEnvironment | null>(null)\n\nexport interface DocumentToolsProviderProps extends DocumentToolsEnvironment {\n children: ReactNode\n}\n\nexport function DocumentToolsProvider({ children, ...env }: DocumentToolsProviderProps) {\n const arbiDeploymentDomain = useDeploymentDomain()\n const guards = useRef(new Map<string, () => Promise<void>>())\n const pendingFlushes = useRef(new Map<string, Promise<void>>())\n const registerBeforeFileShare = useCallback((id: string, flush: () => Promise<void>) => {\n guards.current.set(id, flush)\n return () => {\n if (guards.current.get(id) !== flush) return\n guards.current.delete(id)\n const pending = flush()\n pendingFlushes.current.set(id, pending)\n void pending.then(\n () => {\n if (pendingFlushes.current.get(id) === pending) pendingFlushes.current.delete(id)\n },\n () => {}\n )\n }\n }, [])\n const prepareFileShare = useCallback(async (id: string) => {\n const guard = guards.current.get(id)\n if (guard) {\n await guard()\n pendingFlushes.current.delete(id)\n } else await pendingFlushes.current.get(id)\n }, [])\n const {\n client,\n deploymentDomain,\n user,\n notify,\n openDocument,\n onDocumentsChanged,\n uploadDocument,\n saveFile,\n emailDocument,\n certificateUrl,\n } = env\n const value = useMemo<ResolvedDocumentToolsEnvironment>(\n () => ({\n client,\n prepareFileShare,\n registerBeforeFileShare,\n deploymentDomain: deploymentDomain ?? arbiDeploymentDomain,\n user,\n openDocument,\n onDocumentsChanged,\n emailDocument,\n notify: notify ?? (() => {}),\n saveFile: saveFile ?? downloadBlob,\n uploadDocument: uploadDocument ?? clientUpload(client),\n certificateUrl,\n }),\n [\n client,\n prepareFileShare,\n registerBeforeFileShare,\n deploymentDomain,\n arbiDeploymentDomain,\n user,\n notify,\n openDocument,\n onDocumentsChanged,\n uploadDocument,\n saveFile,\n emailDocument,\n certificateUrl,\n ]\n )\n return <DocumentToolsContext.Provider value={value}>{children}</DocumentToolsContext.Provider>\n}\n\n/** The host's environment, or `null` outside a `<DocumentToolsProvider>`. */\nexport function useOptionalDocumentTools(): ResolvedDocumentToolsEnvironment | null {\n return useContext(DocumentToolsContext)\n}\n\n/** The host's environment; throws outside a `<DocumentToolsProvider>`. */\nexport function useDocumentTools(): ResolvedDocumentToolsEnvironment {\n const env = useContext(DocumentToolsContext)\n if (!env) throw new Error('The document tools must be used within a <DocumentToolsProvider>')\n return env\n}\n","/**\n * A document's bytes, through the host's API client: the PDF the viewer and the tools draw on\n * (`/view`: the file itself for a PDF, its PDF rendering for a Word or text file) and the stored\n * file (`/download`). Either takes a document id or a version reference `doc-…@v{n}`.\n */\n\nimport { parseVersionRef } from '../artifacts/versions'\nimport type { DocumentToolsClient } from './environment'\n\nexport interface DocumentFetchOptions {\n /** The version to fetch. Default: the one `documentRef` names, else the current version. */\n version?: number | null\n workspaceExtId?: string\n signal?: AbortSignal\n}\n\n/** A document's bytes could not be fetched; `status` is the HTTP status. */\nexport class DocumentFetchError extends Error {\n readonly status: number\n constructor(message: string, status: number) {\n super(message)\n this.name = 'DocumentFetchError'\n this.status = status\n }\n}\n\nasync function fetchDocumentBytes(\n client: DocumentToolsClient,\n endpoint: '/v1/document/{document_ext_id}/view' | '/v1/document/{document_ext_id}/download',\n documentRef: string,\n options: DocumentFetchOptions,\n headers: Record<string, string>,\n what: string\n): Promise<{ blob: Blob; response: Response }> {\n const ref = parseVersionRef(documentRef)\n const version = options.version ?? ref.version\n const { data, response } = await client.GET(endpoint, {\n params: {\n path: { document_ext_id: ref.docId },\n query: {\n ...(version ? { version } : {}),\n ...(options.workspaceExtId ? { workspace_ext_id: options.workspaceExtId } : {}),\n },\n },\n headers,\n parseAs: 'blob',\n signal: options.signal,\n })\n if (!response.ok || !(data instanceof Blob)) {\n throw new DocumentFetchError(\n `${what} could not be loaded (${response.status})`,\n response.status\n )\n }\n return { blob: data, response }\n}\n\n/**\n * The file name a `Content-Disposition` header gives, or `undefined`. Prefers the RFC 5987\n * `filename*=UTF-8''…` form (percent-encoded, any script) over the plain `filename=`.\n */\nexport function contentDispositionFileName(header: string | null | undefined): string | undefined {\n if (!header) return undefined\n const extended = /filename\\*\\s*=\\s*(?:[\\w-]+)?'[^']*'([^;]+)/i.exec(header)\n if (extended) {\n try {\n return decodeURIComponent(extended[1].trim().replace(/^\"|\"$/g, '')) || undefined\n } catch {\n // A malformed escape: fall back to the plain parameter.\n }\n }\n const plain = /filename\\s*=\\s*(\"((?:[^\"\\\\]|\\\\.)*)\"|[^;]+)/i.exec(header)\n if (!plain) return undefined\n const name = plain[2] !== undefined ? plain[2].replace(/\\\\(.)/g, '$1') : plain[1].trim()\n return name || undefined\n}\n\n/**\n * The PDF of a document version: `GET /v1/document/{id}/view?version=` with\n * `Accept: application/pdf`. Throws a {@link DocumentFetchError} when there is none (yet).\n */\nexport async function fetchDocumentPdf(\n client: DocumentToolsClient,\n documentRef: string,\n options: DocumentFetchOptions = {}\n): Promise<Blob> {\n const { blob } = await fetchDocumentBytes(\n client,\n '/v1/document/{document_ext_id}/view',\n documentRef,\n options,\n { Accept: 'application/pdf' },\n 'The PDF'\n )\n return blob\n}\n\n/**\n * The stored file of a document version, as uploaded: `GET /v1/document/{id}/download`. When the\n * server names the file (`Content-Disposition`), the result is a `File` carrying that name.\n */\nexport async function fetchDocumentFile(\n client: DocumentToolsClient,\n documentRef: string,\n options: DocumentFetchOptions = {}\n): Promise<Blob | File> {\n const { blob, response } = await fetchDocumentBytes(\n client,\n '/v1/document/{document_ext_id}/download',\n documentRef,\n options,\n {},\n 'The file'\n )\n const name = contentDispositionFileName(response.headers.get('Content-Disposition'))\n return name ? new File([blob], name, { type: blob.type }) : blob\n}\n","/**\n * \"Download with markup\": a document version's markup PDF, the PDF with its annotations as native\n * PDF annotations (comments, highlights, stamps, unapplied redactions), which Acrobat and Preview\n * show. The plain Download serves the original. Kept apart from the annotation layer code so a\n * documents list can offer it without loading the annotation tools.\n *\n * A SIGNED version is locked: nothing but a further signature changes it. Its markup stays in the\n * separate markup layer (a title beside the signature, say) and is never written into its PDF, so\n * it has no \"Download with markup\"; the plain Download is the signed file as it is.\n */\n\nimport type { DocumentToolsClient } from './environment'\n\ninterface DocumentVersions {\n current_version?: number | null\n versions?: Array<{ n: number; markup_count?: number | null; reason?: string | null }> | null\n}\n\n/** Why \"Download with markup\" is off for a signed version. */\nexport const SIGNED_LOCKED_REASON =\n \"Signed documents can't be changed — download the signed file instead\"\n\n/** Whether a version (default: the current one) is a signed copy, per its version entry. */\nexport function isSignedVersion(doc: DocumentVersions, version?: number): boolean {\n const n = version ?? doc.current_version ?? 1\n return (doc.versions ?? []).some((v) => v.n === n && v.reason === 'signed')\n}\n\nexport class MarkupDownloadError extends Error {\n constructor(\n message: string,\n readonly status?: number\n ) {\n super(message)\n this.name = 'MarkupDownloadError'\n }\n}\n\n/** Whether a document's current version has markup (per its version entries). */\nexport function currentHasMarkup(doc: DocumentVersions): boolean {\n const n = doc.current_version ?? 1\n return (doc.versions ?? []).some((v) => v.n === n && (v.markup_count ?? 0) > 0)\n}\n\n/** Fetch a version's markup PDF (default: the current version's). */\nexport async function fetchMarkupPdf(\n client: DocumentToolsClient,\n documentId: string,\n version?: number,\n workspaceExtId?: string\n): Promise<{ blob: Blob; fileName: string }> {\n const { data, response } = await client.GET('/v1/document/{document_ext_id}/markup/pdf', {\n params: {\n path: { document_ext_id: documentId },\n query: {\n ...(version ? { version } : {}),\n ...(workspaceExtId ? { workspace_ext_id: workspaceExtId } : {}),\n },\n },\n parseAs: 'blob',\n })\n if (!response.ok || !data) {\n throw new MarkupDownloadError(\n response.status === 404\n ? 'This document has no markup yet'\n : // The server refuses a signed version: its PDF takes no more changes.\n response.status === 409\n ? SIGNED_LOCKED_REASON\n : 'The markup could not be downloaded',\n response.status\n )\n }\n const disposition = response.headers.get('content-disposition') ?? ''\n const utf8 = /filename\\*=UTF-8''([^;]+)/i.exec(disposition)?.[1]\n const plain = /filename=\"([^\"]+)\"/i.exec(disposition)?.[1]\n const fileName = utf8 ? decodeURIComponent(utf8) : (plain ?? 'markup.pdf')\n return { blob: data as Blob, fileName }\n}\n"]}
|