@arbidocs/react 0.5.111 → 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.
Files changed (983) hide show
  1. package/dist/account/client.js +96 -0
  2. package/dist/account/client.js.map +7 -0
  3. package/dist/account/delete.js +70 -0
  4. package/dist/account/delete.js.map +7 -0
  5. package/dist/account/didit.js +34 -0
  6. package/dist/account/didit.js.map +7 -0
  7. package/dist/account/dismissed-tips.js +33 -0
  8. package/dist/account/dismissed-tips.js.map +7 -0
  9. package/dist/account/email.js +84 -0
  10. package/dist/account/email.js.map +7 -0
  11. package/dist/account/entitlements.js +47 -0
  12. package/dist/account/entitlements.js.map +7 -0
  13. package/dist/account/identity.js +270 -0
  14. package/dist/account/identity.js.map +7 -0
  15. package/dist/account/index.js +93 -0
  16. package/dist/account/index.js.map +7 -0
  17. package/dist/account/notifications.js +59 -0
  18. package/dist/account/notifications.js.map +7 -0
  19. package/dist/account/password.js +103 -0
  20. package/dist/account/password.js.map +7 -0
  21. package/dist/account/profile.js +116 -0
  22. package/dist/account/profile.js.map +7 -0
  23. package/dist/account/recovery.js +13 -0
  24. package/dist/account/recovery.js.map +7 -0
  25. package/dist/account/relevance.js +82 -0
  26. package/dist/account/relevance.js.map +7 -0
  27. package/dist/account/sessions.js +37 -0
  28. package/dist/account/sessions.js.map +7 -0
  29. package/dist/account/settings.js +39 -0
  30. package/dist/account/settings.js.map +7 -0
  31. package/dist/account/table-views.js +16 -0
  32. package/dist/account/table-views.js.map +7 -0
  33. package/dist/ai/AiAnswer.js +83 -0
  34. package/dist/ai/AiAnswer.js.map +7 -0
  35. package/dist/ai/AiMarkdown.js +40 -0
  36. package/dist/ai/AiMarkdown.js.map +7 -0
  37. package/dist/ai/ArtifactCanvas.js +193 -0
  38. package/dist/ai/ArtifactCanvas.js.map +7 -0
  39. package/dist/ai/CitationRenderer.js +413 -0
  40. package/dist/ai/CitationRenderer.js.map +7 -0
  41. package/dist/{chunk-WL2Y2T47.js → ai/MarkdownRenderer.js} +35 -101
  42. package/dist/ai/MarkdownRenderer.js.map +7 -0
  43. package/dist/ai/MessageArtifactCard.js +75 -0
  44. package/dist/ai/MessageArtifactCard.js.map +7 -0
  45. package/dist/ai/PassageCard.js +79 -0
  46. package/dist/ai/PassageCard.js.map +7 -0
  47. package/dist/ai/engine.js +110 -0
  48. package/dist/ai/engine.js.map +7 -0
  49. package/dist/ai/index.js +63 -0
  50. package/dist/ai/index.js.map +7 -0
  51. package/dist/ai/markdown-base-components.js +37 -0
  52. package/dist/ai/markdown-base-components.js.map +7 -0
  53. package/dist/ai/markdown-streaming-context.js +6 -0
  54. package/dist/ai/markdown-streaming-context.js.map +7 -0
  55. package/dist/{chunk-VSCU7K4V.js → ai/normalize-citations.js} +12 -19
  56. package/dist/ai/normalize-citations.js.map +7 -0
  57. package/dist/ai/redline.js +41 -0
  58. package/dist/ai/redline.js.map +7 -0
  59. package/dist/ai/split-markdown-blocks.js +40 -0
  60. package/dist/ai/split-markdown-blocks.js.map +7 -0
  61. package/dist/{chunk-UW2SGTI5.js → ai/stored-markdown.js} +41 -93
  62. package/dist/ai/stored-markdown.js.map +7 -0
  63. package/dist/annotations/AnnotationPageOverlay.js +807 -0
  64. package/dist/annotations/AnnotationPageOverlay.js.map +7 -0
  65. package/dist/annotations/AnnotationToolbar.js +398 -0
  66. package/dist/annotations/AnnotationToolbar.js.map +7 -0
  67. package/dist/annotations/FreezeDialog.js +170 -0
  68. package/dist/annotations/FreezeDialog.js.map +7 -0
  69. package/dist/annotations/ProductionDialog.js +354 -0
  70. package/dist/annotations/ProductionDialog.js.map +7 -0
  71. package/dist/annotations/controller.js +49 -0
  72. package/dist/annotations/controller.js.map +7 -0
  73. package/dist/annotations/freeze/browser.js +21 -0
  74. package/dist/annotations/freeze/browser.js.map +7 -0
  75. package/dist/annotations/freeze/bundle.js +201 -0
  76. package/dist/annotations/freeze/bundle.js.map +7 -0
  77. package/dist/annotations/freeze/coords.js +37 -0
  78. package/dist/annotations/freeze/coords.js.map +7 -0
  79. package/dist/annotations/freeze/freeze.js +261 -0
  80. package/dist/annotations/freeze/freeze.js.map +7 -0
  81. package/dist/annotations/freeze/hash.js +28 -0
  82. package/dist/annotations/freeze/hash.js.map +7 -0
  83. package/dist/annotations/freeze/index-page.js +78 -0
  84. package/dist/annotations/freeze/index-page.js.map +7 -0
  85. package/dist/annotations/freeze/index.js +28 -22
  86. package/dist/annotations/freeze/index.js.map +7 -1
  87. package/dist/annotations/freeze/raster.js +208 -0
  88. package/dist/annotations/freeze/raster.js.map +7 -0
  89. package/dist/annotations/freeze/stamp.js +117 -0
  90. package/dist/annotations/freeze/stamp.js.map +7 -0
  91. package/dist/annotations/freeze/types.js +14 -0
  92. package/dist/annotations/freeze/types.js.map +7 -0
  93. package/dist/annotations/freeze/vector.js +283 -0
  94. package/dist/annotations/freeze/vector.js.map +7 -0
  95. package/dist/annotations/geometry.js +81 -0
  96. package/dist/annotations/geometry.js.map +7 -0
  97. package/dist/annotations/index.js +125 -6
  98. package/dist/annotations/index.js.map +7 -1
  99. package/dist/annotations/merge.js +53 -0
  100. package/dist/annotations/merge.js.map +7 -0
  101. package/dist/{chunk-T3USOSVN.js → annotations/model.js} +23 -16
  102. package/dist/annotations/model.js.map +7 -0
  103. package/dist/annotations/overlay-geometry.js +41 -0
  104. package/dist/annotations/overlay-geometry.js.map +7 -0
  105. package/dist/annotations/redaction-log.js +33 -0
  106. package/dist/annotations/redaction-log.js.map +7 -0
  107. package/dist/annotations/selection-marks.js +122 -0
  108. package/dist/annotations/selection-marks.js.map +7 -0
  109. package/dist/annotations/state.js +140 -0
  110. package/dist/annotations/state.js.map +7 -0
  111. package/dist/annotations/store.js +49 -0
  112. package/dist/annotations/store.js.map +7 -0
  113. package/dist/annotations/useAnnotationLayer.js +306 -0
  114. package/dist/annotations/useAnnotationLayer.js.map +7 -0
  115. package/dist/annotations/useAnnotationShortcuts.js +31 -0
  116. package/dist/annotations/useAnnotationShortcuts.js.map +7 -0
  117. package/dist/annotations/useTextSelectionMarks.js +100 -0
  118. package/dist/annotations/useTextSelectionMarks.js.map +7 -0
  119. package/dist/artifacts/artifact-kind.js +19 -0
  120. package/dist/artifacts/artifact-kind.js.map +7 -0
  121. package/dist/artifacts/index.js +89 -571
  122. package/dist/artifacts/index.js.map +7 -1
  123. package/dist/{chunk-WUTL62MC.js → artifacts/normalize-markdown.js} +12 -14
  124. package/dist/artifacts/normalize-markdown.js.map +7 -0
  125. package/dist/artifacts/redline-core.js +12 -3
  126. package/dist/artifacts/redline-core.js.map +7 -1
  127. package/dist/{chunk-74N436VK.js → artifacts/redline-diff.js} +10 -9
  128. package/dist/artifacts/redline-diff.js.map +7 -0
  129. package/dist/artifacts/redline-engine.js +14 -0
  130. package/dist/artifacts/redline-engine.js.map +7 -0
  131. package/dist/artifacts/renderArtifactMarkdown.js +9 -0
  132. package/dist/artifacts/renderArtifactMarkdown.js.map +7 -0
  133. package/dist/artifacts/useArtifactEditSession.js +183 -0
  134. package/dist/artifacts/useArtifactEditSession.js.map +7 -0
  135. package/dist/artifacts/useArtifactSession.js +173 -0
  136. package/dist/artifacts/useArtifactSession.js.map +7 -0
  137. package/dist/artifacts/useArtifactSource.js +16 -0
  138. package/dist/artifacts/useArtifactSource.js.map +7 -0
  139. package/dist/artifacts/useArtifactText.js +78 -0
  140. package/dist/artifacts/useArtifactText.js.map +7 -0
  141. package/dist/artifacts/useRedline.js +65 -0
  142. package/dist/artifacts/useRedline.js.map +7 -0
  143. package/dist/artifacts/useStreamedArtifact.js +74 -0
  144. package/dist/artifacts/useStreamedArtifact.js.map +7 -0
  145. package/dist/artifacts/versions.js +68 -0
  146. package/dist/artifacts/versions.js.map +7 -0
  147. package/dist/billing.js +200 -0
  148. package/dist/billing.js.map +7 -0
  149. package/dist/boot-timeout.js +19 -0
  150. package/dist/boot-timeout.js.map +7 -0
  151. package/dist/calendar/accounts.js +213 -0
  152. package/dist/calendar/accounts.js.map +7 -0
  153. package/dist/calendar/hooks.js +409 -0
  154. package/dist/calendar/hooks.js.map +7 -0
  155. package/dist/calendar/index.js +31 -0
  156. package/dist/calendar/index.js.map +7 -0
  157. package/dist/calendar/keys.js +5 -0
  158. package/dist/calendar/keys.js.map +7 -0
  159. package/dist/calendar/offline/outbox.js +231 -0
  160. package/dist/calendar/offline/outbox.js.map +7 -0
  161. package/dist/calendar/offline/runtime.js +109 -0
  162. package/dist/calendar/offline/runtime.js.map +7 -0
  163. package/dist/calendar/offline/support.js +41 -0
  164. package/dist/calendar/offline/support.js.map +7 -0
  165. package/dist/calendar/support.js +34 -0
  166. package/dist/calendar/support.js.map +7 -0
  167. package/dist/calls/actions.js +226 -0
  168. package/dist/calls/actions.js.map +7 -0
  169. package/dist/calls/events.js +138 -0
  170. package/dist/calls/events.js.map +7 -0
  171. package/dist/calls/gate.js +19 -0
  172. package/dist/calls/gate.js.map +7 -0
  173. package/dist/calls/hooks.js +115 -0
  174. package/dist/calls/hooks.js.map +7 -0
  175. package/dist/calls/in-call-chat.js +132 -0
  176. package/dist/calls/in-call-chat.js.map +7 -0
  177. package/dist/calls/index.js +24 -0
  178. package/dist/calls/index.js.map +7 -0
  179. package/dist/calls/keys.js +17 -0
  180. package/dist/calls/keys.js.map +7 -0
  181. package/dist/calls/livekit/index.js +6 -958
  182. package/dist/calls/livekit/index.js.map +7 -1
  183. package/dist/calls/livekit/room.js +98 -0
  184. package/dist/calls/livekit/room.js.map +7 -0
  185. package/dist/calls/livekit/useCallRecorder.js +219 -0
  186. package/dist/calls/livekit/useCallRecorder.js.map +7 -0
  187. package/dist/calls/livekit/useCallTranscriber.js +309 -0
  188. package/dist/calls/livekit/useCallTranscriber.js.map +7 -0
  189. package/dist/calls/livekit/useHostMuteNotice.js +29 -0
  190. package/dist/calls/livekit/useHostMuteNotice.js.map +7 -0
  191. package/dist/calls/livekit/useInCallChat.js +161 -0
  192. package/dist/calls/livekit/useInCallChat.js.map +7 -0
  193. package/dist/calls/livekit/useWebinar.js +239 -0
  194. package/dist/calls/livekit/useWebinar.js.map +7 -0
  195. package/dist/calls/meeting-chat.js +149 -0
  196. package/dist/calls/meeting-chat.js.map +7 -0
  197. package/dist/calls/moderation.js +50 -0
  198. package/dist/calls/moderation.js.map +7 -0
  199. package/dist/calls/open-meeting-chat.js +29 -0
  200. package/dist/calls/open-meeting-chat.js.map +7 -0
  201. package/dist/calls/read-only.js +24 -0
  202. package/dist/calls/read-only.js.map +7 -0
  203. package/dist/calls/recording-media.js +218 -0
  204. package/dist/calls/recording-media.js.map +7 -0
  205. package/dist/calls/recording-playback.js +260 -0
  206. package/dist/calls/recording-playback.js.map +7 -0
  207. package/dist/calls/recording.js +268 -0
  208. package/dist/calls/recording.js.map +7 -0
  209. package/dist/calls/save-to-thread.js +80 -0
  210. package/dist/calls/save-to-thread.js.map +7 -0
  211. package/dist/calls/session.js +134 -0
  212. package/dist/calls/session.js.map +7 -0
  213. package/dist/calls/transcript-format.js +147 -0
  214. package/dist/calls/transcript-format.js.map +7 -0
  215. package/dist/calls/transcription.js +101 -0
  216. package/dist/calls/transcription.js.map +7 -0
  217. package/dist/calls/webinar.js +71 -0
  218. package/dist/calls/webinar.js.map +7 -0
  219. package/dist/charge-watch.js +71 -0
  220. package/dist/charge-watch.js.map +7 -0
  221. package/dist/chat/ChatBubble.js +146 -0
  222. package/dist/chat/ChatBubble.js.map +7 -0
  223. package/dist/chat/ConversationScope.js +30 -0
  224. package/dist/chat/ConversationScope.js.map +7 -0
  225. package/dist/chat/active-config.js +20 -0
  226. package/dist/chat/active-config.js.map +7 -0
  227. package/dist/chat/agent-chat-owner.js +25 -0
  228. package/dist/chat/agent-chat-owner.js.map +7 -0
  229. package/dist/chat/chat-artifacts.js +64 -0
  230. package/dist/chat/chat-artifacts.js.map +7 -0
  231. package/dist/chat/citations.js +32 -0
  232. package/dist/chat/citations.js.map +7 -0
  233. package/dist/chat/config-model.js +10 -0
  234. package/dist/chat/config-model.js.map +7 -0
  235. package/dist/chat/conversation-cache.js +676 -0
  236. package/dist/chat/conversation-cache.js.map +7 -0
  237. package/dist/chat/conversation-events.js +57 -0
  238. package/dist/chat/conversation-events.js.map +7 -0
  239. package/dist/chat/conversation-mentions.js +58 -0
  240. package/dist/chat/conversation-mentions.js.map +7 -0
  241. package/dist/chat/conversation-workspace.js +58 -0
  242. package/dist/chat/conversation-workspace.js.map +7 -0
  243. package/dist/chat/mentions.js +116 -0
  244. package/dist/chat/mentions.js.map +7 -0
  245. package/dist/chat/open-document.js +106 -0
  246. package/dist/chat/open-document.js.map +7 -0
  247. package/dist/chat/orphaned.js +44 -0
  248. package/dist/chat/orphaned.js.map +7 -0
  249. package/dist/chat/pendingFirstTurn.js +30 -0
  250. package/dist/chat/pendingFirstTurn.js.map +7 -0
  251. package/dist/chat/reply-target.js +12 -0
  252. package/dist/chat/reply-target.js.map +7 -0
  253. package/dist/chat/run-finished.js +28 -0
  254. package/dist/chat/run-finished.js.map +7 -0
  255. package/dist/chat/run-state.js +91 -0
  256. package/dist/chat/run-state.js.map +7 -0
  257. package/dist/chat/stream-handlers.js +419 -0
  258. package/dist/chat/stream-handlers.js.map +7 -0
  259. package/dist/chat/thread-binding.js +76 -0
  260. package/dist/chat/thread-binding.js.map +7 -0
  261. package/dist/chat/thread-document.js +53 -0
  262. package/dist/chat/thread-document.js.map +7 -0
  263. package/dist/chat/turn-control.js +79 -0
  264. package/dist/chat/turn-control.js.map +7 -0
  265. package/dist/chat/useAgentRunControl.js +36 -0
  266. package/dist/chat/useAgentRunControl.js.map +7 -0
  267. package/dist/chat/useAnswerAgentQuestion.js +19 -0
  268. package/dist/chat/useAnswerAgentQuestion.js.map +7 -0
  269. package/dist/chat/useAskAgain.js +32 -0
  270. package/dist/chat/useAskAgain.js.map +7 -0
  271. package/dist/chat/useAutoSendDraft.js +17 -0
  272. package/dist/chat/useAutoSendDraft.js.map +7 -0
  273. package/dist/chat/useBranchNavigation.js +97 -0
  274. package/dist/chat/useBranchNavigation.js.map +7 -0
  275. package/dist/chat/useConnectRunStream.js +169 -0
  276. package/dist/chat/useConnectRunStream.js.map +7 -0
  277. package/dist/chat/useConversation.js +431 -0
  278. package/dist/chat/useConversation.js.map +7 -0
  279. package/dist/chat/useConversationActions.js +662 -0
  280. package/dist/chat/useConversationActions.js.map +7 -0
  281. package/dist/chat/useConversationData.js +143 -0
  282. package/dist/chat/useConversationData.js.map +7 -0
  283. package/dist/chat/useConversationDocuments.js +41 -0
  284. package/dist/chat/useConversationDocuments.js.map +7 -0
  285. package/dist/chat/useConversationSettings.js +78 -0
  286. package/dist/chat/useConversationSettings.js.map +7 -0
  287. package/dist/chat/useConversationTurn.js +31 -0
  288. package/dist/chat/useConversationTurn.js.map +7 -0
  289. package/dist/chat/useConversationWorkspace.js +12 -0
  290. package/dist/chat/useConversationWorkspace.js.map +7 -0
  291. package/dist/chat/useDeleteMessage.js +15 -0
  292. package/dist/chat/useDeleteMessage.js.map +7 -0
  293. package/dist/chat/useDocumentAutoAdd.js +73 -0
  294. package/dist/chat/useDocumentAutoAdd.js.map +7 -0
  295. package/dist/chat/useMessageTimer.js +39 -0
  296. package/dist/chat/useMessageTimer.js.map +7 -0
  297. package/dist/chat/useThinkingContent.js +67 -0
  298. package/dist/chat/useThinkingContent.js.map +7 -0
  299. package/dist/chat/useThreadDocument.js +61 -0
  300. package/dist/chat/useThreadDocument.js.map +7 -0
  301. package/dist/chat/workflow-run-titles.js +50 -0
  302. package/dist/chat/workflow-run-titles.js.map +7 -0
  303. package/dist/{chunk-Z3W4XFWB.cjs → chunk-C72FSQUE.cjs} +3 -3
  304. package/dist/{chunk-Z3W4XFWB.cjs.map → chunk-C72FSQUE.cjs.map} +1 -1
  305. package/dist/{chunk-LBAG7KL7.cjs → chunk-FQVNZCTD.cjs} +3 -3
  306. package/dist/{chunk-LBAG7KL7.cjs.map → chunk-FQVNZCTD.cjs.map} +1 -1
  307. package/dist/{chunk-DI5KSVKY.cjs → chunk-UDDJIUHJ.cjs} +3 -3
  308. package/dist/{chunk-DI5KSVKY.cjs.map → chunk-UDDJIUHJ.cjs.map} +1 -1
  309. package/dist/config/config-hooks.js +209 -0
  310. package/dist/config/config-hooks.js.map +7 -0
  311. package/dist/connectivity.js +72 -0
  312. package/dist/connectivity.js.map +7 -0
  313. package/dist/connectors/hooks.js +263 -0
  314. package/dist/connectors/hooks.js.map +7 -0
  315. package/dist/connectors/index.js +28 -0
  316. package/dist/connectors/index.js.map +7 -0
  317. package/dist/contacts.js +100 -0
  318. package/dist/contacts.js.map +7 -0
  319. package/dist/conversation-list.js +65 -0
  320. package/dist/conversation-list.js.map +7 -0
  321. package/dist/databases.js +195 -0
  322. package/dist/databases.js.map +7 -0
  323. package/dist/datasets/aggregate.js +281 -0
  324. package/dist/datasets/aggregate.js.map +7 -0
  325. package/dist/datasets/index.js +122 -0
  326. package/dist/datasets/index.js.map +7 -0
  327. package/dist/datasets/members.js +27 -0
  328. package/dist/datasets/members.js.map +7 -0
  329. package/dist/datasets/panel.js +44 -0
  330. package/dist/datasets/panel.js.map +7 -0
  331. package/dist/datasets/registry.js +47 -0
  332. package/dist/datasets/registry.js.map +7 -0
  333. package/dist/datasets/rows-source.js +44 -0
  334. package/dist/datasets/rows-source.js.map +7 -0
  335. package/dist/datasets/sources/activity.js +83 -0
  336. package/dist/datasets/sources/activity.js.map +7 -0
  337. package/dist/datasets/sources/conversations.js +74 -0
  338. package/dist/datasets/sources/conversations.js.map +7 -0
  339. package/dist/datasets/sources/database.js +209 -0
  340. package/dist/datasets/sources/database.js.map +7 -0
  341. package/dist/datasets/sources/documents.js +93 -0
  342. package/dist/datasets/sources/documents.js.map +7 -0
  343. package/dist/datasets/sources/facts.js +56 -0
  344. package/dist/datasets/sources/facts.js.map +7 -0
  345. package/dist/datasets/sources/projects.js +117 -0
  346. package/dist/datasets/sources/projects.js.map +7 -0
  347. package/dist/datasets/sources/tags.js +67 -0
  348. package/dist/datasets/sources/tags.js.map +7 -0
  349. package/dist/datasets/sources/usage.js +268 -0
  350. package/dist/datasets/sources/usage.js.map +7 -0
  351. package/dist/datasets/sources/workflows.js +91 -0
  352. package/dist/datasets/sources/workflows.js.map +7 -0
  353. package/dist/datasets/sources/workspaces.js +67 -0
  354. package/dist/datasets/sources/workspaces.js.map +7 -0
  355. package/dist/datasets/store.js +194 -0
  356. package/dist/datasets/store.js.map +7 -0
  357. package/dist/datasets/types.js +14 -0
  358. package/dist/datasets/types.js.map +7 -0
  359. package/dist/directmessages/ConversationList.js +148 -0
  360. package/dist/directmessages/ConversationList.js.map +7 -0
  361. package/dist/directmessages/DateSeparator.js +8 -0
  362. package/dist/directmessages/DateSeparator.js.map +7 -0
  363. package/dist/directmessages/DmAvatar.js +29 -0
  364. package/dist/directmessages/DmAvatar.js.map +7 -0
  365. package/dist/directmessages/DmComposer.js +201 -0
  366. package/dist/directmessages/DmComposer.js.map +7 -0
  367. package/dist/directmessages/arrivals.js +29 -0
  368. package/dist/directmessages/arrivals.js.map +7 -0
  369. package/dist/directmessages/chat-cache.js +192 -0
  370. package/dist/directmessages/chat-cache.js.map +7 -0
  371. package/dist/directmessages/grouping.js +26 -0
  372. package/dist/directmessages/grouping.js.map +7 -0
  373. package/dist/directmessages/index.js +81 -0
  374. package/dist/directmessages/index.js.map +7 -0
  375. package/dist/directmessages/useChats.js +266 -0
  376. package/dist/directmessages/useChats.js.map +7 -0
  377. package/dist/directmessages/utils.js +23 -0
  378. package/dist/directmessages/utils.js.map +7 -0
  379. package/dist/document-tools/can-annotate.js +7 -0
  380. package/dist/document-tools/can-annotate.js.map +7 -0
  381. package/dist/document-tools/core.cjs +80 -80
  382. package/dist/document-tools/core.js +218 -12
  383. package/dist/document-tools/core.js.map +7 -1
  384. package/dist/document-tools/document-pdf.js +76 -0
  385. package/dist/document-tools/document-pdf.js.map +7 -0
  386. package/dist/document-tools/environment.js +136 -0
  387. package/dist/document-tools/environment.js.map +7 -0
  388. package/dist/document-tools/file-shares.js +112 -0
  389. package/dist/document-tools/file-shares.js.map +7 -0
  390. package/dist/document-tools/frozen-copy.js +27 -0
  391. package/dist/document-tools/frozen-copy.js.map +7 -0
  392. package/dist/document-tools/index.cjs +80 -80
  393. package/dist/document-tools/index.js +26 -148
  394. package/dist/document-tools/index.js.map +7 -1
  395. package/dist/document-tools/markup-download.js +51 -0
  396. package/dist/document-tools/markup-download.js.map +7 -0
  397. package/dist/document-tools/markup-store.js +138 -0
  398. package/dist/document-tools/markup-store.js.map +7 -0
  399. package/dist/document-tools/markup-transfer.js +88 -0
  400. package/dist/document-tools/markup-transfer.js.map +7 -0
  401. package/dist/document-tools/production.js +147 -0
  402. package/dist/document-tools/production.js.map +7 -0
  403. package/dist/document-tools/saved-signature.js +90 -0
  404. package/dist/document-tools/saved-signature.js.map +7 -0
  405. package/dist/document-tools/signature-requests.js +310 -0
  406. package/dist/document-tools/signature-requests.js.map +7 -0
  407. package/dist/document-tools/signing.js +127 -0
  408. package/dist/document-tools/signing.js.map +7 -0
  409. package/dist/document-tools/useDocumentBytes.js +38 -0
  410. package/dist/document-tools/useDocumentBytes.js.map +7 -0
  411. package/dist/document-tools/useDocumentMarkup.js +154 -0
  412. package/dist/document-tools/useDocumentMarkup.js.map +7 -0
  413. package/dist/document-tools/useIsOnline.js +13 -0
  414. package/dist/document-tools/useIsOnline.js.map +7 -0
  415. package/dist/document-tools/verification.js +60 -0
  416. package/dist/document-tools/verification.js.map +7 -0
  417. package/dist/documents/DocumentReview.js +220 -0
  418. package/dist/documents/DocumentReview.js.map +7 -0
  419. package/dist/documents/DraftTitleControls.js +41 -0
  420. package/dist/documents/DraftTitleControls.js.map +7 -0
  421. package/dist/documents/InlineMicButton.js +90 -0
  422. package/dist/documents/InlineMicButton.js.map +7 -0
  423. package/dist/documents/MicRecordingOverlay.js +29 -0
  424. package/dist/documents/MicRecordingOverlay.js.map +7 -0
  425. package/dist/documents/MicWaveformIndicator.js +68 -0
  426. package/dist/documents/MicWaveformIndicator.js.map +7 -0
  427. package/dist/documents/PhotoCapture.js +120 -0
  428. package/dist/documents/PhotoCapture.js.map +7 -0
  429. package/dist/documents/VideoCapture.js +129 -0
  430. package/dist/documents/VideoCapture.js.map +7 -0
  431. package/dist/documents/VoiceNoteRecorder.js +166 -0
  432. package/dist/documents/VoiceNoteRecorder.js.map +7 -0
  433. package/dist/documents/audio-segmenter.js +63 -0
  434. package/dist/documents/audio-segmenter.js.map +7 -0
  435. package/dist/documents/capture-frame.js +21 -0
  436. package/dist/documents/capture-frame.js.map +7 -0
  437. package/dist/documents/chunked-recorder.js +190 -0
  438. package/dist/documents/chunked-recorder.js.map +7 -0
  439. package/dist/documents/document-download.js +53 -0
  440. package/dist/documents/document-download.js.map +7 -0
  441. package/dist/documents/document-fields.js +109 -0
  442. package/dist/documents/document-fields.js.map +7 -0
  443. package/dist/documents/documents-cache.js +110 -0
  444. package/dist/documents/documents-cache.js.map +7 -0
  445. package/dist/documents/documents-data.js +128 -0
  446. package/dist/documents/documents-data.js.map +7 -0
  447. package/dist/documents/documents-loader.js +113 -0
  448. package/dist/documents/documents-loader.js.map +7 -0
  449. package/dist/documents/documents-writes.js +448 -0
  450. package/dist/documents/documents-writes.js.map +7 -0
  451. package/dist/documents/format-elapsed.js +10 -0
  452. package/dist/documents/format-elapsed.js.map +7 -0
  453. package/dist/documents/has-video-track.js +26 -0
  454. package/dist/documents/has-video-track.js.map +7 -0
  455. package/dist/documents/index.js +266 -0
  456. package/dist/documents/index.js.map +7 -0
  457. package/dist/documents/media-error.js +18 -0
  458. package/dist/documents/media-error.js.map +7 -0
  459. package/dist/documents/offline-documents.js +160 -0
  460. package/dist/documents/offline-documents.js.map +7 -0
  461. package/dist/documents/pending-sync.js +210 -0
  462. package/dist/documents/pending-sync.js.map +7 -0
  463. package/dist/documents/processing-live.js +122 -0
  464. package/dist/documents/processing-live.js.map +7 -0
  465. package/dist/documents/processing-order.js +59 -0
  466. package/dist/documents/processing-order.js.map +7 -0
  467. package/dist/documents/processing-settle.js +21 -0
  468. package/dist/documents/processing-settle.js.map +7 -0
  469. package/dist/documents/related-documents.js +133 -0
  470. package/dist/documents/related-documents.js.map +7 -0
  471. package/dist/documents/support.js +29 -0
  472. package/dist/documents/support.js.map +7 -0
  473. package/dist/documents/upload-files.js +169 -0
  474. package/dist/documents/upload-files.js.map +7 -0
  475. package/dist/documents/useAudioRecorder.js +315 -0
  476. package/dist/documents/useAudioRecorder.js.map +7 -0
  477. package/dist/documents/useCameraStream.js +35 -0
  478. package/dist/documents/useCameraStream.js.map +7 -0
  479. package/dist/documents/useDocumentThumbnails.js +71 -0
  480. package/dist/documents/useDocumentThumbnails.js.map +7 -0
  481. package/dist/documents/useDownloadDocuments.js +90 -0
  482. package/dist/documents/useDownloadDocuments.js.map +7 -0
  483. package/dist/documents/usePassageQuotes.js +37 -0
  484. package/dist/documents/usePassageQuotes.js.map +7 -0
  485. package/dist/documents/useUploadFiles.js +165 -0
  486. package/dist/documents/useUploadFiles.js.map +7 -0
  487. package/dist/documents/useUploadFromUrls.js +63 -0
  488. package/dist/documents/useUploadFromUrls.js.map +7 -0
  489. package/dist/documents/useVideoRecorder.js +62 -0
  490. package/dist/documents/useVideoRecorder.js.map +7 -0
  491. package/dist/entities/AgentMarkers.js +61 -0
  492. package/dist/entities/AgentMarkers.js.map +7 -0
  493. package/dist/entities/DocumentEntity.js +125 -0
  494. package/dist/entities/DocumentEntity.js.map +7 -0
  495. package/dist/entities/EntityPill.js +250 -0
  496. package/dist/entities/EntityPill.js.map +7 -0
  497. package/dist/entities/ProjectEntity.js +61 -0
  498. package/dist/entities/ProjectEntity.js.map +7 -0
  499. package/dist/entities/ShieldIcon.js +49 -0
  500. package/dist/entities/ShieldIcon.js.map +7 -0
  501. package/dist/entities/TagEntity.js +79 -0
  502. package/dist/entities/TagEntity.js.map +7 -0
  503. package/dist/entities/ThreadVisibilityIcon.js +15 -0
  504. package/dist/entities/ThreadVisibilityIcon.js.map +7 -0
  505. package/dist/entities/UserEntity.js +211 -0
  506. package/dist/entities/UserEntity.js.map +7 -0
  507. package/dist/entities/VerifiedBadge.js +19 -0
  508. package/dist/entities/VerifiedBadge.js.map +7 -0
  509. package/dist/entities/agent-avatar-colors.js +26 -0
  510. package/dist/entities/agent-avatar-colors.js.map +7 -0
  511. package/dist/entities/colors.js +64 -0
  512. package/dist/entities/colors.js.map +7 -0
  513. package/dist/entities/file-type.js +151 -0
  514. package/dist/entities/file-type.js.map +7 -0
  515. package/dist/entities/index.js +100 -0
  516. package/dist/entities/index.js.map +7 -0
  517. package/dist/entities/media-type.js +61 -0
  518. package/dist/entities/media-type.js.map +7 -0
  519. package/dist/entities/registry.js +385 -0
  520. package/dist/entities/registry.js.map +7 -0
  521. package/dist/entities/status.js +43 -0
  522. package/dist/entities/status.js.map +7 -0
  523. package/dist/entities/tag-kinds.js +23 -0
  524. package/dist/entities/tag-kinds.js.map +7 -0
  525. package/dist/entities/tag-types.js +44 -0
  526. package/dist/entities/tag-types.js.map +7 -0
  527. package/dist/entities/vocabulary.js +12 -0
  528. package/dist/entities/vocabulary.js.map +7 -0
  529. package/dist/entity-extraction.js +25 -0
  530. package/dist/entity-extraction.js.map +7 -0
  531. package/dist/facts-search.js +57 -0
  532. package/dist/facts-search.js.map +7 -0
  533. package/dist/facts.js +69 -0
  534. package/dist/facts.js.map +7 -0
  535. package/dist/hooks.js +320 -0
  536. package/dist/hooks.js.map +7 -0
  537. package/dist/host/ArbiHost.js +24 -0
  538. package/dist/host/ArbiHost.js.map +7 -0
  539. package/dist/host/assistant-copy.js +54 -0
  540. package/dist/host/assistant-copy.js.map +7 -0
  541. package/dist/host/config.js +9 -0
  542. package/dist/host/config.js.map +7 -0
  543. package/dist/host/context.js +10 -0
  544. package/dist/host/context.js.map +7 -0
  545. package/dist/host/features.js +144 -0
  546. package/dist/host/features.js.map +7 -0
  547. package/dist/host/index.js +12 -0
  548. package/dist/host/index.js.map +7 -0
  549. package/dist/{chunk-DPYBZDJB.js → host/merge.js} +7 -7
  550. package/dist/host/merge.js.map +7 -0
  551. package/dist/house-template.js +40 -0
  552. package/dist/house-template.js.map +7 -0
  553. package/dist/icons/AppleIcon.js +25 -0
  554. package/dist/icons/AppleIcon.js.map +7 -0
  555. package/dist/icons/ArbiBotHeadIcon.js +46 -0
  556. package/dist/icons/ArbiBotHeadIcon.js.map +7 -0
  557. package/dist/icons/ArbiIcon.js +24 -0
  558. package/dist/icons/ArbiIcon.js.map +7 -0
  559. package/dist/icons/AudIcon.js +56 -0
  560. package/dist/icons/AudIcon.js.map +7 -0
  561. package/dist/icons/ClaudeIcon.js +28 -0
  562. package/dist/icons/ClaudeIcon.js.map +7 -0
  563. package/dist/icons/DocIcon.js +56 -0
  564. package/dist/icons/DocIcon.js.map +7 -0
  565. package/dist/icons/EmlIcon.js +57 -0
  566. package/dist/icons/EmlIcon.js.map +7 -0
  567. package/dist/icons/FireworksIcon.js +47 -0
  568. package/dist/icons/FireworksIcon.js.map +7 -0
  569. package/dist/icons/GeminiIcon.js +37 -0
  570. package/dist/icons/GeminiIcon.js.map +7 -0
  571. package/dist/icons/GitHubIcon.js +32 -0
  572. package/dist/icons/GitHubIcon.js.map +7 -0
  573. package/dist/icons/GoogleIcon.js +53 -0
  574. package/dist/icons/GoogleIcon.js.map +7 -0
  575. package/dist/icons/HtmlIcon.js +56 -0
  576. package/dist/icons/HtmlIcon.js.map +7 -0
  577. package/dist/icons/ImgIcon.js +56 -0
  578. package/dist/icons/ImgIcon.js.map +7 -0
  579. package/dist/icons/LinkedInIcon.js +25 -0
  580. package/dist/icons/LinkedInIcon.js.map +7 -0
  581. package/dist/icons/OpenAIIcon.js +28 -0
  582. package/dist/icons/OpenAIIcon.js.map +7 -0
  583. package/dist/icons/PdfIcon.js +56 -0
  584. package/dist/icons/PdfIcon.js.map +7 -0
  585. package/dist/icons/ProviderIcon.js +42 -0
  586. package/dist/icons/ProviderIcon.js.map +7 -0
  587. package/dist/icons/TxtIcon.js +56 -0
  588. package/dist/icons/TxtIcon.js.map +7 -0
  589. package/dist/icons/VidIcon.js +56 -0
  590. package/dist/icons/VidIcon.js.map +7 -0
  591. package/dist/icons/XlsIcon.js +56 -0
  592. package/dist/icons/XlsIcon.js.map +7 -0
  593. package/dist/icons/arbi-mark.js +5 -0
  594. package/dist/icons/arbi-mark.js.map +7 -0
  595. package/dist/icons/colors.js +31 -0
  596. package/dist/icons/colors.js.map +7 -0
  597. package/dist/icons/file-type.js +105 -0
  598. package/dist/icons/file-type.js.map +7 -0
  599. package/dist/icons/index.js +55 -0
  600. package/dist/icons/index.js.map +7 -0
  601. package/dist/imagecrop/ImageCropModal.js +56 -0
  602. package/dist/imagecrop/ImageCropModal.js.map +7 -0
  603. package/dist/imagecrop/ImageCropper.js +100 -0
  604. package/dist/imagecrop/ImageCropper.js.map +7 -0
  605. package/dist/imagecrop/cropImage.js +43 -0
  606. package/dist/imagecrop/cropImage.js.map +7 -0
  607. package/dist/imagecrop/index.js +13 -0
  608. package/dist/imagecrop/index.js.map +7 -0
  609. package/dist/index.cjs +282 -282
  610. package/dist/index.js +702 -17116
  611. package/dist/index.js.map +7 -1
  612. package/dist/{chunk-SSXFVWCT.js → lazy-chunk.js} +8 -8
  613. package/dist/lazy-chunk.js.map +7 -0
  614. package/dist/lib/collision-padding.js +13 -0
  615. package/dist/lib/collision-padding.js.map +7 -0
  616. package/dist/lib/format-friendly-date.js +55 -0
  617. package/dist/lib/format-friendly-date.js.map +7 -0
  618. package/dist/lib/format-relative-time.js +52 -0
  619. package/dist/lib/format-relative-time.js.map +7 -0
  620. package/dist/lib/markdown-to-text.js +35 -0
  621. package/dist/lib/markdown-to-text.js.map +7 -0
  622. package/dist/lib/toast-interaction.js +9 -0
  623. package/dist/lib/toast-interaction.js.map +7 -0
  624. package/dist/lib/utils.js +9 -0
  625. package/dist/lib/utils.js.map +7 -0
  626. package/dist/mail/client.js +103 -0
  627. package/dist/mail/client.js.map +7 -0
  628. package/dist/mail/document-attachment.js +38 -0
  629. package/dist/mail/document-attachment.js.map +7 -0
  630. package/dist/mail/filing.js +132 -0
  631. package/dist/mail/filing.js.map +7 -0
  632. package/dist/mail/hooks.js +393 -0
  633. package/dist/mail/hooks.js.map +7 -0
  634. package/dist/mail/index.js +120 -0
  635. package/dist/mail/index.js.map +7 -0
  636. package/dist/mail/offline/changes.js +258 -0
  637. package/dist/mail/offline/changes.js.map +7 -0
  638. package/dist/mail/offline/confirm-sign-out.js +37 -0
  639. package/dist/mail/offline/confirm-sign-out.js.map +7 -0
  640. package/dist/mail/offline/crypto.js +26 -0
  641. package/dist/mail/offline/crypto.js.map +7 -0
  642. package/dist/mail/offline/drafts.js +69 -0
  643. package/dist/mail/offline/drafts.js.map +7 -0
  644. package/dist/mail/offline/hooks.js +104 -0
  645. package/dist/mail/offline/hooks.js.map +7 -0
  646. package/dist/mail/offline/index.js +48 -0
  647. package/dist/mail/offline/index.js.map +7 -0
  648. package/dist/mail/offline/live.js +233 -0
  649. package/dist/mail/offline/live.js.map +7 -0
  650. package/dist/mail/offline/mailbox.js +191 -0
  651. package/dist/mail/offline/mailbox.js.map +7 -0
  652. package/dist/mail/offline/outbox.js +167 -0
  653. package/dist/mail/offline/outbox.js.map +7 -0
  654. package/dist/mail/offline/reads.js +159 -0
  655. package/dist/mail/offline/reads.js.map +7 -0
  656. package/dist/mail/offline/runtime.js +100 -0
  657. package/dist/mail/offline/runtime.js.map +7 -0
  658. package/dist/mail/offline/settings.js +84 -0
  659. package/dist/mail/offline/settings.js.map +7 -0
  660. package/dist/mail/offline/store.js +29 -0
  661. package/dist/mail/offline/store.js.map +7 -0
  662. package/dist/mail/offline/sync.js +251 -0
  663. package/dist/mail/offline/sync.js.map +7 -0
  664. package/dist/mail/offline/wipe.js +19 -0
  665. package/dist/mail/offline/wipe.js.map +7 -0
  666. package/dist/mail/thread-keys.js +53 -0
  667. package/dist/mail/thread-keys.js.map +7 -0
  668. package/dist/mail/threads.js +71 -0
  669. package/dist/mail/threads.js.map +7 -0
  670. package/dist/mail/useMailClient.js +42 -0
  671. package/dist/mail/useMailClient.js.map +7 -0
  672. package/dist/model-connections.js +58 -0
  673. package/dist/model-connections.js.map +7 -0
  674. package/dist/notifications/ActivityFeed.js +70 -0
  675. package/dist/notifications/ActivityFeed.js.map +7 -0
  676. package/dist/notifications/NotificationBell.js +200 -0
  677. package/dist/notifications/NotificationBell.js.map +7 -0
  678. package/dist/notifications/Toaster.js +24 -0
  679. package/dist/notifications/Toaster.js.map +7 -0
  680. package/dist/notifications/activity-types.js +65 -0
  681. package/dist/notifications/activity-types.js.map +7 -0
  682. package/dist/notifications/bell.js +24 -0
  683. package/dist/notifications/bell.js.map +7 -0
  684. package/dist/notifications/calendar-notifications.js +79 -0
  685. package/dist/notifications/calendar-notifications.js.map +7 -0
  686. package/dist/notifications/index.js +108 -0
  687. package/dist/notifications/index.js.map +7 -0
  688. package/dist/notifications/live.js +28 -0
  689. package/dist/notifications/live.js.map +7 -0
  690. package/dist/notifications/notification-types.js +127 -0
  691. package/dist/notifications/notification-types.js.map +7 -0
  692. package/dist/{chunk-BF5KW5ZI.js → notifications/notify-store.js} +24 -74
  693. package/dist/notifications/notify-store.js.map +7 -0
  694. package/dist/notifications/server-notifications.js +452 -0
  695. package/dist/notifications/server-notifications.js.map +7 -0
  696. package/dist/notifications/useNotifications.js +34 -0
  697. package/dist/notifications/useNotifications.js.map +7 -0
  698. package/dist/offline-store/network.js +11 -0
  699. package/dist/offline-store/network.js.map +7 -0
  700. package/dist/offline-store/store.js +136 -0
  701. package/dist/offline-store/store.js.map +7 -0
  702. package/dist/offline-store/wipe.js +8 -0
  703. package/dist/offline-store/wipe.js.map +7 -0
  704. package/dist/offline.js +58 -0
  705. package/dist/offline.js.map +7 -0
  706. package/dist/people.js +122 -0
  707. package/dist/people.js.map +7 -0
  708. package/dist/projects.js +30 -0
  709. package/dist/projects.js.map +7 -0
  710. package/dist/query-client.js +63 -0
  711. package/dist/query-client.js.map +7 -0
  712. package/dist/{chunk-ZM6N7YZH.js → query-keys.js} +18 -31
  713. package/dist/query-keys.js.map +7 -0
  714. package/dist/query-persist.js +66 -0
  715. package/dist/query-persist.js.map +7 -0
  716. package/dist/queued-writes.js +59 -0
  717. package/dist/queued-writes.js.map +7 -0
  718. package/dist/remote-control.js +67 -0
  719. package/dist/remote-control.js.map +7 -0
  720. package/dist/search/index.js +23 -0
  721. package/dist/search/index.js.map +7 -0
  722. package/dist/search/session.js +58 -0
  723. package/dist/search/session.js.map +7 -0
  724. package/dist/search/useSemanticSearch.js +82 -0
  725. package/dist/search/useSemanticSearch.js.map +7 -0
  726. package/dist/session/chat.js +512 -0
  727. package/dist/session/chat.js.map +7 -0
  728. package/dist/session/documents.js +196 -0
  729. package/dist/session/documents.js.map +7 -0
  730. package/dist/session/drafts.js +103 -0
  731. package/dist/session/drafts.js.map +7 -0
  732. package/dist/session/index.js +123 -0
  733. package/dist/session/index.js.map +7 -0
  734. package/dist/session/layout.js +339 -0
  735. package/dist/session/layout.js.map +7 -0
  736. package/dist/session/persist.js +106 -0
  737. package/dist/session/persist.js.map +7 -0
  738. package/dist/session/session-hooks.js +53 -0
  739. package/dist/session/session-hooks.js.map +7 -0
  740. package/dist/session/signed-in.js +36 -0
  741. package/dist/session/signed-in.js.map +7 -0
  742. package/dist/session/store.js +166 -0
  743. package/dist/session/store.js.map +7 -0
  744. package/dist/session/thread-tabs.js +121 -0
  745. package/dist/session/thread-tabs.js.map +7 -0
  746. package/dist/session/ui-state-storage.js +76 -0
  747. package/dist/session/ui-state-storage.js.map +7 -0
  748. package/dist/session/workspace.js +77 -0
  749. package/dist/session/workspace.js.map +7 -0
  750. package/dist/shell/index.cjs +37 -37
  751. package/dist/shell/index.js +43 -10
  752. package/dist/shell/index.js.map +7 -1
  753. package/dist/skill-pack.js +111 -0
  754. package/dist/skill-pack.js.map +7 -0
  755. package/dist/storage.js +186 -0
  756. package/dist/storage.js.map +7 -0
  757. package/dist/support/index.js +35 -0
  758. package/dist/support/index.js.map +7 -0
  759. package/dist/tags.js +204 -0
  760. package/dist/tags.js.map +7 -0
  761. package/dist/ui/DebouncedInput.js +109 -0
  762. package/dist/ui/DebouncedInput.js.map +7 -0
  763. package/dist/ui/DictateContext.js +8 -0
  764. package/dist/ui/DictateContext.js.map +7 -0
  765. package/dist/ui/IconToggle.js +79 -0
  766. package/dist/ui/IconToggle.js.map +7 -0
  767. package/dist/ui/VerifiedToggle.js +38 -0
  768. package/dist/ui/VerifiedToggle.js.map +7 -0
  769. package/dist/ui/VisibilityToggle.js +103 -0
  770. package/dist/ui/VisibilityToggle.js.map +7 -0
  771. package/dist/ui/avatar.js +40 -0
  772. package/dist/ui/avatar.js.map +7 -0
  773. package/dist/ui/badge.js +28 -0
  774. package/dist/ui/badge.js.map +7 -0
  775. package/dist/ui/button.js +48 -0
  776. package/dist/ui/button.js.map +7 -0
  777. package/dist/ui/card.js +90 -0
  778. package/dist/ui/card.js.map +7 -0
  779. package/dist/ui/checkbox.js +22 -0
  780. package/dist/ui/checkbox.js.map +7 -0
  781. package/dist/ui/collapsible.js +10 -0
  782. package/dist/ui/collapsible.js.map +7 -0
  783. package/dist/ui/command.js +103 -0
  784. package/dist/ui/command.js.map +7 -0
  785. package/dist/{chunk-YNNAJJ5Z.js → ui/dialog.js} +30 -68
  786. package/dist/ui/dialog.js.map +7 -0
  787. package/dist/{chunk-47CCGUWR.js → ui/dropdown-menu.js} +40 -45
  788. package/dist/ui/dropdown-menu.js.map +7 -0
  789. package/dist/ui/hover-card.js +36 -0
  790. package/dist/ui/hover-card.js.map +7 -0
  791. package/dist/ui/index.cjs +154 -154
  792. package/dist/ui/index.js +290 -10
  793. package/dist/ui/index.js.map +7 -1
  794. package/dist/ui/input.js +65 -0
  795. package/dist/ui/input.js.map +7 -0
  796. package/dist/ui/label.js +16 -0
  797. package/dist/ui/label.js.map +7 -0
  798. package/dist/ui/mark-menu.js +300 -0
  799. package/dist/ui/mark-menu.js.map +7 -0
  800. package/dist/ui/popover.js +40 -0
  801. package/dist/ui/popover.js.map +7 -0
  802. package/dist/ui/portal-container.js +17 -0
  803. package/dist/ui/portal-container.js.map +7 -0
  804. package/dist/ui/progress.js +24 -0
  805. package/dist/ui/progress.js.map +7 -0
  806. package/dist/ui/radio-group.js +29 -0
  807. package/dist/ui/radio-group.js.map +7 -0
  808. package/dist/ui/scroll-area.js +39 -0
  809. package/dist/ui/scroll-area.js.map +7 -0
  810. package/dist/ui/select.js +130 -0
  811. package/dist/ui/select.js.map +7 -0
  812. package/dist/ui/separator.js +23 -0
  813. package/dist/ui/separator.js.map +7 -0
  814. package/dist/ui/slider.js +23 -0
  815. package/dist/ui/slider.js.map +7 -0
  816. package/dist/ui/switch.js +28 -0
  817. package/dist/ui/switch.js.map +7 -0
  818. package/dist/ui/table.js +75 -0
  819. package/dist/ui/table.js.map +7 -0
  820. package/dist/ui/tabs.js +48 -0
  821. package/dist/ui/tabs.js.map +7 -0
  822. package/dist/ui/textarea.js +63 -0
  823. package/dist/ui/textarea.js.map +7 -0
  824. package/dist/ui/toggle-group.js +43 -0
  825. package/dist/ui/toggle-group.js.map +7 -0
  826. package/dist/ui/toggle.js +40 -0
  827. package/dist/ui/toggle.js.map +7 -0
  828. package/dist/ui/tooltip.js +215 -0
  829. package/dist/ui/tooltip.js.map +7 -0
  830. package/dist/usage-metered.js +8 -0
  831. package/dist/usage-metered.js.map +7 -0
  832. package/dist/useArbi.js +16 -0
  833. package/dist/useArbi.js.map +7 -0
  834. package/dist/useInstallSkillPack.js +81 -0
  835. package/dist/useInstallSkillPack.js.map +7 -0
  836. package/dist/usermenu/UserMenu.js +188 -0
  837. package/dist/usermenu/UserMenu.js.map +7 -0
  838. package/dist/usermenu/index.js +5 -0
  839. package/dist/usermenu/index.js.map +7 -0
  840. package/dist/users/index.js +15 -0
  841. package/dist/users/index.js.map +7 -0
  842. package/dist/users/user-display.js +60 -0
  843. package/dist/users/user-display.js.map +7 -0
  844. package/dist/viewers/AudioViewer.js +23 -0
  845. package/dist/viewers/AudioViewer.js.map +7 -0
  846. package/dist/viewers/DocxViewer.js +81 -0
  847. package/dist/viewers/DocxViewer.js.map +7 -0
  848. package/dist/viewers/ImageViewer.js +31 -0
  849. package/dist/viewers/ImageViewer.js.map +7 -0
  850. package/dist/viewers/PdfViewer.js +19 -3
  851. package/dist/viewers/PdfViewer.js.map +7 -1
  852. package/dist/{PdfViewerImpl-TEBYF2QI.js → viewers/PdfViewerImpl.js} +25 -19
  853. package/dist/viewers/PdfViewerImpl.js.map +7 -0
  854. package/dist/viewers/VideoViewer.js +31 -0
  855. package/dist/viewers/VideoViewer.js.map +7 -0
  856. package/dist/viewers/XlsxViewer.js +102 -0
  857. package/dist/viewers/XlsxViewer.js.map +7 -0
  858. package/dist/viewers/index.js +61 -271
  859. package/dist/viewers/index.js.map +7 -1
  860. package/dist/viewers/page-scroll.js +59 -0
  861. package/dist/viewers/page-scroll.js.map +7 -0
  862. package/dist/viewers/pdf-viewer-constants.js +9 -0
  863. package/dist/viewers/pdf-viewer-constants.js.map +7 -0
  864. package/dist/{chunk-PTOP7OHG.js → viewers/pdfjs-polyfills.js} +5 -6
  865. package/dist/viewers/pdfjs-polyfills.js.map +7 -0
  866. package/dist/viewers/selection-runs.js +38 -0
  867. package/dist/viewers/selection-runs.js.map +7 -0
  868. package/dist/viewers/usePageIntersectionObserver.js +68 -0
  869. package/dist/viewers/usePageIntersectionObserver.js.map +7 -0
  870. package/dist/viewers/useProcessedChunks.js +58 -0
  871. package/dist/viewers/useProcessedChunks.js.map +7 -0
  872. package/dist/viewers/viewer-zoom.js +163 -0
  873. package/dist/viewers/viewer-zoom.js.map +7 -0
  874. package/dist/websocket/ArbiWebSocketProvider.js +207 -0
  875. package/dist/websocket/ArbiWebSocketProvider.js.map +7 -0
  876. package/dist/websocket/context.js +14 -0
  877. package/dist/websocket/context.js.map +7 -0
  878. package/dist/websocket/hooks.js +30 -0
  879. package/dist/websocket/hooks.js.map +7 -0
  880. package/dist/websocket/index.js +22 -0
  881. package/dist/websocket/index.js.map +7 -0
  882. package/dist/websocket/live-updates.js +38 -0
  883. package/dist/websocket/live-updates.js.map +7 -0
  884. package/dist/websocket/reconnect.js +13 -0
  885. package/dist/websocket/reconnect.js.map +7 -0
  886. package/dist/websocket/store.js +58 -0
  887. package/dist/websocket/store.js.map +7 -0
  888. package/dist/workforce.js +607 -0
  889. package/dist/workforce.js.map +7 -0
  890. package/dist/workspaces/access-request.js +35 -0
  891. package/dist/workspaces/access-request.js.map +7 -0
  892. package/dist/workspaces/archive.js +59 -0
  893. package/dist/workspaces/archive.js.map +7 -0
  894. package/dist/workspaces/current.js +20 -0
  895. package/dist/workspaces/current.js.map +7 -0
  896. package/dist/workspaces/delete-workspaces.js +15 -0
  897. package/dist/workspaces/delete-workspaces.js.map +7 -0
  898. package/dist/workspaces/export-archive.js +40 -0
  899. package/dist/workspaces/export-archive.js.map +7 -0
  900. package/dist/workspaces/index.js +99 -0
  901. package/dist/workspaces/index.js.map +7 -0
  902. package/dist/workspaces/settings.js +45 -0
  903. package/dist/workspaces/settings.js.map +7 -0
  904. package/dist/workspaces/shell-workspaces.js +49 -0
  905. package/dist/workspaces/shell-workspaces.js.map +7 -0
  906. package/dist/workspaces/switch.js +234 -0
  907. package/dist/workspaces/switch.js.map +7 -0
  908. package/dist/workspaces/transfer.js +170 -0
  909. package/dist/workspaces/transfer.js.map +7 -0
  910. package/dist/workspaces/useShellWorkspaces.js +86 -0
  911. package/dist/workspaces/useShellWorkspaces.js.map +7 -0
  912. package/dist/workspaces/workspace-users.js +65 -0
  913. package/dist/workspaces/workspace-users.js.map +7 -0
  914. package/package.json +4 -4
  915. package/dist/PdfViewerImpl-TEBYF2QI.js.map +0 -1
  916. package/dist/PdfViewerImpl.d-B28hLEuj.d.cts +0 -62
  917. package/dist/ProductionDialog.d-CpzslFn0.d.cts +0 -51
  918. package/dist/annotations/freeze/index.d.cts +0 -205
  919. package/dist/annotations/index.d.cts +0 -360
  920. package/dist/artifacts/index.d.cts +0 -476
  921. package/dist/artifacts/redline-core.d.cts +0 -39
  922. package/dist/bundle-YNOX7VIL.js +0 -5
  923. package/dist/bundle-YNOX7VIL.js.map +0 -1
  924. package/dist/bundle.d-BnCSbHy2.d.cts +0 -85
  925. package/dist/calls/livekit/index.d.cts +0 -280
  926. package/dist/chunk-47CCGUWR.js.map +0 -1
  927. package/dist/chunk-4FL3X3LA.js +0 -2057
  928. package/dist/chunk-4FL3X3LA.js.map +0 -1
  929. package/dist/chunk-6QNBSXCE.js +0 -271
  930. package/dist/chunk-6QNBSXCE.js.map +0 -1
  931. package/dist/chunk-74N436VK.js.map +0 -1
  932. package/dist/chunk-APZZQZ6P.js +0 -147
  933. package/dist/chunk-APZZQZ6P.js.map +0 -1
  934. package/dist/chunk-BF5KW5ZI.js.map +0 -1
  935. package/dist/chunk-DPYBZDJB.js.map +0 -1
  936. package/dist/chunk-DZKRL5H3.js +0 -2766
  937. package/dist/chunk-DZKRL5H3.js.map +0 -1
  938. package/dist/chunk-HDCRPPBW.js +0 -75
  939. package/dist/chunk-HDCRPPBW.js.map +0 -1
  940. package/dist/chunk-L2IPPTVC.js +0 -20
  941. package/dist/chunk-L2IPPTVC.js.map +0 -1
  942. package/dist/chunk-LSU4UPS5.js +0 -1011
  943. package/dist/chunk-LSU4UPS5.js.map +0 -1
  944. package/dist/chunk-NIKPG4PW.js +0 -1128
  945. package/dist/chunk-NIKPG4PW.js.map +0 -1
  946. package/dist/chunk-NNAJLY6B.js +0 -4974
  947. package/dist/chunk-NNAJLY6B.js.map +0 -1
  948. package/dist/chunk-OYPKKHXY.js +0 -559
  949. package/dist/chunk-OYPKKHXY.js.map +0 -1
  950. package/dist/chunk-PTOP7OHG.js.map +0 -1
  951. package/dist/chunk-QMY2JKBI.js +0 -246
  952. package/dist/chunk-QMY2JKBI.js.map +0 -1
  953. package/dist/chunk-SN5YV6FF.js +0 -11
  954. package/dist/chunk-SN5YV6FF.js.map +0 -1
  955. package/dist/chunk-SSXFVWCT.js.map +0 -1
  956. package/dist/chunk-T3USOSVN.js.map +0 -1
  957. package/dist/chunk-T4CLW3DN.js +0 -2560
  958. package/dist/chunk-T4CLW3DN.js.map +0 -1
  959. package/dist/chunk-UW2SGTI5.js.map +0 -1
  960. package/dist/chunk-VSCU7K4V.js.map +0 -1
  961. package/dist/chunk-WL2Y2T47.js.map +0 -1
  962. package/dist/chunk-WUTL62MC.js.map +0 -1
  963. package/dist/chunk-XWPLOFDN.js +0 -644
  964. package/dist/chunk-XWPLOFDN.js.map +0 -1
  965. package/dist/chunk-Y3MTRA7D.js +0 -97
  966. package/dist/chunk-Y3MTRA7D.js.map +0 -1
  967. package/dist/chunk-YNNAJJ5Z.js.map +0 -1
  968. package/dist/chunk-ZM6N7YZH.js.map +0 -1
  969. package/dist/document-tools/core.d.cts +0 -883
  970. package/dist/document-tools/index.d.cts +0 -90
  971. package/dist/index.d-LArLnpI8.d.cts +0 -2036
  972. package/dist/index.d-oR5FKZpJ.d.cts +0 -579
  973. package/dist/index.d.cts +0 -15923
  974. package/dist/lazy-chunk.d-B6YDLMKI.d.cts +0 -31
  975. package/dist/model.d-CNtRWKVK.d.cts +0 -110
  976. package/dist/query-keys.d-B1Am9tIF.d.cts +0 -337
  977. package/dist/shell/index.d.cts +0 -6
  978. package/dist/store.d-GADDvC7w.d.cts +0 -35
  979. package/dist/stored-markdown.d-Bp18vrbr.d.cts +0 -125
  980. package/dist/ui/index.d.cts +0 -26
  981. package/dist/useAudioRecorder.d-B9rlMI_E.d.cts +0 -778
  982. package/dist/viewers/PdfViewer.d.cts +0 -9
  983. package/dist/viewers/index.d.cts +0 -262
@@ -0,0 +1,7 @@
1
+ {
2
+ "version": 3,
3
+ "sources": ["../../src/ai/CitationRenderer.tsx"],
4
+ "sourcesContent": ["import React, { useMemo, useCallback, useEffect, useLayoutEffect, useRef, useState } from 'react'\nimport { createPortal } from 'react-dom'\nimport ReactMarkdown, { Components } from 'react-markdown'\nimport type { components } from '@arbidocs/client'\nimport { MarkMenu, returnFocusToMark, type MarkMenuItem } from '../ui/mark-menu'\nimport { cn } from '../lib/utils'\nimport { normalizeCitationMarkup } from './normalize-citations'\n\n/**\n * Presentational core of the ARBI citation renderer \u2014 promoted from the monolith\n * as the callback-injection reference for the AI family. It owns all the hard-won\n * citation behaviour (numbering, per-doc grouping, hover/active highlighting,\n * click/open flows, emphasis-safe markdown parsing) but knows NOTHING about the\n * app's store, router or React Query. Every app coupling is injected:\n *\n * - `renderMarkdown` \u2014 the app's `MarkdownRenderer` (KaTeX / Mermaid / doc-entity\n * pills all stay app-side; the core just hands it the citation `a` override).\n * - `ExternalLink` \u2014 the app's confirm-before-open external-link component.\n * - `onOpenCitation` / `onActivateChunk` \u2014 replace the two store writes that used\n * to fire when a citation opens / a chunk card is clicked.\n * - `useCitationState` \u2014 an injected hook the popover calls to read the reactive\n * active-citation / viewing-passage / active-page state (kept as a hook so the\n * subscription stays local to each popover, exactly as before \u2014 the top-level\n * renderer never re-renders on citation state changes, so the markdown is never\n * re-parsed mid-interaction).\n * - `onCloseCitation` / `onDismissCitation` \u2014 the two distinct close flows.\n */\n\n// Renders markdown inline (no block wrappers) for single-line truncated display\nconst INLINE_MD_COMPONENTS = {\n p: ({ children }: { children?: React.ReactNode }) => <>{children}</>,\n strong: ({ children }: { children?: React.ReactNode }) => (\n <strong className=\"font-semibold\">{children}</strong>\n ),\n em: ({ children }: { children?: React.ReactNode }) => <em>{children}</em>,\n code: ({ children }: { children?: React.ReactNode }) => (\n <code className=\"font-mono\">{children}</code>\n ),\n a: ({ children }: { children?: React.ReactNode }) => <>{children}</>,\n ul: ({ children }: { children?: React.ReactNode }) => <>{children}</>,\n ol: ({ children }: { children?: React.ReactNode }) => <>{children}</>,\n li: ({ children }: { children?: React.ReactNode }) => <span>{children} </span>,\n h1: ({ children }: { children?: React.ReactNode }) => <>{children}</>,\n h2: ({ children }: { children?: React.ReactNode }) => <>{children}</>,\n h3: ({ children }: { children?: React.ReactNode }) => <>{children}</>,\n h4: ({ children }: { children?: React.ReactNode }) => <>{children}</>,\n h5: ({ children }: { children?: React.ReactNode }) => <>{children}</>,\n h6: ({ children }: { children?: React.ReactNode }) => <>{children}</>,\n blockquote: ({ children }: { children?: React.ReactNode }) => <>{children}</>,\n pre: ({ children }: { children?: React.ReactNode }) => <>{children}</>,\n}\n\n// Structural citation types, sourced from the canonical OpenAPI schema so the\n// core stays in lockstep with the app's `Chunk` / `ToolResponses` shapes.\nexport type Chunk = components['schemas']['Chunk']\nexport interface ToolResponses {\n [docId: string]: Chunk[]\n}\n\n/** Reactive citation state the popover reads (injected as a hook by the app). */\nexport interface CitationState {\n activeCitationKey: string | null\n viewingPassageId: string | null\n isOnConversationPage: boolean\n}\n\n/** Payload handed to the app when a chunk card is clicked / a citation opens. */\nexport interface ChunkActivation {\n messageId: string\n citationNum: string\n chunkIds: string[]\n chunk: Chunk\n citationData?: ToolResponses\n}\n\n/** Renders the citation content as markdown \u2014 the app supplies its MarkdownRenderer. */\nexport type RenderMarkdown = (args: {\n components: Partial<Components>\n isStreaming: boolean\n children: string\n}) => React.ReactNode\n\nexport interface CitationRendererProps {\n content: string\n citations?: Record<string, string[]>\n citationData?: ToolResponses\n className?: string\n messageId: string\n isStreaming?: boolean\n // \u2500\u2500 injected app bindings \u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\n renderMarkdown: RenderMarkdown\n ExternalLink: React.ComponentType<React.ComponentPropsWithoutRef<'a'>>\n onOpenCitation: (citationKey: string) => void\n onActivateChunk: (activation: ChunkActivation) => void\n useCitationState: () => CitationState\n onCloseCitation: () => void\n onDismissCitation: () => void\n /** Tells the user a citation was copied (or could not be). Optional: copying is silent without it. */\n notify?: (message: string, kind?: 'success' | 'error' | 'info') => void\n /** Display names keyed by doc_ext_id. A chunk's `doc_title` is the raw upload name, which can\n * differ from the name the workspace shows; when a name is given here it is used instead. */\n docTitles?: ReadonlyMap<string, string>\n}\n\nconst CitationRendererComponent: React.FC<CitationRendererProps> = ({\n content,\n citations,\n citationData,\n className,\n messageId,\n isStreaming = false,\n renderMarkdown,\n ExternalLink,\n onOpenCitation,\n onActivateChunk,\n useCitationState,\n onCloseCitation,\n onDismissCitation,\n notify,\n docTitles,\n}) => {\n const chunkMap = useMemo(() => {\n const map = new Map<string, Chunk>()\n if (citationData) {\n Object.entries(citationData as ToolResponses).forEach(([, docChunks]) => {\n if (docChunks && Array.isArray(docChunks)) {\n docChunks.forEach((chunk: Chunk) => {\n if (chunk.metadata && chunk.metadata.chunk_ext_id) {\n const displayTitle = chunk.metadata.doc_ext_id\n ? docTitles?.get(chunk.metadata.doc_ext_id)\n : undefined\n map.set(\n chunk.metadata.chunk_ext_id,\n displayTitle\n ? { ...chunk, metadata: { ...chunk.metadata, doc_title: displayTitle } }\n : chunk\n )\n }\n })\n }\n })\n }\n return map\n }, [citationData, docTitles])\n\n const getChunkDetails = useCallback(\n (chunkIds: string[]): Chunk[] =>\n [...new Set(chunkIds)]\n .map((id) => chunkMap.get(id))\n .filter((c): c is Chunk => c !== undefined),\n [chunkMap]\n )\n\n const handleChunkClick = useCallback(\n (citationNum: string, chunkIds: string[], chunk: Chunk) => {\n onActivateChunk({ messageId, citationNum, chunkIds, chunk, citationData })\n },\n [messageId, citationData, onActivateChunk]\n )\n\n // What the citation links read. It reaches them through context, not through the markdown\n // components, so the components keep one identity and a new copy of the answer (a refetch, a\n // cache write, new document titles) re-renders the citations instead of remounting them: a\n // remount drops the mark an open citation dialog returns focus to.\n const anchorContext = useMemo<CitationAnchorContextValue>(\n () => ({\n citations,\n messageId,\n isStreaming,\n getChunkDetails,\n handleChunkClick,\n onOpenCitation,\n ExternalLink,\n useCitationState,\n onCloseCitation,\n onDismissCitation,\n notify,\n }),\n [\n citations,\n messageId,\n isStreaming,\n getChunkDetails,\n handleChunkClick,\n onOpenCitation,\n ExternalLink,\n useCitationState,\n onCloseCitation,\n onDismissCitation,\n notify,\n ]\n )\n\n // Citation markers `[text](#cite-N)` are already valid markdown link syntax.\n // We let react-markdown parse them natively (the `a` override above keys on the\n // `#cite-` href) instead of pre-converting to raw HTML \u2014 so emphasis inside the\n // cited text (**bold**, *italic*, `code`) and literal `*`/`_` characters survive\n // intact, and link boundaries can never split an emphasis span.\n return (\n <CitationAnchorContext.Provider value={anchorContext}>\n <div className={cn('citation-container', className)} data-testid=\"citation-renderer\">\n {renderMarkdown({\n components: CITATION_MARKDOWN_COMPONENTS,\n isStreaming,\n children: normalizeCitationMarkup(content),\n })}\n </div>\n </CitationAnchorContext.Provider>\n )\n}\n\n// \u2500\u2500 CitationAnchor \u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\n\ninterface CitationAnchorContextValue {\n citations?: Record<string, string[]>\n messageId: string\n isStreaming: boolean\n getChunkDetails: (chunkIds: string[]) => Chunk[]\n handleChunkClick: (citationNum: string, chunkIds: string[], chunk: Chunk) => void\n onOpenCitation: (citationKey: string) => void\n ExternalLink: React.ComponentType<React.ComponentPropsWithoutRef<'a'>>\n useCitationState: () => CitationState\n onCloseCitation: () => void\n onDismissCitation: () => void\n notify?: CitationRendererProps['notify']\n}\n\nconst CitationAnchorContext = React.createContext<CitationAnchorContextValue | null>(null)\n\n/** Every link in an answer: `#cite-N` is a citation, anything else a plain or external link. */\nfunction CitationAnchor({\n href,\n children,\n ...rest\n}: React.ComponentPropsWithoutRef<'a'> & { node?: unknown }) {\n // react-markdown's syntax-tree node is not a DOM attribute.\n const { node, ...props } = rest\n void node\n const ctx = React.useContext(CitationAnchorContext)\n if (!ctx || !href?.startsWith('#cite-')) {\n if (!ctx || !href || href.startsWith('#')) {\n return (\n <a className=\"text-primary underline underline-offset-2\" href={href} {...props}>\n {children}\n </a>\n )\n }\n const { ExternalLink } = ctx\n return (\n <ExternalLink href={href} {...props}>\n {children}\n </ExternalLink>\n )\n }\n\n const citationNum = href.slice(6)\n const { messageId, citations, getChunkDetails, handleChunkClick, onOpenCitation } = ctx\n const citationKey = `${messageId}-${citationNum}`\n const chunkIds = citations?.[citationNum] || []\n const chunks = getChunkDetails(chunkIds)\n\n return (\n <CitationPopover\n key={citationKey}\n citationNum={citationNum}\n messageId={messageId}\n chunks={chunks}\n isStreaming={ctx.isStreaming}\n onOpen={() => onOpenCitation(citationKey)}\n onChunkClick={(chunk) => handleChunkClick(citationNum, chunkIds, chunk)}\n useCitationState={ctx.useCitationState}\n onCloseCitation={ctx.onCloseCitation}\n onDismissCitation={ctx.onDismissCitation}\n notify={ctx.notify}\n >\n {children}\n </CitationPopover>\n )\n}\n\n/** One identity for the life of the module: see `anchorContext`. */\nconst CITATION_MARKDOWN_COMPONENTS: Partial<Components> = { a: CitationAnchor }\n\n// \u2500\u2500 CitationPopover \u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\n\n/** Space between the docked popover and the composer below it (and the screen top above it). */\nconst DOCK_GAP_PX = 8\n\ninterface CitationPopoverProps {\n citationNum: string\n messageId: string\n chunks: Chunk[]\n isStreaming: boolean\n onOpen: () => void\n onChunkClick: (chunk: Chunk) => void\n useCitationState: () => CitationState\n onCloseCitation: () => void\n onDismissCitation: () => void\n notify?: CitationRendererProps['notify']\n children: React.ReactNode\n}\n\nconst CitationPopover: React.FC<CitationPopoverProps> = ({\n citationNum,\n messageId,\n chunks,\n isStreaming,\n onOpen,\n onChunkClick,\n useCitationState,\n onCloseCitation,\n onDismissCitation,\n notify,\n children,\n}) => {\n const { activeCitationKey, viewingPassageId, isOnConversationPage } = useCitationState()\n const isActive = activeCitationKey === `${messageId}-${citationNum}`\n // Gate on the app's navigation state, not useLocation(): in-app navigation\n // rewrites the hash via history.replaceState, which react-router never\n // observes, so its location stays frozen at the page-load value.\n const open = isActive && isOnConversationPage\n\n // The popover belongs to the conversation view. If the user leaves it (another page, or a\n // full-screen panel over it) while it is open, drop the active key so it neither floats over\n // the new view nor reappears when they come back.\n useEffect(() => {\n if (isActive && !isOnConversationPage) onDismissCitation()\n }, [isActive, isOnConversationPage, onDismissCitation])\n\n const triggerRef = useRef<HTMLElement>(null)\n const dialogRef = useRef<HTMLDivElement>(null)\n // Set when the user closes it (Escape / the X): focus then goes back to the citation they came\n // from. A close caused by something else (another citation, leaving the page) leaves focus alone.\n const restoreFocusRef = useRef(false)\n\n const dismiss = useCallback(() => {\n restoreFocusRef.current = true\n onDismissCitation()\n }, [onDismissCitation])\n\n // The popover is portalled to the end of <body>, so a keyboard or screen-reader user who\n // opened it would otherwise have to Tab through the whole page to reach it. Move focus into the\n // dialog on open (taps do not focus a span on iOS, so this is not gated on the trigger) and\n // return it to the citation when the user dismisses.\n useEffect(() => {\n if (!open) return\n dialogRef.current?.focus({ preventScroll: true })\n return () => {\n if (!restoreFocusRef.current) return\n restoreFocusRef.current = false\n if (triggerRef.current) returnFocusToMark(triggerRef.current)\n }\n }, [open])\n\n // Escape closes like the X: the popover goes, the passage stays in the viewer.\n useEffect(() => {\n if (!open) return\n const onKeyDown = (e: KeyboardEvent) => {\n if (e.key === 'Escape') dismiss()\n }\n document.addEventListener('keydown', onKeyDown)\n return () => document.removeEventListener('keydown', onKeyDown)\n }, [open, dismiss])\n\n // The popover docks to the top edge of the composer (full chat width) instead of the cited\n // word, so it never covers the answer paragraph being cited. The edge is measured while it is\n // open, and again whenever the composer changes size: opening a citation also opens the document\n // viewer, which narrows the chat column after the first measurement.\n const [dock, setDock] = useState({ left: 0, top: 0, width: 0 })\n\n // Measured whenever it opens, however it was opened (click, keyboard, a source chip).\n useLayoutEffect(() => {\n if (!open) return\n // The composer is exactly the chat column (the main element also spans a docked viewer).\n const edge =\n document.querySelector('[data-testid=\"message-input-container\"]') ??\n document.querySelector('main[data-testid^=\"conversation-\"]') ??\n document.body\n const measure = () => {\n const rect = edge.getBoundingClientRect()\n setDock({ left: rect.left, top: rect.top, width: rect.width })\n }\n measure()\n const observer = new ResizeObserver(measure)\n observer.observe(edge)\n window.addEventListener('resize', measure)\n return () => {\n observer.disconnect()\n window.removeEventListener('resize', measure)\n }\n }, [open])\n\n const handleOpen = useCallback(() => {\n onOpen()\n if (chunks.length > 0) {\n onChunkClick(chunks[0])\n }\n }, [onOpen, onChunkClick, chunks])\n\n const byDoc = useMemo(() => {\n const map = new Map<string, { title: string; chunks: Chunk[] }>()\n chunks.forEach((chunk) => {\n const docId = chunk.metadata.doc_ext_id ?? 'unknown'\n const title = chunk.metadata.doc_title ?? docId\n if (!map.has(docId)) map.set(docId, { title, chunks: [] })\n map.get(docId)!.chunks.push(chunk)\n })\n return Array.from(map.entries()).map(([docId, val]) => ({ docId, ...val }))\n }, [chunks])\n\n const first = chunks[0]\n const firstText = first ? first.content.replace(/\\n+/g, ' ').trim() : ''\n const firstTitle = first ? (first.metadata.doc_title ?? first.metadata.doc_ext_id ?? '') : ''\n const firstPage = first?.metadata.page_number\n\n const copyCitation = useCallback(async () => {\n const source = [firstTitle, firstPage != null ? `p.${firstPage}` : null]\n .filter(Boolean)\n .join(', ')\n try {\n await navigator.clipboard.writeText(source ? `\u201C${firstText}\u201D (${source})` : firstText)\n notify?.('Citation copied', 'success')\n } catch {\n notify?.('Could not copy the citation', 'error')\n }\n }, [firstText, firstTitle, firstPage, notify])\n\n const items: MarkMenuItem[] =\n isStreaming || chunks.length === 0\n ? []\n : [\n {\n id: 'open',\n label: 'Open in viewer',\n primary: true,\n onSelect: handleOpen,\n testId: `citation-open-${citationNum}`,\n },\n {\n id: 'copy',\n label: 'Copy citation',\n onSelect: () => void copyCitation(),\n testId: `citation-copy-${citationNum}`,\n },\n ]\n\n // The cited passage itself: quoted text, its source and page, before anything is opened.\n const preview = first ? (\n <div className=\"max-w-xs\" data-testid={`citation-preview-${citationNum}`}>\n <span className=\"block text-xs font-medium text-foreground\">{firstTitle}</span>\n {firstPage != null && (\n <span className=\"block text-xs text-muted-foreground\">Page {firstPage}</span>\n )}\n <span className=\"mt-1 line-clamp-4 block text-sm text-foreground\">\n <ReactMarkdown components={INLINE_MD_COMPONENTS}>{firstText}</ReactMarkdown>\n </span>\n {chunks.length > 1 && (\n <span className=\"mt-1 block text-xs text-muted-foreground\">\n +{chunks.length - 1} more passage{chunks.length > 2 ? 's' : ''}\n </span>\n )}\n </div>\n ) : undefined\n\n return (\n <>\n <CitationLink\n triggerRef={triggerRef}\n citationNum={citationNum}\n isActive={isActive}\n isStreaming={isStreaming}\n items={items}\n preview={preview}\n >\n {children}\n </CitationLink>\n {open &&\n createPortal(\n <div\n className=\"pointer-events-none fixed z-[42] flex justify-center px-2\"\n style={{\n left: dock.left,\n width: dock.width,\n bottom: window.innerHeight - dock.top + DOCK_GAP_PX,\n }}\n >\n <div\n ref={dialogRef}\n role=\"dialog\"\n tabIndex={-1}\n aria-label={`Citation ${citationNum}`}\n // Never taller than the room above the composer (it sits 8px above it, and keeps 8px\n // from the top of the screen): on a landscape phone 45vh is more than that room, and\n // the header rose off the top of the screen.\n style={{ maxHeight: `min(45vh, ${Math.max(dock.top - 2 * DOCK_GAP_PX, 0)}px)` }}\n className=\"pointer-events-auto z-[42] outline-none w-[min(100%,48rem)] min-w-0 overflow-y-auto rounded-md border border-border bg-popover p-0 text-popover-foreground shadow-xl\"\n data-testid={`citation-popover-${citationNum}`}\n >\n <div className=\"px-3 py-2 pointer-coarse:py-0 border-b border-border sticky top-0 bg-popover z-10 flex items-center justify-between gap-2\">\n <span className=\"text-xs font-semibold text-muted-foreground tracking-wide\">\n Citation {citationNum} ({chunks.length} passage{chunks.length !== 1 ? 's' : ''})\n </span>\n <button\n onClick={dismiss}\n // A bare 12px glyph is a tiny target \u2014 easy to miss, so closing takes\n // several tries. Pad it out to a comfortable ~28px tap area (negative\n // margin keeps the icon where it sat, so the header layout is\n // unchanged) and give it a hover background so it reads as a button.\n className=\"-m-1.5 flex shrink-0 items-center justify-center rounded p-1.5 text-muted-foreground transition-colors hover:bg-muted hover:text-foreground pointer-coarse:m-0 pointer-coarse:size-11 pointer-coarse:p-0\"\n aria-label=\"Close\"\n data-testid={`citation-popover-close-${citationNum}`}\n >\n <svg\n width=\"14\"\n height=\"14\"\n viewBox=\"0 0 12 12\"\n fill=\"none\"\n xmlns=\"http://www.w3.org/2000/svg\"\n >\n <path\n d=\"M1 1L11 11M11 1L1 11\"\n stroke=\"currentColor\"\n strokeWidth=\"1.5\"\n strokeLinecap=\"round\"\n />\n </svg>\n </button>\n </div>\n {byDoc.map(({ docId, title, chunks: docChunks }) => (\n <div key={docId} className=\"px-3 py-2 border-b border-border last:border-0\">\n <p className=\"text-sm font-semibold text-foreground mb-1 truncate\" title={title}>\n {title}\n </p>\n {docChunks.map((chunk) => {\n const isSelected = viewingPassageId === chunk.metadata.chunk_ext_id\n return (\n <button\n key={chunk.metadata.chunk_ext_id}\n data-testid={`citation-chunk-${chunk.metadata.chunk_ext_id}`}\n onClick={() => onChunkClick(chunk)}\n className={cn(\n 'w-full text-left text-sm rounded-md px-2 py-1.5 pointer-coarse:min-h-11 pointer-coarse:py-3 transition-colors flex items-start gap-2 mb-1 last:mb-0',\n isSelected\n ? 'bg-ai-soft text-foreground ring-1 ring-ai-accent/40'\n : 'text-muted-foreground hover:text-primary hover:bg-muted'\n )}\n >\n <span className=\"min-w-0 flex-1\">\n {chunk.metadata.page_number != null && (\n <span className=\"block text-xs text-muted-foreground\">\n Page {chunk.metadata.page_number}\n </span>\n )}\n <span className=\"line-clamp-3 italic\">\n <ReactMarkdown components={INLINE_MD_COMPONENTS}>\n {chunk.content.replace(/\\n+/g, ' ').trim()}\n </ReactMarkdown>\n </span>\n </span>\n </button>\n )\n })}\n </div>\n ))}\n </div>\n </div>,\n document.body\n )}\n </>\n )\n}\n\n// \u2500\u2500 CitationLink \u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\n\ninterface CitationLinkProps {\n citationNum: string\n isActive: boolean\n isStreaming: boolean\n items: MarkMenuItem[]\n preview: React.ReactNode\n triggerRef: React.Ref<HTMLElement>\n children: React.ReactNode\n}\n\n/**\n * The cited words with a faint wash and a superscript number: quiet text, not a badge.\n * Its one menu (preview of the passage, Open in viewer, Copy citation) is the shared `MarkMenu`.\n */\nconst CitationLink: React.FC<CitationLinkProps> = ({\n citationNum,\n isActive,\n isStreaming,\n items,\n preview,\n triggerRef,\n children,\n}) => (\n <MarkMenu\n triggerRef={triggerRef}\n items={items}\n preview={isStreaming ? undefined : preview}\n menuLabel={`Citation ${citationNum}`}\n testId={`citation-link-${citationNum}`}\n tabIndex={isStreaming ? -1 : 0}\n data-mark-kind=\"citation\"\n className={cn(\n 'cited-text relative rounded-sm px-0.5 transition-colors',\n // 44px touch hit area without changing the text layout. `touch-hit` grows only up to\n // 44px (never past the mark's own width), so it doesn't reach over the neighbouring\n // citation: a fixed inset let citation 2's area cover citation 1, and a tap on [1]\n // opened [2].\n 'touch-hit',\n isStreaming ? 'cursor-default' : 'cursor-pointer',\n isActive ? 'bg-ai-soft text-foreground' : 'bg-ai-soft/30 hover:bg-ai-soft/70'\n )}\n >\n {children}\n {/* Readable floor: never below the text-xs token, bold, so the number is easy to spot.\n `top-0` cancels preflight's `sup { top: -0.5em }`, which would raise the number a second\n time and push it up into the line above (most visible in table cells). */}\n <sup className=\"ml-px top-0 align-super text-[max(0.8em,var(--text-xs))] font-bold leading-none tabular-nums text-ai-ink\">\n {citationNum}\n </sup>\n </MarkMenu>\n)\n\nexport const CitationRenderer = React.memo(CitationRendererComponent)\n"],
5
+ "mappings": "AA8BuD,wBAWC,YAXD;AA9BvD,OAAO,SAAS,SAAS,aAAa,WAAW,iBAAiB,QAAQ,gBAAgB;AAC1F,SAAS,oBAAoB;AAC7B,OAAO,mBAAmC;AAE1C,SAAS,UAAU,yBAA4C;AAC/D,SAAS,UAAU;AACnB,SAAS,+BAA+B;AAuBxC,MAAM,uBAAuB;AAAA,EAC3B,GAAG,CAAC,EAAE,SAAS,MAAsC,gCAAG,UAAS;AAAA,EACjE,QAAQ,CAAC,EAAE,SAAS,MAClB,oBAAC,YAAO,WAAU,iBAAiB,UAAS;AAAA,EAE9C,IAAI,CAAC,EAAE,SAAS,MAAsC,oBAAC,QAAI,UAAS;AAAA,EACpE,MAAM,CAAC,EAAE,SAAS,MAChB,oBAAC,UAAK,WAAU,aAAa,UAAS;AAAA,EAExC,GAAG,CAAC,EAAE,SAAS,MAAsC,gCAAG,UAAS;AAAA,EACjE,IAAI,CAAC,EAAE,SAAS,MAAsC,gCAAG,UAAS;AAAA,EAClE,IAAI,CAAC,EAAE,SAAS,MAAsC,gCAAG,UAAS;AAAA,EAClE,IAAI,CAAC,EAAE,SAAS,MAAsC,qBAAC,UAAM;AAAA;AAAA,IAAS;AAAA,KAAC;AAAA,EACvE,IAAI,CAAC,EAAE,SAAS,MAAsC,gCAAG,UAAS;AAAA,EAClE,IAAI,CAAC,EAAE,SAAS,MAAsC,gCAAG,UAAS;AAAA,EAClE,IAAI,CAAC,EAAE,SAAS,MAAsC,gCAAG,UAAS;AAAA,EAClE,IAAI,CAAC,EAAE,SAAS,MAAsC,gCAAG,UAAS;AAAA,EAClE,IAAI,CAAC,EAAE,SAAS,MAAsC,gCAAG,UAAS;AAAA,EAClE,IAAI,CAAC,EAAE,SAAS,MAAsC,gCAAG,UAAS;AAAA,EAClE,YAAY,CAAC,EAAE,SAAS,MAAsC,gCAAG,UAAS;AAAA,EAC1E,KAAK,CAAC,EAAE,SAAS,MAAsC,gCAAG,UAAS;AACrE;AAsDA,MAAM,4BAA6D,CAAC;AAAA,EAClE;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA,cAAc;AAAA,EACd;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AACF,MAAM;AACJ,QAAM,WAAW,QAAQ,MAAM;AAC7B,UAAM,MAAM,oBAAI,IAAmB;AACnC,QAAI,cAAc;AAChB,aAAO,QAAQ,YAA6B,EAAE,QAAQ,CAAC,CAAC,EAAE,SAAS,MAAM;AACvE,YAAI,aAAa,MAAM,QAAQ,SAAS,GAAG;AACzC,oBAAU,QAAQ,CAAC,UAAiB;AAClC,gBAAI,MAAM,YAAY,MAAM,SAAS,cAAc;AACjD,oBAAM,eAAe,MAAM,SAAS,aAChC,WAAW,IAAI,MAAM,SAAS,UAAU,IACxC;AACJ,kBAAI;AAAA,gBACF,MAAM,SAAS;AAAA,gBACf,eACI,EAAE,GAAG,OAAO,UAAU,EAAE,GAAG,MAAM,UAAU,WAAW,aAAa,EAAE,IACrE;AAAA,cACN;AAAA,YACF;AAAA,UACF,CAAC;AAAA,QACH;AAAA,MACF,CAAC;AAAA,IACH;AACA,WAAO;AAAA,EACT,GAAG,CAAC,cAAc,SAAS,CAAC;AAE5B,QAAM,kBAAkB;AAAA,IACtB,CAAC,aACC,CAAC,GAAG,IAAI,IAAI,QAAQ,CAAC,EAClB,IAAI,CAAC,OAAO,SAAS,IAAI,EAAE,CAAC,EAC5B,OAAO,CAAC,MAAkB,MAAM,MAAS;AAAA,IAC9C,CAAC,QAAQ;AAAA,EACX;AAEA,QAAM,mBAAmB;AAAA,IACvB,CAAC,aAAqB,UAAoB,UAAiB;AACzD,sBAAgB,EAAE,WAAW,aAAa,UAAU,OAAO,aAAa,CAAC;AAAA,IAC3E;AAAA,IACA,CAAC,WAAW,cAAc,eAAe;AAAA,EAC3C;AAMA,QAAM,gBAAgB;AAAA,IACpB,OAAO;AAAA,MACL;AAAA,MACA;AAAA,MACA;AAAA,MACA;AAAA,MACA;AAAA,MACA;AAAA,MACA;AAAA,MACA;AAAA,MACA;AAAA,MACA;AAAA,MACA;AAAA,IACF;AAAA,IACA;AAAA,MACE;AAAA,MACA;AAAA,MACA;AAAA,MACA;AAAA,MACA;AAAA,MACA;AAAA,MACA;AAAA,MACA;AAAA,MACA;AAAA,MACA;AAAA,MACA;AAAA,IACF;AAAA,EACF;AAOA,SACE,oBAAC,sBAAsB,UAAtB,EAA+B,OAAO,eACrC,8BAAC,SAAI,WAAW,GAAG,sBAAsB,SAAS,GAAG,eAAY,qBAC9D,yBAAe;AAAA,IACd,YAAY;AAAA,IACZ;AAAA,IACA,UAAU,wBAAwB,OAAO;AAAA,EAC3C,CAAC,GACH,GACF;AAEJ;AAkBA,MAAM,wBAAwB,MAAM,cAAiD,IAAI;AAGzF,SAAS,eAAe;AAAA,EACtB;AAAA,EACA;AAAA,EACA,GAAG;AACL,GAA6D;AAE3D,QAAM,EAAE,MAAM,GAAG,MAAM,IAAI;AAC3B,OAAK;AACL,QAAM,MAAM,MAAM,WAAW,qBAAqB;AAClD,MAAI,CAAC,OAAO,CAAC,MAAM,WAAW,QAAQ,GAAG;AACvC,QAAI,CAAC,OAAO,CAAC,QAAQ,KAAK,WAAW,GAAG,GAAG;AACzC,aACE,oBAAC,OAAE,WAAU,6CAA4C,MAAa,GAAG,OACtE,UACH;AAAA,IAEJ;AACA,UAAM,EAAE,aAAa,IAAI;AACzB,WACE,oBAAC,gBAAa,MAAa,GAAG,OAC3B,UACH;AAAA,EAEJ;AAEA,QAAM,cAAc,KAAK,MAAM,CAAC;AAChC,QAAM,EAAE,WAAW,WAAW,iBAAiB,kBAAkB,eAAe,IAAI;AACpF,QAAM,cAAc,GAAG,SAAS,IAAI,WAAW;AAC/C,QAAM,WAAW,YAAY,WAAW,KAAK,CAAC;AAC9C,QAAM,SAAS,gBAAgB,QAAQ;AAEvC,SACE;AAAA,IAAC;AAAA;AAAA,MAEC;AAAA,MACA;AAAA,MACA;AAAA,MACA,aAAa,IAAI;AAAA,MACjB,QAAQ,MAAM,eAAe,WAAW;AAAA,MACxC,cAAc,CAAC,UAAU,iBAAiB,aAAa,UAAU,KAAK;AAAA,MACtE,kBAAkB,IAAI;AAAA,MACtB,iBAAiB,IAAI;AAAA,MACrB,mBAAmB,IAAI;AAAA,MACvB,QAAQ,IAAI;AAAA,MAEX;AAAA;AAAA,IAZI;AAAA,EAaP;AAEJ;AAGA,MAAM,+BAAoD,EAAE,GAAG,eAAe;AAK9E,MAAM,cAAc;AAgBpB,MAAM,kBAAkD,CAAC;AAAA,EACvD;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AACF,MAAM;AACJ,QAAM,EAAE,mBAAmB,kBAAkB,qBAAqB,IAAI,iBAAiB;AACvF,QAAM,WAAW,sBAAsB,GAAG,SAAS,IAAI,WAAW;AAIlE,QAAM,OAAO,YAAY;AAKzB,YAAU,MAAM;AACd,QAAI,YAAY,CAAC,qBAAsB,mBAAkB;AAAA,EAC3D,GAAG,CAAC,UAAU,sBAAsB,iBAAiB,CAAC;AAEtD,QAAM,aAAa,OAAoB,IAAI;AAC3C,QAAM,YAAY,OAAuB,IAAI;AAG7C,QAAM,kBAAkB,OAAO,KAAK;AAEpC,QAAM,UAAU,YAAY,MAAM;AAChC,oBAAgB,UAAU;AAC1B,sBAAkB;AAAA,EACpB,GAAG,CAAC,iBAAiB,CAAC;AAMtB,YAAU,MAAM;AACd,QAAI,CAAC,KAAM;AACX,cAAU,SAAS,MAAM,EAAE,eAAe,KAAK,CAAC;AAChD,WAAO,MAAM;AACX,UAAI,CAAC,gBAAgB,QAAS;AAC9B,sBAAgB,UAAU;AAC1B,UAAI,WAAW,QAAS,mBAAkB,WAAW,OAAO;AAAA,IAC9D;AAAA,EACF,GAAG,CAAC,IAAI,CAAC;AAGT,YAAU,MAAM;AACd,QAAI,CAAC,KAAM;AACX,UAAM,YAAY,CAAC,MAAqB;AACtC,UAAI,EAAE,QAAQ,SAAU,SAAQ;AAAA,IAClC;AACA,aAAS,iBAAiB,WAAW,SAAS;AAC9C,WAAO,MAAM,SAAS,oBAAoB,WAAW,SAAS;AAAA,EAChE,GAAG,CAAC,MAAM,OAAO,CAAC;AAMlB,QAAM,CAAC,MAAM,OAAO,IAAI,SAAS,EAAE,MAAM,GAAG,KAAK,GAAG,OAAO,EAAE,CAAC;AAG9D,kBAAgB,MAAM;AACpB,QAAI,CAAC,KAAM;AAEX,UAAM,OACJ,SAAS,cAAc,yCAAyC,KAChE,SAAS,cAAc,oCAAoC,KAC3D,SAAS;AACX,UAAM,UAAU,MAAM;AACpB,YAAM,OAAO,KAAK,sBAAsB;AACxC,cAAQ,EAAE,MAAM,KAAK,MAAM,KAAK,KAAK,KAAK,OAAO,KAAK,MAAM,CAAC;AAAA,IAC/D;AACA,YAAQ;AACR,UAAM,WAAW,IAAI,eAAe,OAAO;AAC3C,aAAS,QAAQ,IAAI;AACrB,WAAO,iBAAiB,UAAU,OAAO;AACzC,WAAO,MAAM;AACX,eAAS,WAAW;AACpB,aAAO,oBAAoB,UAAU,OAAO;AAAA,IAC9C;AAAA,EACF,GAAG,CAAC,IAAI,CAAC;AAET,QAAM,aAAa,YAAY,MAAM;AACnC,WAAO;AACP,QAAI,OAAO,SAAS,GAAG;AACrB,mBAAa,OAAO,CAAC,CAAC;AAAA,IACxB;AAAA,EACF,GAAG,CAAC,QAAQ,cAAc,MAAM,CAAC;AAEjC,QAAM,QAAQ,QAAQ,MAAM;AAC1B,UAAM,MAAM,oBAAI,IAAgD;AAChE,WAAO,QAAQ,CAAC,UAAU;AACxB,YAAM,QAAQ,MAAM,SAAS,cAAc;AAC3C,YAAM,QAAQ,MAAM,SAAS,aAAa;AAC1C,UAAI,CAAC,IAAI,IAAI,KAAK,EAAG,KAAI,IAAI,OAAO,EAAE,OAAO,QAAQ,CAAC,EAAE,CAAC;AACzD,UAAI,IAAI,KAAK,EAAG,OAAO,KAAK,KAAK;AAAA,IACnC,CAAC;AACD,WAAO,MAAM,KAAK,IAAI,QAAQ,CAAC,EAAE,IAAI,CAAC,CAAC,OAAO,GAAG,OAAO,EAAE,OAAO,GAAG,IAAI,EAAE;AAAA,EAC5E,GAAG,CAAC,MAAM,CAAC;AAEX,QAAM,QAAQ,OAAO,CAAC;AACtB,QAAM,YAAY,QAAQ,MAAM,QAAQ,QAAQ,QAAQ,GAAG,EAAE,KAAK,IAAI;AACtE,QAAM,aAAa,QAAS,MAAM,SAAS,aAAa,MAAM,SAAS,cAAc,KAAM;AAC3F,QAAM,YAAY,OAAO,SAAS;AAElC,QAAM,eAAe,YAAY,YAAY;AAC3C,UAAM,SAAS,CAAC,YAAY,aAAa,OAAO,KAAK,SAAS,KAAK,IAAI,EACpE,OAAO,OAAO,EACd,KAAK,IAAI;AACZ,QAAI;AACF,YAAM,UAAU,UAAU,UAAU,SAAS,SAAI,SAAS,WAAM,MAAM,MAAM,SAAS;AACrF,eAAS,mBAAmB,SAAS;AAAA,IACvC,QAAQ;AACN,eAAS,+BAA+B,OAAO;AAAA,IACjD;AAAA,EACF,GAAG,CAAC,WAAW,YAAY,WAAW,MAAM,CAAC;AAE7C,QAAM,QACJ,eAAe,OAAO,WAAW,IAC7B,CAAC,IACD;AAAA,IACE;AAAA,MACE,IAAI;AAAA,MACJ,OAAO;AAAA,MACP,SAAS;AAAA,MACT,UAAU;AAAA,MACV,QAAQ,iBAAiB,WAAW;AAAA,IACtC;AAAA,IACA;AAAA,MACE,IAAI;AAAA,MACJ,OAAO;AAAA,MACP,UAAU,MAAM,KAAK,aAAa;AAAA,MAClC,QAAQ,iBAAiB,WAAW;AAAA,IACtC;AAAA,EACF;AAGN,QAAM,UAAU,QACd,qBAAC,SAAI,WAAU,YAAW,eAAa,oBAAoB,WAAW,IACpE;AAAA,wBAAC,UAAK,WAAU,6CAA6C,sBAAW;AAAA,IACvE,aAAa,QACZ,qBAAC,UAAK,WAAU,uCAAsC;AAAA;AAAA,MAAM;AAAA,OAAU;AAAA,IAExE,oBAAC,UAAK,WAAU,mDACd,8BAAC,iBAAc,YAAY,sBAAuB,qBAAU,GAC9D;AAAA,IACC,OAAO,SAAS,KACf,qBAAC,UAAK,WAAU,4CAA2C;AAAA;AAAA,MACvD,OAAO,SAAS;AAAA,MAAE;AAAA,MAAc,OAAO,SAAS,IAAI,MAAM;AAAA,OAC9D;AAAA,KAEJ,IACE;AAEJ,SACE,iCACE;AAAA;AAAA,MAAC;AAAA;AAAA,QACC;AAAA,QACA;AAAA,QACA;AAAA,QACA;AAAA,QACA;AAAA,QACA;AAAA,QAEC;AAAA;AAAA,IACH;AAAA,IACC,QACC;AAAA,MACE;AAAA,QAAC;AAAA;AAAA,UACC,WAAU;AAAA,UACV,OAAO;AAAA,YACL,MAAM,KAAK;AAAA,YACX,OAAO,KAAK;AAAA,YACZ,QAAQ,OAAO,cAAc,KAAK,MAAM;AAAA,UAC1C;AAAA,UAEA;AAAA,YAAC;AAAA;AAAA,cACC,KAAK;AAAA,cACL,MAAK;AAAA,cACL,UAAU;AAAA,cACV,cAAY,YAAY,WAAW;AAAA,cAInC,OAAO,EAAE,WAAW,aAAa,KAAK,IAAI,KAAK,MAAM,IAAI,aAAa,CAAC,CAAC,MAAM;AAAA,cAC9E,WAAU;AAAA,cACV,eAAa,oBAAoB,WAAW;AAAA,cAE5C;AAAA,qCAAC,SAAI,WAAU,6HACb;AAAA,uCAAC,UAAK,WAAU,6DAA4D;AAAA;AAAA,oBAChE;AAAA,oBAAY;AAAA,oBAAG,OAAO;AAAA,oBAAO;AAAA,oBAAS,OAAO,WAAW,IAAI,MAAM;AAAA,oBAAG;AAAA,qBACjF;AAAA,kBACA;AAAA,oBAAC;AAAA;AAAA,sBACC,SAAS;AAAA,sBAKT,WAAU;AAAA,sBACV,cAAW;AAAA,sBACX,eAAa,0BAA0B,WAAW;AAAA,sBAElD;AAAA,wBAAC;AAAA;AAAA,0BACC,OAAM;AAAA,0BACN,QAAO;AAAA,0BACP,SAAQ;AAAA,0BACR,MAAK;AAAA,0BACL,OAAM;AAAA,0BAEN;AAAA,4BAAC;AAAA;AAAA,8BACC,GAAE;AAAA,8BACF,QAAO;AAAA,8BACP,aAAY;AAAA,8BACZ,eAAc;AAAA;AAAA,0BAChB;AAAA;AAAA,sBACF;AAAA;AAAA,kBACF;AAAA,mBACF;AAAA,gBACC,MAAM,IAAI,CAAC,EAAE,OAAO,OAAO,QAAQ,UAAU,MAC5C,qBAAC,SAAgB,WAAU,kDACzB;AAAA,sCAAC,OAAE,WAAU,uDAAsD,OAChE,iBACH;AAAA,kBACC,UAAU,IAAI,CAAC,UAAU;AACxB,0BAAM,aAAa,qBAAqB,MAAM,SAAS;AACvD,2BACE;AAAA,sBAAC;AAAA;AAAA,wBAEC,eAAa,kBAAkB,MAAM,SAAS,YAAY;AAAA,wBAC1D,SAAS,MAAM,aAAa,KAAK;AAAA,wBACjC,WAAW;AAAA,0BACT;AAAA,0BACA,aACI,wDACA;AAAA,wBACN;AAAA,wBAEA,+BAAC,UAAK,WAAU,kBACb;AAAA,gCAAM,SAAS,eAAe,QAC7B,qBAAC,UAAK,WAAU,uCAAsC;AAAA;AAAA,4BAC9C,MAAM,SAAS;AAAA,6BACvB;AAAA,0BAEF,oBAAC,UAAK,WAAU,uBACd,8BAAC,iBAAc,YAAY,sBACxB,gBAAM,QAAQ,QAAQ,QAAQ,GAAG,EAAE,KAAK,GAC3C,GACF;AAAA,2BACF;AAAA;AAAA,sBArBK,MAAM,SAAS;AAAA,oBAsBtB;AAAA,kBAEJ,CAAC;AAAA,qBAhCO,KAiCV,CACD;AAAA;AAAA;AAAA,UACH;AAAA;AAAA,MACF;AAAA,MACA,SAAS;AAAA,IACX;AAAA,KACJ;AAEJ;AAkBA,MAAM,eAA4C,CAAC;AAAA,EACjD;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AACF,MACE;AAAA,EAAC;AAAA;AAAA,IACC;AAAA,IACA;AAAA,IACA,SAAS,cAAc,SAAY;AAAA,IACnC,WAAW,YAAY,WAAW;AAAA,IAClC,QAAQ,iBAAiB,WAAW;AAAA,IACpC,UAAU,cAAc,KAAK;AAAA,IAC7B,kBAAe;AAAA,IACf,WAAW;AAAA,MACT;AAAA;AAAA;AAAA;AAAA;AAAA,MAKA;AAAA,MACA,cAAc,mBAAmB;AAAA,MACjC,WAAW,+BAA+B;AAAA,IAC5C;AAAA,IAEC;AAAA;AAAA,MAID,oBAAC,SAAI,WAAU,4GACZ,uBACH;AAAA;AAAA;AACF;AAGK,MAAM,mBAAmB,MAAM,KAAK,yBAAyB;",
6
+ "names": []
7
+ }
@@ -1,86 +1,17 @@
1
- import { normalizeCitationMarkup, closeOpenEmphasis, trimOpenCitation } from './chunk-VSCU7K4V.js';
2
- import { cn } from './chunk-SN5YV6FF.js';
3
- import { jsx, Fragment, jsxs } from 'react/jsx-runtime';
4
- import React, { createContext, useMemo, useRef, useState, useCallback, useEffect, useReducer } from 'react';
5
- import Markdown from 'react-markdown';
6
- import remarkGfm from 'remark-gfm';
7
- import rehypeRaw from 'rehype-raw';
8
- import rehypeSanitize, { defaultSchema } from 'rehype-sanitize';
9
- import rehypeSlug from 'rehype-slug';
10
- import { Check, Copy } from 'lucide-react';
11
-
12
- var markdownBaseComponents = {
13
- h1: ({ children, ...props }) => /* @__PURE__ */ jsx("h1", { className: "text-lg font-semibold", "data-testid": "markdown-heading-1", ...props, children }),
14
- h2: ({ children, ...props }) => /* @__PURE__ */ jsx("h2", { className: "font-semibold text-base", "data-testid": "markdown-heading-2", ...props, children }),
15
- h3: ({ children, ...props }) => /* @__PURE__ */ jsx("h3", { className: "font-semibold text-base", "data-testid": "markdown-heading-3", ...props, children }),
16
- h4: ({ children, ...props }) => /* @__PURE__ */ jsx("h4", { className: "font-semibold text-base", ...props, children }),
17
- h5: ({ children, ...props }) => /* @__PURE__ */ jsx("h5", { className: "font-medium", ...props, children }),
18
- strong: ({ children, ...props }) => /* @__PURE__ */ jsx("strong", { className: "font-semibold", ...props, children }),
19
- blockquote: ({ children, ...props }) => /* @__PURE__ */ jsx("blockquote", { className: "border-l-2 border-primary pl-4", ...props, children }),
20
- ol: ({ children, ...props }) => /* @__PURE__ */ jsx("ol", { className: "list-decimal space-y-2 pl-6", "data-testid": "markdown-ordered-list", ...props, children }),
21
- ul: ({ children, ...props }) => /* @__PURE__ */ jsx("ul", { className: "list-none space-y-2 pl-6", "data-testid": "markdown-unordered-list", ...props, children }),
22
- li: ({ children, ...props }) => /* @__PURE__ */ jsx("li", { className: "my-1.5", ...props, children }),
23
- table: ({ children, ...props }) => /* @__PURE__ */ jsx("table", { "data-testid": "markdown-table", ...props, children }),
24
- th: ({ children, ...props }) => /* @__PURE__ */ jsx("th", { ...props, children }),
25
- td: ({ children, ...props }) => /* @__PURE__ */ jsx("td", { ...props, children }),
26
- tr: ({ children, ...props }) => /* @__PURE__ */ jsx("tr", { ...props, children }),
27
- p: ({ children, ...props }) => /* @__PURE__ */ jsx("p", { className: "whitespace-pre-wrap", ...props, children }),
28
- hr: (props) => /* @__PURE__ */ jsx("hr", { className: "border-foreground/20", ...props }),
29
- sup: ({ children, ...props }) => /* @__PURE__ */ jsx("sup", { className: "text-xs", ...props, children }),
30
- sub: ({ children, ...props }) => /* @__PURE__ */ jsx("sub", { className: "text-xs", ...props, children }),
31
- div: ({ children, className, ...props }) => /* @__PURE__ */ jsx("div", { className, ...props, children }),
32
- br: (props) => /* @__PURE__ */ jsx("br", { ...props }),
33
- kbd: ({ children, ...props }) => /* @__PURE__ */ jsx(
34
- "kbd",
35
- {
36
- className: "px-1.5 py-0.5 text-xs font-mono bg-muted border border-border rounded",
37
- ...props,
38
- children
39
- }
40
- ),
41
- abbr: ({ children, title, ...props }) => /* @__PURE__ */ jsx("abbr", { title, className: "underline decoration-dotted cursor-help", ...props, children }),
42
- cite: ({ children, ...props }) => /* @__PURE__ */ jsx("cite", { className: "italic", ...props, children })
43
- };
44
- var MarkdownStreamingContext = createContext(false);
45
-
46
- // src/ai/split-markdown-blocks.ts
47
- var LIST_ITEM_RE = /^\s*([-*+]|\d+[.)])\s/;
48
- var BLOCKQUOTE_RE = /^\s*>/;
49
- function splitMarkdownBlocks(content) {
50
- if (!content) return [];
51
- const blocks = [];
52
- let start = 0;
53
- let inFence = false;
54
- let i = 0;
55
- while (i < content.length) {
56
- if (content.startsWith("```", i)) {
57
- inFence = !inFence;
58
- i += 3;
59
- continue;
60
- }
61
- if (!inFence && content[i] === "\n" && content[i + 1] === "\n") {
62
- const before = content.slice(start, i);
63
- const lastLine = before.slice(before.lastIndexOf("\n") + 1);
64
- const afterStart = i + 2;
65
- const nextNewline = content.indexOf("\n", afterStart);
66
- const nextLine = content.slice(afterStart, nextNewline === -1 ? void 0 : nextNewline);
67
- const bothListItems = LIST_ITEM_RE.test(lastLine) && LIST_ITEM_RE.test(nextLine);
68
- const bothBlockquotes = BLOCKQUOTE_RE.test(lastLine) && BLOCKQUOTE_RE.test(nextLine);
69
- if (bothListItems || bothBlockquotes) {
70
- i += 2;
71
- continue;
72
- }
73
- blocks.push(content.slice(start, afterStart));
74
- start = afterStart;
75
- i = afterStart;
76
- continue;
77
- }
78
- i++;
79
- }
80
- if (start < content.length) blocks.push(content.slice(start));
81
- return blocks;
82
- }
83
- var EDGE_FADE = "1.5rem";
1
+ import { Fragment, jsx, jsxs } from "react/jsx-runtime";
2
+ import React, { useCallback, useEffect, useMemo, useReducer, useRef, useState } from "react";
3
+ import Markdown from "react-markdown";
4
+ import remarkGfm from "remark-gfm";
5
+ import rehypeRaw from "rehype-raw";
6
+ import rehypeSanitize, { defaultSchema } from "rehype-sanitize";
7
+ import rehypeSlug from "rehype-slug";
8
+ import { Copy, Check } from "lucide-react";
9
+ import { cn } from "../lib/utils.js";
10
+ import { markdownBaseComponents } from "./markdown-base-components.js";
11
+ import { MarkdownStreamingContext } from "./markdown-streaming-context.js";
12
+ import { splitMarkdownBlocks } from "./split-markdown-blocks.js";
13
+ import { closeOpenEmphasis, normalizeCitationMarkup, trimOpenCitation } from "./normalize-citations.js";
14
+ const EDGE_FADE = "1.5rem";
84
15
  function MarkdownTable({ children, ...props }) {
85
16
  const ref = useRef(null);
86
17
  const [edges, setEdges] = useState({ start: false, end: false });
@@ -204,7 +135,7 @@ function MarkdownCode({
204
135
  }
205
136
  return /* @__PURE__ */ jsx(CodeBlock, { language: match[1], code: String(children).replace(/\n$/, "") });
206
137
  }
207
- var defaultComponents = {
138
+ const defaultComponents = {
208
139
  ...markdownBaseComponents,
209
140
  a: MarkdownLink,
210
141
  em: ({ children, ...props }) => /* @__PURE__ */ jsx("em", { className: "italic", ...props, children }),
@@ -229,7 +160,7 @@ var defaultComponents = {
229
160
  ins: ({ children, ...props }) => /* @__PURE__ */ jsx("ins", { className: "underline decoration-primary/60", ...props, children }),
230
161
  mark: ({ children, ...props }) => /* @__PURE__ */ jsx("mark", { className: "rounded bg-primary/15 px-0.5 text-inherit", ...props, children })
231
162
  };
232
- var markdownSanitizeSchema = {
163
+ const markdownSanitizeSchema = {
233
164
  ...defaultSchema,
234
165
  tagNames: [...defaultSchema.tagNames ?? [], "mark"],
235
166
  attributes: {
@@ -242,16 +173,16 @@ var markdownSanitizeSchema = {
242
173
  del: [...defaultSchema.attributes?.del ?? [], "dataCid"]
243
174
  }
244
175
  };
245
- var loadedMath = null;
246
- var mathLoadStarted = false;
247
- var mathSubscribers = /* @__PURE__ */ new Set();
176
+ let loadedMath = null;
177
+ let mathLoadStarted = false;
178
+ const mathSubscribers = /* @__PURE__ */ new Set();
248
179
  function loadMath() {
249
180
  if (mathLoadStarted) return;
250
181
  mathLoadStarted = true;
251
182
  void Promise.all([
252
- import('remark-math'),
253
- import('rehype-katex'),
254
- import('katex/dist/katex.min.css')
183
+ import("remark-math"),
184
+ import("rehype-katex"),
185
+ import("katex/dist/katex.min.css")
255
186
  ]).then(([remarkMath, rehypeKatex]) => {
256
187
  loadedMath = { remarkMath: remarkMath.default, rehypeKatex: rehypeKatex.default };
257
188
  mathSubscribers.forEach((notify) => notify());
@@ -259,7 +190,7 @@ function loadMath() {
259
190
  mathLoadStarted = false;
260
191
  });
261
192
  }
262
- var MATH_RE = /\$\$[\s\S]+?\$\$|(?<!\\)\$(?![\s$])(?:\\\$|[^$\n])+?(?<![\s\\])\$/;
193
+ const MATH_RE = /\$\$[\s\S]+?\$\$|(?<!\\)\$(?![\s$])(?:\\\$|[^$\n])+?(?<![\s\\])\$/;
263
194
  function escapeCurrencyDollars(markdown) {
264
195
  return markdown.split(/(```[\s\S]*?```|`[^`\n]*`)/).map((part, i) => i % 2 === 1 ? part : part.replace(/(?<!\\)\$(?=\d)/g, "\\$")).join("");
265
196
  }
@@ -276,7 +207,7 @@ function useMathReady(content) {
276
207
  }, [hasMath]);
277
208
  return hasMath && loadedMath !== null;
278
209
  }
279
- var NO_PLUGINS = [];
210
+ const NO_PLUGINS = [];
280
211
  function usePlugins(allowHtml, mathReady, extra) {
281
212
  return useMemo(() => {
282
213
  const math = mathReady && loadedMath ? loadedMath : null;
@@ -291,7 +222,7 @@ function usePlugins(allowHtml, mathReady, extra) {
291
222
  return { remarkPlugins, rehypePlugins };
292
223
  }, [allowHtml, mathReady, extra]);
293
224
  }
294
- var MemoizedBlock = React.memo(function MarkdownBlock({
225
+ const MemoizedBlock = React.memo(function MarkdownBlock({
295
226
  content,
296
227
  components,
297
228
  remarkPlugins,
@@ -299,7 +230,7 @@ var MemoizedBlock = React.memo(function MarkdownBlock({
299
230
  }) {
300
231
  return /* @__PURE__ */ jsx(Markdown, { remarkPlugins, rehypePlugins, components, children: content });
301
232
  });
302
- var MarkdownErrorBoundary = class extends React.Component {
233
+ class MarkdownErrorBoundary extends React.Component {
303
234
  state = { hasError: false };
304
235
  static getDerivedStateFromError() {
305
236
  return { hasError: true };
@@ -307,7 +238,7 @@ var MarkdownErrorBoundary = class extends React.Component {
307
238
  render() {
308
239
  return this.state.hasError ? this.props.fallback : this.props.children;
309
240
  }
310
- };
241
+ }
311
242
  function MarkdownRendererComponent({
312
243
  children,
313
244
  components: customComponents,
@@ -360,8 +291,11 @@ function MarkdownRendererComponent({
360
291
  }
361
292
  );
362
293
  }
363
- var MarkdownRenderer = React.memo(MarkdownRendererComponent);
364
-
365
- export { MarkdownCode, MarkdownLink, MarkdownRenderer, MarkdownStreamingContext, markdownBaseComponents, markdownSanitizeSchema, splitMarkdownBlocks };
366
- //# sourceMappingURL=chunk-WL2Y2T47.js.map
367
- //# sourceMappingURL=chunk-WL2Y2T47.js.map
294
+ const MarkdownRenderer = React.memo(MarkdownRendererComponent);
295
+ export {
296
+ MarkdownCode,
297
+ MarkdownLink,
298
+ MarkdownRenderer,
299
+ markdownSanitizeSchema
300
+ };
301
+ //# sourceMappingURL=MarkdownRenderer.js.map
@@ -0,0 +1,7 @@
1
+ {
2
+ "version": 3,
3
+ "sources": ["../../src/ai/MarkdownRenderer.tsx"],
4
+ "sourcesContent": ["import React, { useCallback, useEffect, useMemo, useReducer, useRef, useState } from 'react'\nimport Markdown, { type Components, type Options as MarkdownOptions } from 'react-markdown'\nimport remarkGfm from 'remark-gfm'\nimport rehypeRaw from 'rehype-raw'\nimport rehypeSanitize, { defaultSchema, type Options as SanitizeSchema } from 'rehype-sanitize'\nimport rehypeSlug from 'rehype-slug'\nimport { Copy, Check } from 'lucide-react'\nimport { cn } from '../lib/utils'\nimport { markdownBaseComponents } from './markdown-base-components'\nimport { MarkdownStreamingContext } from './markdown-streaming-context'\nimport { splitMarkdownBlocks } from './split-markdown-blocks'\nimport { closeOpenEmphasis, normalizeCitationMarkup, trimOpenCitation } from './normalize-citations'\n\n/** remark/rehype plugin lists, as react-markdown takes them. */\ntype PluggableList = NonNullable<MarkdownOptions['rehypePlugins']>\n\n/**\n * MarkdownRenderer \u2014 the single, full-featured markdown surface for the kit.\n *\n * Renders AI answers, chat/DM messages and parsed-document panes with one house\n * style: headings, paragraphs, bold/italic, ordered/unordered lists, GFM tables,\n * fenced code blocks (monospace + copy button), inline code, blockquotes, safe\n * links (`rel=\"noopener\"`, new tab) and horizontal rules.\n *\n * Styling is 100% semantic Tailwind tokens (`text-foreground`,\n * `text-muted-foreground`, `border-border`, `bg-muted`, `text-primary`) so it\n * themes per firm \u2014 no hardcoded brand colours. It sizes to its container, so it\n * looks right in a compact chat bubble and in a full-width document pane alike.\n *\n * Streaming: the content is split into block-level chunks (see\n * `splitMarkdownBlocks`) and each chunk is memoised, so streaming token updates\n * only re-parse the trailing block instead of the whole message. Pass\n * `isStreaming` to let heavy custom components defer via `MarkdownStreamingContext`.\n *\n * Safety: inline HTML (redlines, `<mark>` highlights, parser tables) is parsed and then sanitised\n * (`markdownSanitizeSchema`), so a model or a document cannot inject scripts, handlers or styles.\n * Headings get slug ids, so `#section` links and bookmarks land.\n *\n * Math: `$\u2026$` and `$$\u2026$$` are typeset with KaTeX. remark-math, rehype-katex and KaTeX's CSS\n * (~90 kB gzip) load only once some content actually contains math. A `$` before a digit is a\n * currency sign, never a formula delimiter.\n *\n * Extending: pass `components` to override any element (the kit's `AiMarkdown`\n * and `CitationRenderer` layer their accent links / citation popovers on top; a host composes\n * `MarkdownLink` / `MarkdownCode` into its own overrides), and `rehypePlugins` for trusted\n * transforms that run after sanitising (e.g. turning entity ids into pills).\n */\n\nconst EDGE_FADE = '1.5rem'\n\n/**\n * A GFM table in its own horizontal scroller. The table keeps a minimum width per column\n * (`min-w-[7rem]` cells, words never broken mid-word), so on a narrow screen it scrolls sideways\n * inside this wrapper instead of squeezing cells to a letter per line. The edge(s) with more\n * content to scroll to fade out, which is the scroll hint. Wide containers are unchanged: the\n * table is `w-full` and nothing overflows.\n */\nfunction MarkdownTable({ children, ...props }: React.ComponentPropsWithoutRef<'table'>) {\n const ref = useRef<HTMLDivElement>(null)\n const [edges, setEdges] = useState({ start: false, end: false })\n const measure = useCallback(() => {\n const el = ref.current\n if (!el) return\n const start = el.scrollLeft > 1\n const end = el.scrollLeft + el.clientWidth < el.scrollWidth - 1\n setEdges((prev) => (prev.start === start && prev.end === end ? prev : { start, end }))\n }, [])\n useEffect(() => {\n const el = ref.current\n if (!el) return\n measure()\n if (typeof ResizeObserver === 'undefined') return\n const observer = new ResizeObserver(measure)\n observer.observe(el)\n if (el.firstElementChild) observer.observe(el.firstElementChild)\n return () => observer.disconnect()\n }, [measure])\n const mask =\n edges.start || edges.end\n ? `linear-gradient(to right, ${edges.start ? 'transparent' : '#000'}, #000 ${EDGE_FADE}, #000 calc(100% - ${EDGE_FADE}), ${edges.end ? 'transparent' : '#000'})`\n : undefined\n return (\n <div\n ref={ref}\n onScroll={measure}\n data-testid=\"markdown-table-scroller\"\n data-scroll-start={edges.start || undefined}\n data-scroll-end={edges.end || undefined}\n className=\"my-3 overflow-x-auto rounded-lg border border-border\"\n style={mask ? { maskImage: mask, WebkitMaskImage: mask } : undefined}\n >\n <table\n data-testid=\"markdown-table\"\n className=\"w-full border-collapse text-sm [overflow-wrap:normal] [word-break:normal]\"\n {...props}\n >\n {children}\n </table>\n </div>\n )\n}\n\n/** Fenced code block with a language label and copy-to-clipboard button. */\nfunction CodeBlock({ language, code }: { language: string; code: string }) {\n const [copied, setCopied] = useState(false)\n\n const handleCopy = async () => {\n try {\n await navigator.clipboard.writeText(code)\n setCopied(true)\n setTimeout(() => setCopied(false), 2000)\n } catch {\n // Clipboard unavailable (insecure context / permissions) \u2014 no-op.\n }\n }\n\n return (\n <div\n className=\"code-block relative my-3 overflow-hidden rounded-md border border-current/20 bg-current/5\"\n data-testid=\"markdown-code-block\"\n >\n <div className=\"flex items-center justify-between border-b border-current/20 px-3 py-1.5\">\n <span className=\"font-mono text-xs text-muted-foreground\">{language || 'code'}</span>\n <button\n type=\"button\"\n onClick={handleCopy}\n className=\"flex items-center gap-1 text-xs text-muted-foreground transition-colors hover:text-foreground\"\n title={copied ? 'Copied!' : 'Copy code'}\n >\n {copied ? <Check size={12} /> : <Copy size={12} />}\n <span>{copied ? 'Copied' : 'Copy'}</span>\n </button>\n </div>\n <pre className=\"overflow-x-auto p-3 text-sm leading-relaxed\">\n <code className={cn('font-mono', language && `language-${language}`)}>{code}</code>\n </pre>\n </div>\n )\n}\n\n/**\n * Links. Internal hash/anchor links stay in-page; everything else opens safely in a new tab\n * (`rel=\"noopener noreferrer\"` prevents reverse-tabnabbing). A backend citation marker\n * (`#cite-N`) has no popover here: the cited words stay in the surface's own colour with a quiet\n * superscript number after them (no underline, so a cited sentence does not read as a link).\n * Pass `renderCitation` to `MarkdownRenderer` to swap in a real source popover.\n */\nexport function MarkdownLink({ href, children, ...props }: React.ComponentPropsWithoutRef<'a'>) {\n if (href?.startsWith('#cite-')) {\n return (\n <span\n className=\"cited-text after:ml-px after:align-super after:text-[max(0.8em,var(--text-xs))] after:font-semibold after:text-muted-foreground after:content-[attr(data-cite)]\"\n data-cite={href.slice(6)}\n >\n {children}\n </span>\n )\n }\n const isInternal = !href || href.startsWith('#') || href.startsWith('cite:')\n return (\n <a\n className=\"text-primary underline underline-offset-2\"\n href={href}\n // A `cite:` reference is not a place to go: the click must not navigate.\n onClick={href?.startsWith('cite:') ? (e) => e.preventDefault() : undefined}\n {...(isInternal ? {} : { target: '_blank', rel: 'noopener noreferrer' })}\n {...props}\n >\n {children}\n </a>\n )\n}\n\n/**\n * Inline code, and fenced code as a `CodeBlock` (language label + copy). Exported so a host's own\n * `code` override can handle its special cases (a diagram language, an id shown as a pill) and\n * hand everything else back here.\n */\nexport function MarkdownCode({\n className,\n children,\n ...props\n}: React.ComponentPropsWithoutRef<'code'>) {\n const match = /language-(\\w+)/.exec(className || '')\n if (!match) {\n return (\n <code\n className=\"rounded bg-current/10 px-1 py-0.5 font-mono text-[0.9em]\"\n data-testid=\"markdown-inline-code\"\n {...props}\n >\n {children}\n </code>\n )\n }\n return <CodeBlock language={match[1]} code={String(children).replace(/\\n$/, '')} />\n}\n\n/**\n * Default component overrides. Spreads the shared brand-neutral base\n * (`markdownBaseComponents`: headings, lists, paragraphs, emphasis, hr\u2026) and adds\n * the elements that carry behaviour or need self-contained styling: safe links,\n * code (inline + fenced), bordered tables and blockquotes. Module-scoped so the\n * reference is stable across renders and react-markdown can skip re-parsing.\n */\nconst defaultComponents: Partial<Components> = {\n ...markdownBaseComponents,\n a: MarkdownLink,\n em: ({ children, ...props }: React.ComponentPropsWithoutRef<'em'>) => (\n <em className=\"italic\" {...props}>\n {children}\n </em>\n ),\n code: MarkdownCode,\n // The CodeBlock renders its own <pre>; unwrap react-markdown's wrapper so we\n // don't nest <pre><pre>.\n pre: ({ children }: React.ComponentPropsWithoutRef<'pre'>) => <>{children}</>,\n blockquote: ({ children, ...props }: React.ComponentPropsWithoutRef<'blockquote'>) => (\n <blockquote className=\"border-l-2 border-border pl-4 italic text-muted-foreground\" {...props}>\n {children}\n </blockquote>\n ),\n table: MarkdownTable,\n thead: ({ children, ...props }: React.ComponentPropsWithoutRef<'thead'>) => (\n <thead className=\"bg-current/10\" {...props}>\n {children}\n </thead>\n ),\n th: ({ children, ...props }: React.ComponentPropsWithoutRef<'th'>) => (\n <th\n className=\"min-w-[7rem] border-b border-border px-3 py-2 text-left font-semibold\"\n {...props}\n >\n {children}\n </th>\n ),\n td: ({ children, ...props }: React.ComponentPropsWithoutRef<'td'>) => (\n <td className=\"min-w-[7rem] border-b border-border px-3 py-2 align-top\" {...props}>\n {children}\n </td>\n ),\n // General emphasis marks (GFM `~~strikethrough~~` \u2192 <del>, raw <ins>/<mark>).\n del: ({ children, ...props }: React.ComponentPropsWithoutRef<'del'>) => (\n <del className=\"text-muted-foreground line-through\" {...props}>\n {children}\n </del>\n ),\n ins: ({ children, ...props }: React.ComponentPropsWithoutRef<'ins'>) => (\n <ins className=\"underline decoration-primary/60\" {...props}>\n {children}\n </ins>\n ),\n mark: ({ children, ...props }: React.ComponentPropsWithoutRef<'mark'>) => (\n <mark className=\"rounded bg-primary/15 px-0.5 text-inherit\" {...props}>\n {children}\n </mark>\n ),\n}\n\n/**\n * What survives sanitising inline HTML: GitHub's schema, plus the classes the downstream steps and\n * renderers read (KaTeX's `math-*` placeholders, `language-*` on code), `<mark>` for search\n * highlights, and `data-cid` on `<ins>`/`<del>` (the redline's per-change id, minted from diff\n * positions, never from content). Scripts, event handlers, inline styles and `javascript:` URLs\n * stay out.\n */\nexport const markdownSanitizeSchema: SanitizeSchema = {\n ...defaultSchema,\n tagNames: [...(defaultSchema.tagNames ?? []), 'mark'],\n attributes: {\n ...defaultSchema.attributes,\n span: [...(defaultSchema.attributes?.span ?? []), 'className'],\n div: [...(defaultSchema.attributes?.div ?? []), 'className'],\n code: [...(defaultSchema.attributes?.code ?? []), 'className'],\n pre: [...(defaultSchema.attributes?.pre ?? []), 'className'],\n ins: [...(defaultSchema.attributes?.ins ?? []), 'dataCid'],\n del: [...(defaultSchema.attributes?.del ?? []), 'dataCid'],\n },\n}\n\n// \u2500\u2500 Lazy KaTeX (math) \u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\n// Loaded once, module-wide, the first time content with math renders; mounted renderers that\n// were waiting re-render when it lands.\ntype MathPlugins = { remarkMath: PluggableList[number]; rehypeKatex: PluggableList[number] }\nlet loadedMath: MathPlugins | null = null\nlet mathLoadStarted = false\nconst mathSubscribers = new Set<() => void>()\n\nfunction loadMath() {\n if (mathLoadStarted) return\n mathLoadStarted = true\n void Promise.all([\n import('remark-math'),\n import('rehype-katex'),\n import('katex/dist/katex.min.css'),\n ])\n .then(([remarkMath, rehypeKatex]) => {\n loadedMath = { remarkMath: remarkMath.default, rehypeKatex: rehypeKatex.default }\n mathSubscribers.forEach((notify) => notify())\n })\n .catch(() => {\n // Retry on the next math-bearing render if the chunk failed to load.\n mathLoadStarted = false\n })\n}\n\n// remark-math's inline rule: `$\u2026$` with no whitespace just inside, or a `$$\u2026$$` block. A lone\n// price (\"$5,000\") never matches.\nconst MATH_RE = /\\$\\$[\\s\\S]+?\\$\\$|(?<!\\\\)\\$(?![\\s$])(?:\\\\\\$|[^$\\n])+?(?<![\\s\\\\])\\$/\n\n/**\n * A `$` straight before a digit is a currency sign (\"$2,000\", \"\u2248$50,000\"), not the start of inline\n * math: two in one paragraph would otherwise pair up and typeset everything between as a formula.\n * Escape them (outside code, where a backslash would show) so they stay text.\n */\nfunction escapeCurrencyDollars(markdown: string): string {\n return markdown\n .split(/(```[\\s\\S]*?```|`[^`\\n]*`)/)\n .map((part, i) => (i % 2 === 1 ? part : part.replace(/(?<!\\\\)\\$(?=\\d)/g, '\\\\$')))\n .join('')\n}\n\n/** True once the math plugins are loaded for content that contains math. */\nfunction useMathReady(content: string): boolean {\n const hasMath = useMemo(() => MATH_RE.test(content), [content])\n const [, rerender] = useReducer((n: number) => n + 1, 0)\n useEffect(() => {\n if (!hasMath || loadedMath) return\n mathSubscribers.add(rerender)\n loadMath()\n return () => {\n mathSubscribers.delete(rerender)\n }\n }, [hasMath])\n return hasMath && loadedMath !== null\n}\n\nconst NO_PLUGINS: PluggableList = []\n\n/**\n * The remark/rehype pipelines. Raw HTML (when allowed) is parsed and sanitised before the trusted\n * steps (KaTeX, slugs, the host's plugins), so their output is not stripped again. Memoised on\n * its inputs so react-markdown sees stable arrays and memoised blocks do not re-parse.\n */\nfunction usePlugins(allowHtml: boolean, mathReady: boolean, extra: PluggableList) {\n return useMemo(() => {\n const math = mathReady && loadedMath ? loadedMath : null\n const remarkPlugins: PluggableList = math ? [remarkGfm, math.remarkMath] : [remarkGfm]\n const rehypePlugins: PluggableList = [\n // Text someone else wrote (a Word comment from any .docx): raw HTML stays text.\n ...(allowHtml ? [rehypeRaw, [rehypeSanitize, markdownSanitizeSchema]] : []),\n ...(math ? [math.rehypeKatex] : []),\n rehypeSlug,\n ...extra,\n ] as PluggableList\n return { remarkPlugins, rehypePlugins }\n }, [allowHtml, mathReady, extra])\n}\n\n/**\n * One parsed markdown block, memoised on (content, components) so already-rendered\n * blocks don't re-parse when a later block streams new tokens. This is the core\n * of the streaming-rendering optimisation.\n */\nconst MemoizedBlock = React.memo(function MarkdownBlock({\n content,\n components,\n remarkPlugins,\n rehypePlugins,\n}: {\n content: string\n components: Partial<Components>\n remarkPlugins: PluggableList\n rehypePlugins: PluggableList\n}) {\n return (\n <Markdown remarkPlugins={remarkPlugins} rehypePlugins={rehypePlugins} components={components}>\n {content}\n </Markdown>\n )\n})\n\n/** Prevents a malformed-markdown render error from crashing the whole surface. */\nclass MarkdownErrorBoundary extends React.Component<\n { fallback: React.ReactNode; children: React.ReactNode },\n { hasError: boolean }\n> {\n state = { hasError: false }\n static getDerivedStateFromError() {\n return { hasError: true }\n }\n render() {\n return this.state.hasError ? this.props.fallback : this.props.children\n }\n}\n\nexport interface MarkdownRendererProps {\n /** Markdown content to render. */\n children: string\n /** Custom component overrides merged on top of the defaults. */\n components?: Partial<Components>\n /**\n * When true, signals heavy custom components (via `MarkdownStreamingContext`)\n * to defer their work while tokens are still arriving. Defaults to false.\n */\n isStreaming?: boolean\n /**\n * Renders a citation marker `[words](#cite-N)`: `children` are the cited words, `num` the N.\n * Keep it referentially stable (`useCallback`/`useMemo`), or every block re-parses.\n */\n renderCitation?: (citation: { num: string; children: React.ReactNode }) => React.ReactNode\n /** Extra classes on the wrapper (font-size, prose width, etc.). */\n className?: string\n /** Overrides the `data-testid` on the wrapper (default `markdown-renderer`). */\n testId?: string\n /**\n * Inline HTML in the markdown becomes elements, sanitised (default). False keeps it as text: for\n * content from outside the app, such as a comment in a Word file anyone could have written.\n */\n allowHtml?: boolean\n /**\n * Trusted rehype plugins run after sanitising, KaTeX and heading slugs (e.g. a pass that turns\n * entity ids into elements the host's `components` render). Keep the array referentially\n * stable (module scope), or every block re-parses.\n */\n rehypePlugins?: PluggableList\n}\n\nfunction MarkdownRendererComponent({\n children,\n components: customComponents,\n renderCitation,\n isStreaming = false,\n className,\n testId = 'markdown-renderer',\n allowHtml = true,\n rehypePlugins: extraRehypePlugins = NO_PLUGINS,\n}: MarkdownRendererProps) {\n const components = useMemo(() => {\n const base = customComponents\n ? { ...defaultComponents, ...customComponents }\n : defaultComponents\n if (!renderCitation) return base\n const Link = base.a ?? MarkdownLink\n return {\n ...base,\n a: (props: React.ComponentPropsWithoutRef<'a'>) =>\n props.href?.startsWith('#cite-')\n ? renderCitation({ num: props.href.slice(6), children: props.children })\n : React.createElement(Link as React.ElementType, props),\n }\n }, [customComponents, renderCitation])\n\n const text = useMemo(() => {\n const escaped = escapeCurrencyDollars(children)\n return normalizeCitationMarkup(\n isStreaming ? closeOpenEmphasis(trimOpenCitation(escaped)) : escaped\n )\n }, [children, isStreaming])\n const blocks = useMemo(() => splitMarkdownBlocks(text), [text])\n const mathReady = useMathReady(text)\n const { remarkPlugins, rehypePlugins } = usePlugins(allowHtml, mathReady, extraRehypePlugins)\n\n return (\n <MarkdownErrorBoundary\n fallback={<div className={cn('whitespace-pre-wrap break-words', className)}>{children}</div>}\n >\n <MarkdownStreamingContext.Provider value={isStreaming}>\n <div\n className={cn('markdown-content space-y-3 break-words leading-relaxed', className)}\n data-testid={testId}\n >\n {blocks.map((block, index) => (\n <MemoizedBlock\n key={index}\n content={block}\n components={components}\n remarkPlugins={remarkPlugins}\n rehypePlugins={rehypePlugins}\n />\n ))}\n </div>\n </MarkdownStreamingContext.Provider>\n </MarkdownErrorBoundary>\n )\n}\n\n/**\n * Memoised so a stable message in a long thread doesn't re-parse when unrelated\n * tokens arrive elsewhere; a streaming message gets a fresh `children` each flush\n * and re-renders (only its trailing block re-parses, thanks to `MemoizedBlock`).\n */\nexport const MarkdownRenderer = React.memo(MarkdownRendererComponent)\n"],
5
+ "mappings": "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",
6
+ "names": []
7
+ }
@@ -0,0 +1,75 @@
1
+ import { jsx, jsxs } from "react/jsx-runtime";
2
+ import { AppWindow, FileText, Image as ImageIcon } from "lucide-react";
3
+ import { Card } from "../ui/card.js";
4
+ const LABELS = {
5
+ document: {
6
+ Icon: FileText,
7
+ busy: "Drafting\u2026",
8
+ ready: "Draft ready",
9
+ action: "Open in Editor",
10
+ untitled: "Untitled draft"
11
+ },
12
+ live: {
13
+ Icon: AppWindow,
14
+ busy: "Building\u2026",
15
+ ready: "Preview ready",
16
+ action: "Open preview",
17
+ untitled: "Untitled app"
18
+ },
19
+ image: {
20
+ Icon: ImageIcon,
21
+ busy: "Generating\u2026",
22
+ ready: "Image ready",
23
+ action: "View image",
24
+ untitled: "Generated image"
25
+ }
26
+ };
27
+ function labelsFor(mode) {
28
+ if (mode === "image") return LABELS.image;
29
+ if (mode === "html" || mode === "react") return LABELS.live;
30
+ return LABELS.document;
31
+ }
32
+ function MessageArtifactCard({
33
+ artifact,
34
+ onOpen
35
+ }) {
36
+ const { docExtId, title, isComplete, mode } = artifact;
37
+ const labels = labelsFor(mode);
38
+ const Icon = labels.Icon;
39
+ return /* @__PURE__ */ jsxs(
40
+ Card,
41
+ {
42
+ variant: "outline",
43
+ className: "mt-3 flex items-center gap-3 px-3 py-2.5",
44
+ "data-testid": `message-artifact-card-${docExtId}`,
45
+ children: [
46
+ /* @__PURE__ */ jsx(Icon, { className: "h-4 w-4 shrink-0 text-muted-foreground", "aria-hidden": true }),
47
+ /* @__PURE__ */ jsxs("div", { className: "min-w-0 flex-1", children: [
48
+ /* @__PURE__ */ jsx(
49
+ "div",
50
+ {
51
+ className: "truncate text-chat font-semibold text-foreground",
52
+ "data-testid": "artifact-title",
53
+ children: title || labels.untitled
54
+ }
55
+ ),
56
+ /* @__PURE__ */ jsx("div", { className: "text-sm text-muted-foreground", "data-testid": "artifact-status", children: isComplete ? labels.ready : labels.busy })
57
+ ] }),
58
+ /* @__PURE__ */ jsx(
59
+ "button",
60
+ {
61
+ type: "button",
62
+ onClick: () => onOpen(docExtId),
63
+ className: "shrink-0 rounded-md bg-secondary/15 px-3 py-1.5 text-sm font-semibold text-secondary transition-colors hover:bg-secondary/25",
64
+ "data-testid": `view-artifact-button-${docExtId}`,
65
+ children: labels.action
66
+ }
67
+ )
68
+ ]
69
+ }
70
+ );
71
+ }
72
+ export {
73
+ MessageArtifactCard
74
+ };
75
+ //# sourceMappingURL=MessageArtifactCard.js.map
@@ -0,0 +1,7 @@
1
+ {
2
+ "version": 3,
3
+ "sources": ["../../src/ai/MessageArtifactCard.tsx"],
4
+ "sourcesContent": ["import React from 'react'\nimport { AppWindow, FileText, Image as ImageIcon } from 'lucide-react'\nimport { Card } from '../ui/card'\n\n/**\n * The minimal artifact shape this card renders. A structural subset of the\n * ARBI app's `StreamingDocument`, defined here so the light package doesn't\n * depend on the app store \u2014 any object carrying these fields is accepted.\n */\nexport interface MessageArtifact {\n /** External id of the drafted document; opened in the docked viewer. */\n docExtId: string\n /** Display title; falls back when empty. */\n title: string\n /** Whether generation has finished. */\n isComplete: boolean\n /**\n * Content mode. `markdown` / `text` are document drafts, which the server stores as Word\n * documents (.docx); `html` / `react` are live UI artifacts; `image` is a generated image.\n */\n mode: 'markdown' | 'html' | 'text' | 'react' | 'image'\n}\n\nconst LABELS = {\n document: {\n Icon: FileText,\n busy: 'Drafting\u2026',\n ready: 'Draft ready',\n action: 'Open in Editor',\n untitled: 'Untitled draft',\n },\n live: {\n Icon: AppWindow,\n busy: 'Building\u2026',\n ready: 'Preview ready',\n action: 'Open preview',\n untitled: 'Untitled app',\n },\n image: {\n Icon: ImageIcon,\n busy: 'Generating\u2026',\n ready: 'Image ready',\n action: 'View image',\n untitled: 'Generated image',\n },\n} as const\n\nfunction labelsFor(mode: MessageArtifact['mode']) {\n if (mode === 'image') return LABELS.image\n if (mode === 'html' || mode === 'react') return LABELS.live\n return LABELS.document\n}\n\ninterface MessageArtifactCardProps {\n /** The streaming/drafted document linked to this assistant message. */\n artifact: MessageArtifact\n /** Opens the drafted document (docExtId) in the docked viewer. */\n onOpen: (docExtId: string) => void\n}\n\n/**\n * Inline \"Open in Editor\" (document drafts) / \"Open preview\" / \"View image\" affordance shown inside the assistant message that\n * produced a drafted document \u2014 so the artifact lives in the conversation\n * narrative (dyad-style) instead of only a hidden docked panel.\n *\n * Clean-ARBI contract: flat outline card, one chat type size, brand\n * accent on the action, tap-friendly (a real button \u2014 no hover-only).\n */\nexport function MessageArtifactCard({\n artifact,\n onOpen,\n}: MessageArtifactCardProps): React.JSX.Element {\n const { docExtId, title, isComplete, mode } = artifact\n const labels = labelsFor(mode)\n const Icon = labels.Icon\n return (\n <Card\n variant=\"outline\"\n className=\"mt-3 flex items-center gap-3 px-3 py-2.5\"\n data-testid={`message-artifact-card-${docExtId}`}\n >\n <Icon className=\"h-4 w-4 shrink-0 text-muted-foreground\" aria-hidden />\n <div className=\"min-w-0 flex-1\">\n <div\n className=\"truncate text-chat font-semibold text-foreground\"\n data-testid=\"artifact-title\"\n >\n {title || labels.untitled}\n </div>\n <div className=\"text-sm text-muted-foreground\" data-testid=\"artifact-status\">\n {isComplete ? labels.ready : labels.busy}\n </div>\n </div>\n <button\n type=\"button\"\n onClick={() => onOpen(docExtId)}\n className=\"shrink-0 rounded-md bg-secondary/15 px-3 py-1.5 text-sm font-semibold text-secondary transition-colors hover:bg-secondary/25\"\n data-testid={`view-artifact-button-${docExtId}`}\n >\n {labels.action}\n </button>\n </Card>\n )\n}\n"],
5
+ "mappings": "AAiFM,cACA,YADA;AAhFN,SAAS,WAAW,UAAU,SAAS,iBAAiB;AACxD,SAAS,YAAY;AAqBrB,MAAM,SAAS;AAAA,EACb,UAAU;AAAA,IACR,MAAM;AAAA,IACN,MAAM;AAAA,IACN,OAAO;AAAA,IACP,QAAQ;AAAA,IACR,UAAU;AAAA,EACZ;AAAA,EACA,MAAM;AAAA,IACJ,MAAM;AAAA,IACN,MAAM;AAAA,IACN,OAAO;AAAA,IACP,QAAQ;AAAA,IACR,UAAU;AAAA,EACZ;AAAA,EACA,OAAO;AAAA,IACL,MAAM;AAAA,IACN,MAAM;AAAA,IACN,OAAO;AAAA,IACP,QAAQ;AAAA,IACR,UAAU;AAAA,EACZ;AACF;AAEA,SAAS,UAAU,MAA+B;AAChD,MAAI,SAAS,QAAS,QAAO,OAAO;AACpC,MAAI,SAAS,UAAU,SAAS,QAAS,QAAO,OAAO;AACvD,SAAO,OAAO;AAChB;AAiBO,SAAS,oBAAoB;AAAA,EAClC;AAAA,EACA;AACF,GAAgD;AAC9C,QAAM,EAAE,UAAU,OAAO,YAAY,KAAK,IAAI;AAC9C,QAAM,SAAS,UAAU,IAAI;AAC7B,QAAM,OAAO,OAAO;AACpB,SACE;AAAA,IAAC;AAAA;AAAA,MACC,SAAQ;AAAA,MACR,WAAU;AAAA,MACV,eAAa,yBAAyB,QAAQ;AAAA,MAE9C;AAAA,4BAAC,QAAK,WAAU,0CAAyC,eAAW,MAAC;AAAA,QACrE,qBAAC,SAAI,WAAU,kBACb;AAAA;AAAA,YAAC;AAAA;AAAA,cACC,WAAU;AAAA,cACV,eAAY;AAAA,cAEX,mBAAS,OAAO;AAAA;AAAA,UACnB;AAAA,UACA,oBAAC,SAAI,WAAU,iCAAgC,eAAY,mBACxD,uBAAa,OAAO,QAAQ,OAAO,MACtC;AAAA,WACF;AAAA,QACA;AAAA,UAAC;AAAA;AAAA,YACC,MAAK;AAAA,YACL,SAAS,MAAM,OAAO,QAAQ;AAAA,YAC9B,WAAU;AAAA,YACV,eAAa,wBAAwB,QAAQ;AAAA,YAE5C,iBAAO;AAAA;AAAA,QACV;AAAA;AAAA;AAAA,EACF;AAEJ;",
6
+ "names": []
7
+ }
@@ -0,0 +1,79 @@
1
+ import { Fragment, jsx, jsxs } from "react/jsx-runtime";
2
+ import { cn } from "../lib/utils.js";
3
+ const TIERS = [
4
+ { min: 0.7, tone: "bg-emerald-500", label: "High relevance" },
5
+ { min: 0.4, tone: "bg-amber-500", label: "Medium relevance" },
6
+ { min: -Infinity, tone: "bg-muted-foreground/40", label: "Low relevance" }
7
+ ];
8
+ function RelevanceDot({ score }) {
9
+ if (score == null) return null;
10
+ const tier = TIERS.find((t) => score >= t.min) ?? TIERS[TIERS.length - 1];
11
+ return /* @__PURE__ */ jsx(
12
+ "span",
13
+ {
14
+ role: "img",
15
+ "aria-label": tier.label,
16
+ title: `${tier.label} (${score.toFixed(2)})`,
17
+ className: cn("size-1.5 shrink-0 rounded-full", tier.tone),
18
+ "data-testid": "passage-relevance"
19
+ }
20
+ );
21
+ }
22
+ function PassageCard({
23
+ header,
24
+ score,
25
+ headerRight,
26
+ active,
27
+ onClick,
28
+ footer,
29
+ className,
30
+ children,
31
+ "data-testid": testId
32
+ }) {
33
+ const body = /* @__PURE__ */ jsxs(Fragment, { children: [
34
+ /* @__PURE__ */ jsxs("div", { className: "mb-1.5 flex items-center gap-2", children: [
35
+ header,
36
+ (score != null || headerRight) && /* @__PURE__ */ jsxs("div", { className: "ml-auto flex shrink-0 items-center gap-2", children: [
37
+ /* @__PURE__ */ jsx(RelevanceDot, { score }),
38
+ headerRight
39
+ ] })
40
+ ] }),
41
+ /* @__PURE__ */ jsx("div", { className: "[&_mark]:rounded-sm [&_mark]:bg-ai-accent/20 [&_mark]:px-0.5 [&_mark]:font-medium [&_mark]:text-foreground", children })
42
+ ] });
43
+ return /* @__PURE__ */ jsxs(
44
+ "div",
45
+ {
46
+ className: cn(
47
+ "group rounded-lg border border-border bg-card p-3 text-left transition-colors",
48
+ onClick && "hover:border-ai-accent/40 focus-within:ring-2 focus-within:ring-ai-accent/40",
49
+ active && "border-ai-accent/60 ring-1 ring-ai-accent/30",
50
+ className
51
+ ),
52
+ children: [
53
+ onClick ? /* @__PURE__ */ jsx(
54
+ "div",
55
+ {
56
+ role: "button",
57
+ tabIndex: 0,
58
+ onClick,
59
+ onKeyDown: (e) => {
60
+ if (e.key === "Enter" || e.key === " ") {
61
+ e.preventDefault();
62
+ onClick(e);
63
+ }
64
+ },
65
+ "aria-current": active || void 0,
66
+ "data-testid": testId,
67
+ className: "cursor-pointer focus:outline-none",
68
+ children: body
69
+ }
70
+ ) : /* @__PURE__ */ jsx("div", { "aria-current": active || void 0, "data-testid": testId, children: body }),
71
+ footer
72
+ ]
73
+ }
74
+ );
75
+ }
76
+ export {
77
+ PassageCard
78
+ };
79
+ //# sourceMappingURL=PassageCard.js.map
@@ -0,0 +1,7 @@
1
+ {
2
+ "version": 3,
3
+ "sources": ["../../src/ai/PassageCard.tsx"],
4
+ "sourcesContent": ["/**\n * PassageCard \u2014 the card (\"bubble\") a single retrieved passage is rendered as.\n *\n * One presentation shared by every surface that lists retrieval hits: the\n * blocks search page (`SearchHit`) and the conversation search. Those had drifted into two different looks for the same object; this\n * is the single one.\n *\n * The card owns the chrome only \u2014 the rounded border, the AI-accent hover /\n * focus / selected states, the header row and the relevance dot. What goes in\n * the header and how the snippet itself is rendered stays with the caller,\n * because those genuinely differ: the block shows a plain-text excerpt in a\n * narrow sidebar, the monolith renders markdown with a show-more toggle.\n *\n * Theming is semantic tokens only (shadcn + the AI-accent contract).\n */\n\nimport React from 'react'\nimport { cn } from '../lib/utils'\n\n/** Relevance bands. Shared so a hit is coloured the same wherever it appears. */\nconst TIERS = [\n { min: 0.7, tone: 'bg-emerald-500', label: 'High relevance' },\n { min: 0.4, tone: 'bg-amber-500', label: 'Medium relevance' },\n { min: -Infinity, tone: 'bg-muted-foreground/40', label: 'Low relevance' },\n] as const\n\n/**\n * A dot conveying relevance \u2014 green (high) / amber (mid) / muted (low).\n *\n * The band is shown, the raw number is not: scores are not on a normalized 0-1\n * scale across search modes (BM25 keyword scores can exceed 1), so a printed\n * figure invites a comparison it cannot support. The value is kept in the\n * tooltip for anyone debugging a ranking.\n */\nfunction RelevanceDot({ score }: { score?: number | null }) {\n if (score == null) return null\n const tier = TIERS.find((t) => score >= t.min) ?? TIERS[TIERS.length - 1]\n return (\n <span\n role=\"img\"\n aria-label={tier.label}\n title={`${tier.label} (${score.toFixed(2)})`}\n className={cn('size-1.5 shrink-0 rounded-full', tier.tone)}\n data-testid=\"passage-relevance\"\n />\n )\n}\n\nexport interface PassageCardProps {\n /** Left of the header row \u2014 the source affordance (document pill, page label). */\n header: React.ReactNode\n /** Relevance score for the dot. Omit to hide it. */\n score?: number | null\n /** Extra affordance pinned right of the dot (e.g. a hover-revealed open icon). */\n headerRight?: React.ReactNode\n /** Marks the card as the currently open passage. */\n active?: boolean\n onClick?: (e: React.MouseEvent) => void\n /** Rendered under the snippet, outside the click target's typography. */\n footer?: React.ReactNode\n className?: string\n children: React.ReactNode\n 'data-testid'?: string\n}\n\nexport function PassageCard({\n header,\n score,\n headerRight,\n active,\n onClick,\n footer,\n className,\n children,\n 'data-testid': testId,\n}: PassageCardProps) {\n const body = (\n <>\n <div className=\"mb-1.5 flex items-center gap-2\">\n {header}\n {(score != null || headerRight) && (\n <div className=\"ml-auto flex shrink-0 items-center gap-2\">\n <RelevanceDot score={score} />\n {headerRight}\n </div>\n )}\n </div>\n {/* Query-term highlights are styled here rather than by each caller, so a\n * <mark> reads as an accent on the passage instead of browser yellow. */}\n <div className=\"[&_mark]:rounded-sm [&_mark]:bg-ai-accent/20 [&_mark]:px-0.5 [&_mark]:font-medium [&_mark]:text-foreground\">\n {children}\n </div>\n </>\n )\n\n return (\n <div\n className={cn(\n 'group rounded-lg border border-border bg-card p-3 text-left transition-colors',\n onClick && 'hover:border-ai-accent/40 focus-within:ring-2 focus-within:ring-ai-accent/40',\n active && 'border-ai-accent/60 ring-1 ring-ai-accent/30',\n className\n )}\n >\n {/* The footer sits OUTSIDE the click target on purpose. It holds the\n * caller's own controls (a show-more toggle), and a button nested inside a\n * role=\"button\" is both invalid and ambiguous to hit \u2014 the whole passage\n * would otherwise become that control's accessible name.\n *\n * `data-testid` rides on the click target rather than this shell, so\n * \"click the result row\" keeps working for every caller's tests. */}\n {onClick ? (\n <div\n role=\"button\"\n tabIndex={0}\n onClick={onClick}\n onKeyDown={(e) => {\n if (e.key === 'Enter' || e.key === ' ') {\n e.preventDefault()\n onClick(e as unknown as React.MouseEvent)\n }\n }}\n aria-current={active || undefined}\n data-testid={testId}\n className=\"cursor-pointer focus:outline-none\"\n >\n {body}\n </div>\n ) : (\n <div aria-current={active || undefined} data-testid={testId}>\n {body}\n </div>\n )}\n {footer}\n </div>\n )\n}\n"],
5
+ "mappings": "AAsCI,SAuCA,UAvCA,KA2CM,YA3CN;AArBJ,SAAS,UAAU;AAGnB,MAAM,QAAQ;AAAA,EACZ,EAAE,KAAK,KAAK,MAAM,kBAAkB,OAAO,iBAAiB;AAAA,EAC5D,EAAE,KAAK,KAAK,MAAM,gBAAgB,OAAO,mBAAmB;AAAA,EAC5D,EAAE,KAAK,WAAW,MAAM,0BAA0B,OAAO,gBAAgB;AAC3E;AAUA,SAAS,aAAa,EAAE,MAAM,GAA8B;AAC1D,MAAI,SAAS,KAAM,QAAO;AAC1B,QAAM,OAAO,MAAM,KAAK,CAAC,MAAM,SAAS,EAAE,GAAG,KAAK,MAAM,MAAM,SAAS,CAAC;AACxE,SACE;AAAA,IAAC;AAAA;AAAA,MACC,MAAK;AAAA,MACL,cAAY,KAAK;AAAA,MACjB,OAAO,GAAG,KAAK,KAAK,KAAK,MAAM,QAAQ,CAAC,CAAC;AAAA,MACzC,WAAW,GAAG,kCAAkC,KAAK,IAAI;AAAA,MACzD,eAAY;AAAA;AAAA,EACd;AAEJ;AAmBO,SAAS,YAAY;AAAA,EAC1B;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA,eAAe;AACjB,GAAqB;AACnB,QAAM,OACJ,iCACE;AAAA,yBAAC,SAAI,WAAU,kCACZ;AAAA;AAAA,OACC,SAAS,QAAQ,gBACjB,qBAAC,SAAI,WAAU,4CACb;AAAA,4BAAC,gBAAa,OAAc;AAAA,QAC3B;AAAA,SACH;AAAA,OAEJ;AAAA,IAGA,oBAAC,SAAI,WAAU,8GACZ,UACH;AAAA,KACF;AAGF,SACE;AAAA,IAAC;AAAA;AAAA,MACC,WAAW;AAAA,QACT;AAAA,QACA,WAAW;AAAA,QACX,UAAU;AAAA,QACV;AAAA,MACF;AAAA,MASC;AAAA,kBACC;AAAA,UAAC;AAAA;AAAA,YACC,MAAK;AAAA,YACL,UAAU;AAAA,YACV;AAAA,YACA,WAAW,CAAC,MAAM;AAChB,kBAAI,EAAE,QAAQ,WAAW,EAAE,QAAQ,KAAK;AACtC,kBAAE,eAAe;AACjB,wBAAQ,CAAgC;AAAA,cAC1C;AAAA,YACF;AAAA,YACA,gBAAc,UAAU;AAAA,YACxB,eAAa;AAAA,YACb,WAAU;AAAA,YAET;AAAA;AAAA,QACH,IAEA,oBAAC,SAAI,gBAAc,UAAU,QAAW,eAAa,QAClD,gBACH;AAAA,QAED;AAAA;AAAA;AAAA,EACH;AAEJ;",
6
+ "names": []
7
+ }