@athenaintel/react 0.43.0 → 0.48.0

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 (661) hide show
  1. package/README.md +215 -3
  2. package/dist/agent-runtime/src/answer-label.cjs +137 -0
  3. package/dist/agent-runtime/src/answer-label.cjs.map +1 -0
  4. package/dist/agent-runtime/src/answer-label.d.ts +104 -0
  5. package/dist/agent-runtime/src/answer-label.js +137 -0
  6. package/dist/agent-runtime/src/answer-label.js.map +1 -0
  7. package/dist/agent-runtime/src/answer-rows.cjs +180 -0
  8. package/dist/agent-runtime/src/answer-rows.cjs.map +1 -0
  9. package/dist/agent-runtime/src/answer-rows.d.ts +86 -0
  10. package/dist/agent-runtime/src/answer-rows.js +180 -0
  11. package/dist/agent-runtime/src/answer-rows.js.map +1 -0
  12. package/dist/agent-runtime/src/client-tool-bridge.cjs +15 -15
  13. package/dist/agent-runtime/src/client-tool-bridge.cjs.map +1 -1
  14. package/dist/agent-runtime/src/conversation-index.cjs +8 -8
  15. package/dist/agent-runtime/src/conversation-index.cjs.map +1 -1
  16. package/dist/agent-runtime/src/decision-checks.cjs +207 -0
  17. package/dist/agent-runtime/src/decision-checks.cjs.map +1 -0
  18. package/dist/agent-runtime/src/decision-checks.d.ts +142 -0
  19. package/dist/agent-runtime/src/decision-checks.js +207 -0
  20. package/dist/agent-runtime/src/decision-checks.js.map +1 -0
  21. package/dist/agent-runtime/src/desktop-handoff.d.ts +12 -0
  22. package/dist/agent-runtime/src/errors.cjs +18 -0
  23. package/dist/agent-runtime/src/errors.cjs.map +1 -1
  24. package/dist/agent-runtime/src/errors.d.ts +7 -0
  25. package/dist/agent-runtime/src/errors.js +18 -0
  26. package/dist/agent-runtime/src/errors.js.map +1 -1
  27. package/dist/agent-runtime/src/generated/runconfig-contract.cjs +12 -0
  28. package/dist/agent-runtime/src/generated/runconfig-contract.cjs.map +1 -1
  29. package/dist/agent-runtime/src/generated/runconfig-contract.d.ts +6 -6
  30. package/dist/agent-runtime/src/generated/runconfig-contract.js +12 -0
  31. package/dist/agent-runtime/src/generated/runconfig-contract.js.map +1 -1
  32. package/dist/agent-runtime/src/handoff-arrival.cjs +60 -0
  33. package/dist/agent-runtime/src/handoff-arrival.cjs.map +1 -0
  34. package/dist/agent-runtime/src/handoff-arrival.d.ts +46 -0
  35. package/dist/agent-runtime/src/handoff-arrival.js +60 -0
  36. package/dist/agent-runtime/src/handoff-arrival.js.map +1 -0
  37. package/dist/agent-runtime/src/index.d.ts +14 -8
  38. package/dist/agent-runtime/src/interrupts.cjs +43 -18
  39. package/dist/agent-runtime/src/interrupts.cjs.map +1 -1
  40. package/dist/agent-runtime/src/interrupts.d.ts +19 -2
  41. package/dist/agent-runtime/src/interrupts.js +28 -3
  42. package/dist/agent-runtime/src/interrupts.js.map +1 -1
  43. package/dist/agent-runtime/src/lane-history.cjs +8 -8
  44. package/dist/agent-runtime/src/lane-history.cjs.map +1 -1
  45. package/dist/agent-runtime/src/messages.cjs +43 -8
  46. package/dist/agent-runtime/src/messages.cjs.map +1 -1
  47. package/dist/agent-runtime/src/messages.d.ts +25 -3
  48. package/dist/agent-runtime/src/messages.js +43 -8
  49. package/dist/agent-runtime/src/messages.js.map +1 -1
  50. package/dist/agent-runtime/src/offline-status.cjs +36 -0
  51. package/dist/agent-runtime/src/offline-status.cjs.map +1 -0
  52. package/dist/agent-runtime/src/offline-status.d.ts +118 -3
  53. package/dist/agent-runtime/src/offline-status.js +36 -0
  54. package/dist/agent-runtime/src/offline-status.js.map +1 -0
  55. package/dist/agent-runtime/src/queue.cjs +0 -9
  56. package/dist/agent-runtime/src/queue.cjs.map +1 -1
  57. package/dist/agent-runtime/src/queue.js +0 -9
  58. package/dist/agent-runtime/src/queue.js.map +1 -1
  59. package/dist/agent-runtime/src/quota-safe-local-storage-session.cjs +9 -9
  60. package/dist/agent-runtime/src/quota-safe-local-storage-session.cjs.map +1 -1
  61. package/dist/agent-runtime/src/runtime-catalog.cjs +42 -0
  62. package/dist/agent-runtime/src/runtime-catalog.cjs.map +1 -0
  63. package/dist/agent-runtime/src/runtime-catalog.d.ts +35 -0
  64. package/dist/agent-runtime/src/runtime-catalog.js +42 -0
  65. package/dist/agent-runtime/src/runtime-catalog.js.map +1 -0
  66. package/dist/agent-runtime/src/runtime-messages.cjs.map +1 -1
  67. package/dist/agent-runtime/src/runtime-messages.d.ts +1 -1
  68. package/dist/agent-runtime/src/runtime-messages.js.map +1 -1
  69. package/dist/agent-runtime/src/runtime.d.ts +40 -0
  70. package/dist/agent-runtime/src/statewire-suspended.cjs +3 -3
  71. package/dist/agent-runtime/src/statewire-suspended.cjs.map +1 -1
  72. package/dist/agent-runtime/src/subagents.cjs +32 -2
  73. package/dist/agent-runtime/src/subagents.cjs.map +1 -1
  74. package/dist/agent-runtime/src/subagents.d.ts +9 -0
  75. package/dist/agent-runtime/src/subagents.js +30 -0
  76. package/dist/agent-runtime/src/subagents.js.map +1 -1
  77. package/dist/agent-runtime/src/thread-driver.cjs +67 -0
  78. package/dist/agent-runtime/src/thread-driver.cjs.map +1 -0
  79. package/dist/agent-runtime/src/thread-driver.d.ts +49 -0
  80. package/dist/agent-runtime/src/thread-driver.js +67 -0
  81. package/dist/agent-runtime/src/thread-driver.js.map +1 -0
  82. package/dist/agent-runtime/src/thread-handoff-flow-machine.d.ts +172 -0
  83. package/dist/agent-runtime/src/thread-handoff-protocol.d.ts +756 -0
  84. package/dist/agent-runtime/src/thread-handoff-qr.d.ts +11 -0
  85. package/dist/agent-runtime/src/thread-handoff.d.ts +3 -364
  86. package/dist/agent-runtime/src/thread-status.cjs +3 -3
  87. package/dist/agent-runtime/src/thread-status.cjs.map +1 -1
  88. package/dist/agent-runtime/src/tool-metadata.cjs +210 -25
  89. package/dist/agent-runtime/src/tool-metadata.cjs.map +1 -1
  90. package/dist/agent-runtime/src/tool-metadata.d.ts +12 -0
  91. package/dist/agent-runtime/src/tool-metadata.js +210 -25
  92. package/dist/agent-runtime/src/tool-metadata.js.map +1 -1
  93. package/dist/agent-runtime/src/tool-names.cjs +2 -0
  94. package/dist/agent-runtime/src/tool-names.cjs.map +1 -1
  95. package/dist/agent-runtime/src/tool-names.d.ts +2 -0
  96. package/dist/agent-runtime/src/tool-names.js +2 -0
  97. package/dist/agent-runtime/src/tool-names.js.map +1 -1
  98. package/dist/agent-runtime/src/types.d.ts +10 -2
  99. package/dist/agent-runtime/src/use-conversation-list.cjs +11 -11
  100. package/dist/agent-runtime/src/use-conversation-list.cjs.map +1 -1
  101. package/dist/agent-runtime/src/use-deep-agent-chat-outbox.cjs +24 -19
  102. package/dist/agent-runtime/src/use-deep-agent-chat-outbox.cjs.map +1 -1
  103. package/dist/agent-runtime/src/use-deep-agent-chat-outbox.d.ts +2 -1
  104. package/dist/agent-runtime/src/use-deep-agent-chat-outbox.js +6 -1
  105. package/dist/agent-runtime/src/use-deep-agent-chat-outbox.js.map +1 -1
  106. package/dist/agent-runtime/src/use-deep-agent-config.cjs +14 -14
  107. package/dist/agent-runtime/src/use-deep-agent-config.cjs.map +1 -1
  108. package/dist/agent-runtime/src/use-deep-agent-edit-submit.cjs +6 -6
  109. package/dist/agent-runtime/src/use-deep-agent-edit-submit.cjs.map +1 -1
  110. package/dist/agent-runtime/src/use-deep-agent-runtime.cjs +16 -16
  111. package/dist/agent-runtime/src/use-deep-agent-runtime.cjs.map +1 -1
  112. package/dist/agent-runtime/src/use-deep-agent-thread.cjs +45 -45
  113. package/dist/agent-runtime/src/use-deep-agent-thread.cjs.map +1 -1
  114. package/dist/agent-runtime/src/use-deep-agent-voice.cjs +547 -124
  115. package/dist/agent-runtime/src/use-deep-agent-voice.cjs.map +1 -1
  116. package/dist/agent-runtime/src/use-deep-agent-voice.d.ts +129 -10
  117. package/dist/agent-runtime/src/use-deep-agent-voice.js +487 -64
  118. package/dist/agent-runtime/src/use-deep-agent-voice.js.map +1 -1
  119. package/dist/agent-runtime/src/use-deep-agent-window-sync.cjs +26 -26
  120. package/dist/agent-runtime/src/use-deep-agent-window-sync.cjs.map +1 -1
  121. package/dist/agent-runtime/src/use-historical-edit-attachments.cjs +4 -4
  122. package/dist/agent-runtime/src/use-historical-edit-attachments.cjs.map +1 -1
  123. package/dist/agent-runtime/src/use-thread-handoff-flow.d.ts +28 -26
  124. package/dist/agent-runtime/src/voice-media.cjs +117 -0
  125. package/dist/agent-runtime/src/voice-media.cjs.map +1 -0
  126. package/dist/agent-runtime/src/voice-media.d.ts +49 -0
  127. package/dist/agent-runtime/src/voice-media.js +117 -0
  128. package/dist/agent-runtime/src/voice-media.js.map +1 -0
  129. package/dist/agent-runtime/src/voice-wire-types.d.ts +32 -0
  130. package/dist/assets/AssetPanel.cjs +11 -11
  131. package/dist/assets/AssetPanel.cjs.map +1 -1
  132. package/dist/assets/AthenaAssetEmbed.cjs +11 -9
  133. package/dist/assets/AthenaAssetEmbed.cjs.map +1 -1
  134. package/dist/assets/AthenaAssetEmbed.d.ts +7 -0
  135. package/dist/assets/AthenaAssetEmbed.js +4 -2
  136. package/dist/assets/AthenaAssetEmbed.js.map +1 -1
  137. package/dist/assets/AthenaLayout.cjs +16 -16
  138. package/dist/assets/AthenaLayout.cjs.map +1 -1
  139. package/dist/assets/use-asset-content.cjs +4 -4
  140. package/dist/assets/use-asset-content.cjs.map +1 -1
  141. package/dist/assets/use-asset-embed.cjs +14 -7
  142. package/dist/assets/use-asset-embed.cjs.map +1 -1
  143. package/dist/assets/use-asset-embed.d.ts +11 -1
  144. package/dist/assets/use-asset-embed.js +10 -3
  145. package/dist/assets/use-asset-embed.js.map +1 -1
  146. package/dist/auth/AthenaAuthContext.cjs +3 -3
  147. package/dist/auth/AthenaAuthContext.cjs.map +1 -1
  148. package/dist/auth/AthenaAuthProvider.cjs +8 -8
  149. package/dist/auth/AthenaAuthProvider.cjs.map +1 -1
  150. package/dist/auth/AthenaCredentialSourceContext.cjs +5 -5
  151. package/dist/auth/AthenaCredentialSourceContext.cjs.map +1 -1
  152. package/dist/auth/AthenaSSOProvider.cjs +14 -14
  153. package/dist/auth/AthenaSSOProvider.cjs.map +1 -1
  154. package/dist/auth/credential-source.cjs +26 -13
  155. package/dist/auth/credential-source.cjs.map +1 -1
  156. package/dist/auth/credential-source.d.ts +8 -0
  157. package/dist/auth/credential-source.js +26 -13
  158. package/dist/auth/credential-source.js.map +1 -1
  159. package/dist/catalog/agent-model-options.cjs +25 -17
  160. package/dist/catalog/agent-model-options.cjs.map +1 -1
  161. package/dist/catalog/agent-model-options.d.ts +38 -5
  162. package/dist/catalog/agent-model-options.js +25 -17
  163. package/dist/catalog/agent-model-options.js.map +1 -1
  164. package/dist/catalog/channel-refusal.cjs +36 -0
  165. package/dist/catalog/channel-refusal.cjs.map +1 -0
  166. package/dist/catalog/channel-refusal.d.ts +29 -0
  167. package/dist/catalog/channel-refusal.js +36 -0
  168. package/dist/catalog/channel-refusal.js.map +1 -0
  169. package/dist/catalog/chat-pickers.cjs +60 -24
  170. package/dist/catalog/chat-pickers.cjs.map +1 -1
  171. package/dist/catalog/chat-pickers.d.ts +12 -2
  172. package/dist/catalog/chat-pickers.js +56 -20
  173. package/dist/catalog/chat-pickers.js.map +1 -1
  174. package/dist/catalog/runtime-catalog.cjs +89 -23
  175. package/dist/catalog/runtime-catalog.cjs.map +1 -1
  176. package/dist/catalog/runtime-catalog.d.ts +8 -2
  177. package/dist/catalog/runtime-catalog.js +83 -17
  178. package/dist/catalog/runtime-catalog.js.map +1 -1
  179. package/dist/catalog/use-athena-chat-mode.cjs +12 -12
  180. package/dist/catalog/use-athena-chat-mode.cjs.map +1 -1
  181. package/dist/chat/AthenaChat.cjs +155 -67
  182. package/dist/chat/AthenaChat.cjs.map +1 -1
  183. package/dist/chat/AthenaChat.d.ts +42 -2
  184. package/dist/chat/AthenaChat.js +106 -18
  185. package/dist/chat/AthenaChat.js.map +1 -1
  186. package/dist/chat/AthenaChatErrorBoundary.cjs +3 -3
  187. package/dist/chat/AthenaChatErrorBoundary.cjs.map +1 -1
  188. package/dist/chat/DrivingOnChip.cjs +23 -0
  189. package/dist/chat/DrivingOnChip.cjs.map +1 -0
  190. package/dist/chat/DrivingOnChip.d.ts +17 -0
  191. package/dist/chat/DrivingOnChip.js +23 -0
  192. package/dist/chat/DrivingOnChip.js.map +1 -0
  193. package/dist/chat/StatewireApprovalCard.cjs +125 -31
  194. package/dist/chat/StatewireApprovalCard.cjs.map +1 -1
  195. package/dist/chat/StatewireApprovalCard.d.ts +73 -1
  196. package/dist/chat/StatewireApprovalCard.js +115 -21
  197. package/dist/chat/StatewireApprovalCard.js.map +1 -1
  198. package/dist/chat/StatewireClientToolBridge.cjs +2 -2
  199. package/dist/chat/StatewireClientToolBridge.cjs.map +1 -1
  200. package/dist/chat/StatewireQueuedMessages.cjs +25 -63
  201. package/dist/chat/StatewireQueuedMessages.cjs.map +1 -1
  202. package/dist/chat/StatewireQueuedMessages.d.ts +11 -13
  203. package/dist/chat/StatewireQueuedMessages.js +16 -54
  204. package/dist/chat/StatewireQueuedMessages.js.map +1 -1
  205. package/dist/chat/WaitingOnYouBanner.cjs +3 -3
  206. package/dist/chat/WaitingOnYouBanner.cjs.map +1 -1
  207. package/dist/chat/athena-chat-welcome.cjs +2 -2
  208. package/dist/chat/athena-chat-welcome.cjs.map +1 -1
  209. package/dist/chat/athena-citation-links.cjs +5 -5
  210. package/dist/chat/athena-citation-links.cjs.map +1 -1
  211. package/dist/chat/athena-composer-controls.cjs +26 -16
  212. package/dist/chat/athena-composer-controls.cjs.map +1 -1
  213. package/dist/chat/athena-composer-controls.d.ts +6 -0
  214. package/dist/chat/athena-composer-controls.js +26 -16
  215. package/dist/chat/athena-composer-controls.js.map +1 -1
  216. package/dist/chat/athena-turn-end-status.cjs +42 -0
  217. package/dist/chat/athena-turn-end-status.cjs.map +1 -0
  218. package/dist/chat/athena-turn-end-status.d.ts +24 -0
  219. package/dist/chat/athena-turn-end-status.js +42 -0
  220. package/dist/chat/athena-turn-end-status.js.map +1 -0
  221. package/dist/chat/browser-decision-check.cjs +131 -0
  222. package/dist/chat/browser-decision-check.cjs.map +1 -0
  223. package/dist/chat/browser-decision-check.d.ts +61 -0
  224. package/dist/chat/browser-decision-check.js +131 -0
  225. package/dist/chat/browser-decision-check.js.map +1 -0
  226. package/dist/chat/chat-outbox-rows.cjs +3 -3
  227. package/dist/chat/chat-outbox-rows.cjs.map +1 -1
  228. package/dist/chat/chat-voice-controls.cjs +93 -28
  229. package/dist/chat/chat-voice-controls.cjs.map +1 -1
  230. package/dist/chat/chat-voice-controls.d.ts +36 -2
  231. package/dist/chat/chat-voice-controls.js +89 -24
  232. package/dist/chat/chat-voice-controls.js.map +1 -1
  233. package/dist/chat/composer-keyboard-hint.cjs +5 -5
  234. package/dist/chat/composer-keyboard-hint.cjs.map +1 -1
  235. package/dist/chat/device-operation.cjs +29 -0
  236. package/dist/chat/device-operation.cjs.map +1 -0
  237. package/dist/chat/device-operation.d.ts +34 -0
  238. package/dist/chat/device-operation.js +29 -0
  239. package/dist/chat/device-operation.js.map +1 -0
  240. package/dist/chat/super-grouping/CollapsibleGroup.cjs +14 -14
  241. package/dist/chat/super-grouping/CollapsibleGroup.cjs.map +1 -1
  242. package/dist/chat/super-grouping/GroupedMessageParts.cjs +4 -4
  243. package/dist/chat/super-grouping/GroupedMessageParts.cjs.map +1 -1
  244. package/dist/chat/super-grouping/SuperGroupingCard.cjs +52 -36
  245. package/dist/chat/super-grouping/SuperGroupingCard.cjs.map +1 -1
  246. package/dist/chat/super-grouping/SuperGroupingCard.d.ts +19 -4
  247. package/dist/chat/super-grouping/SuperGroupingCard.js +29 -13
  248. package/dist/chat/super-grouping/SuperGroupingCard.js.map +1 -1
  249. package/dist/chat/super-grouping/SuperGroupingTranscript.cjs +32 -32
  250. package/dist/chat/super-grouping/SuperGroupingTranscript.cjs.map +1 -1
  251. package/dist/chat/super-grouping/SuperGroupingTranscript.js +3 -3
  252. package/dist/chat/super-grouping/SuperGroupingTranscript.js.map +1 -1
  253. package/dist/chat/super-grouping/ToolTimeline.cjs +73 -40
  254. package/dist/chat/super-grouping/ToolTimeline.cjs.map +1 -1
  255. package/dist/chat/super-grouping/ToolTimeline.d.ts +10 -2
  256. package/dist/chat/super-grouping/ToolTimeline.js +69 -36
  257. package/dist/chat/super-grouping/ToolTimeline.js.map +1 -1
  258. package/dist/chat/super-grouping/activity-timeline.cjs +47 -12
  259. package/dist/chat/super-grouping/activity-timeline.cjs.map +1 -1
  260. package/dist/chat/super-grouping/activity-timeline.d.ts +21 -0
  261. package/dist/chat/super-grouping/activity-timeline.js +47 -12
  262. package/dist/chat/super-grouping/activity-timeline.js.map +1 -1
  263. package/dist/chat/super-grouping/grouping-function.cjs +4 -0
  264. package/dist/chat/super-grouping/grouping-function.cjs.map +1 -1
  265. package/dist/chat/super-grouping/grouping-function.d.ts +7 -0
  266. package/dist/chat/super-grouping/grouping-function.js +5 -1
  267. package/dist/chat/super-grouping/grouping-function.js.map +1 -1
  268. package/dist/chat/super-grouping/index.cjs +6 -0
  269. package/dist/chat/super-grouping/index.cjs.map +1 -1
  270. package/dist/chat/super-grouping/index.d.ts +5 -2
  271. package/dist/chat/super-grouping/index.js +7 -1
  272. package/dist/chat/super-grouping/index.js.map +1 -1
  273. package/dist/chat/super-grouping/tool-part-placement.cjs +17 -0
  274. package/dist/chat/super-grouping/tool-part-placement.cjs.map +1 -0
  275. package/dist/chat/super-grouping/tool-part-placement.d.ts +22 -0
  276. package/dist/chat/super-grouping/tool-part-placement.js +17 -0
  277. package/dist/chat/super-grouping/tool-part-placement.js.map +1 -0
  278. package/dist/chat/thread-scroll-to-bottom.cjs +2 -2
  279. package/dist/chat/thread-scroll-to-bottom.cjs.map +1 -1
  280. package/dist/chat/thread-scroll-to-bottom.d.ts +10 -7
  281. package/dist/chat/thread-scroll-to-bottom.js +2 -2
  282. package/dist/chat/thread-scroll-to-bottom.js.map +1 -1
  283. package/dist/chat/tooltip-icon-button.cjs +2 -2
  284. package/dist/chat/tooltip-icon-button.cjs.map +1 -1
  285. package/dist/chat/use-athena-voice-live.cjs +11 -0
  286. package/dist/chat/use-athena-voice-live.cjs.map +1 -0
  287. package/dist/chat/use-athena-voice-live.d.ts +11 -0
  288. package/dist/chat/use-athena-voice-live.js +11 -0
  289. package/dist/chat/use-athena-voice-live.js.map +1 -0
  290. package/dist/chat/use-statewire-approval-request.cjs +56 -24
  291. package/dist/chat/use-statewire-approval-request.cjs.map +1 -1
  292. package/dist/chat/use-statewire-approval-request.d.ts +33 -4
  293. package/dist/chat/use-statewire-approval-request.js +41 -9
  294. package/dist/chat/use-statewire-approval-request.js.map +1 -1
  295. package/dist/chat-ui/auth/sign-in-card.cjs +2 -2
  296. package/dist/chat-ui/auth/sign-in-card.cjs.map +1 -1
  297. package/dist/chat-ui/composer/tiptap-composer.cjs +138 -107
  298. package/dist/chat-ui/composer/tiptap-composer.cjs.map +1 -1
  299. package/dist/chat-ui/composer/tiptap-composer.d.ts +20 -4
  300. package/dist/chat-ui/composer/tiptap-composer.js +85 -54
  301. package/dist/chat-ui/composer/tiptap-composer.js.map +1 -1
  302. package/dist/chat-ui/header/conversation-history-panel.cjs +49 -23
  303. package/dist/chat-ui/header/conversation-history-panel.cjs.map +1 -1
  304. package/dist/chat-ui/header/conversation-history-panel.d.ts +12 -1
  305. package/dist/chat-ui/header/conversation-history-panel.js +38 -12
  306. package/dist/chat-ui/header/conversation-history-panel.js.map +1 -1
  307. package/dist/chat-ui/index.cjs +18 -0
  308. package/dist/chat-ui/index.cjs.map +1 -1
  309. package/dist/chat-ui/index.d.ts +7 -1
  310. package/dist/chat-ui/index.js +18 -0
  311. package/dist/chat-ui/index.js.map +1 -1
  312. package/dist/chat-ui/mentions/mention-chip.cjs +4 -4
  313. package/dist/chat-ui/mentions/mention-chip.cjs.map +1 -1
  314. package/dist/chat-ui/mentions/suggestions/components/mention-suggestion-list.cjs +10 -9
  315. package/dist/chat-ui/mentions/suggestions/components/mention-suggestion-list.cjs.map +1 -1
  316. package/dist/chat-ui/mentions/suggestions/components/mention-suggestion-list.js +3 -2
  317. package/dist/chat-ui/mentions/suggestions/components/mention-suggestion-list.js.map +1 -1
  318. package/dist/chat-ui/mentions/suggestions/components/mention-suggestion-popup.cjs +2 -2
  319. package/dist/chat-ui/mentions/suggestions/components/mention-suggestion-popup.cjs.map +1 -1
  320. package/dist/chat-ui/mentions/suggestions/components/menu-list.cjs +29 -6
  321. package/dist/chat-ui/mentions/suggestions/components/menu-list.cjs.map +1 -1
  322. package/dist/chat-ui/mentions/suggestions/components/menu-list.d.ts +7 -1
  323. package/dist/chat-ui/mentions/suggestions/components/menu-list.js +25 -2
  324. package/dist/chat-ui/mentions/suggestions/components/menu-list.js.map +1 -1
  325. package/dist/chat-ui/mentions/suggestions/components/use-keyboard-navigation.cjs +2 -2
  326. package/dist/chat-ui/mentions/suggestions/components/use-keyboard-navigation.cjs.map +1 -1
  327. package/dist/chat-ui/mentions/suggestions/components/use-menu-navigation.cjs +2 -2
  328. package/dist/chat-ui/mentions/suggestions/components/use-menu-navigation.cjs.map +1 -1
  329. package/dist/chat-ui/mentions/suggestions/data/api-client.cjs +3 -3
  330. package/dist/chat-ui/mentions/suggestions/data/api-client.cjs.map +1 -1
  331. package/dist/chat-ui/mentions/suggestions/data/orchestrator.cjs +56 -2
  332. package/dist/chat-ui/mentions/suggestions/data/orchestrator.cjs.map +1 -1
  333. package/dist/chat-ui/mentions/suggestions/data/orchestrator.d.ts +12 -0
  334. package/dist/chat-ui/mentions/suggestions/data/orchestrator.js +56 -2
  335. package/dist/chat-ui/mentions/suggestions/data/orchestrator.js.map +1 -1
  336. package/dist/chat-ui/mentions/suggestions/data/sources/index.cjs +24 -3
  337. package/dist/chat-ui/mentions/suggestions/data/sources/index.cjs.map +1 -1
  338. package/dist/chat-ui/mentions/suggestions/data/sources/index.d.ts +7 -0
  339. package/dist/chat-ui/mentions/suggestions/data/sources/index.js +24 -3
  340. package/dist/chat-ui/mentions/suggestions/data/sources/index.js.map +1 -1
  341. package/dist/chat-ui/mentions/suggestions/data/use-mention-suggestions.cjs +35 -13
  342. package/dist/chat-ui/mentions/suggestions/data/use-mention-suggestions.cjs.map +1 -1
  343. package/dist/chat-ui/mentions/suggestions/data/use-mention-suggestions.d.ts +15 -1
  344. package/dist/chat-ui/mentions/suggestions/data/use-mention-suggestions.js +28 -6
  345. package/dist/chat-ui/mentions/suggestions/data/use-mention-suggestions.js.map +1 -1
  346. package/dist/chat-ui/mentions/suggestions/data/use-menu-items.cjs +9 -6
  347. package/dist/chat-ui/mentions/suggestions/data/use-menu-items.cjs.map +1 -1
  348. package/dist/chat-ui/mentions/suggestions/data/use-menu-items.d.ts +3 -0
  349. package/dist/chat-ui/mentions/suggestions/data/use-menu-items.js +5 -2
  350. package/dist/chat-ui/mentions/suggestions/data/use-menu-items.js.map +1 -1
  351. package/dist/chat-ui/mentions/use-account-workspace-id.cjs +45 -10
  352. package/dist/chat-ui/mentions/use-account-workspace-id.cjs.map +1 -1
  353. package/dist/chat-ui/mentions/use-account-workspace-id.d.ts +24 -1
  354. package/dist/chat-ui/mentions/use-account-workspace-id.js +46 -11
  355. package/dist/chat-ui/mentions/use-account-workspace-id.js.map +1 -1
  356. package/dist/chat-ui/mentions/use-member-avatar.cjs +4 -4
  357. package/dist/chat-ui/mentions/use-member-avatar.cjs.map +1 -1
  358. package/dist/chat-ui/mentions/use-mention-asset.cjs +3 -3
  359. package/dist/chat-ui/mentions/use-mention-asset.cjs.map +1 -1
  360. package/dist/chat-ui/messages/answer-label.cjs +42 -0
  361. package/dist/chat-ui/messages/answer-label.cjs.map +1 -0
  362. package/dist/chat-ui/messages/answer-label.d.ts +33 -0
  363. package/dist/chat-ui/messages/answer-label.js +42 -0
  364. package/dist/chat-ui/messages/answer-label.js.map +1 -0
  365. package/dist/chat-ui/messages/arrival-animation.cjs +13 -0
  366. package/dist/chat-ui/messages/arrival-animation.cjs.map +1 -0
  367. package/dist/chat-ui/messages/arrival-animation.d.ts +14 -0
  368. package/dist/chat-ui/messages/arrival-animation.js +13 -0
  369. package/dist/chat-ui/messages/arrival-animation.js.map +1 -0
  370. package/dist/chat-ui/messages/continue-pill.cjs +5 -5
  371. package/dist/chat-ui/messages/continue-pill.cjs.map +1 -1
  372. package/dist/chat-ui/messages/handoff-arrival-divider.cjs +44 -0
  373. package/dist/chat-ui/messages/handoff-arrival-divider.cjs.map +1 -0
  374. package/dist/chat-ui/messages/handoff-arrival-divider.d.ts +17 -0
  375. package/dist/chat-ui/messages/handoff-arrival-divider.js +44 -0
  376. package/dist/chat-ui/messages/handoff-arrival-divider.js.map +1 -0
  377. package/dist/chat-ui/messages/message-actions-config.cjs +3 -3
  378. package/dist/chat-ui/messages/message-actions-config.cjs.map +1 -1
  379. package/dist/chat-ui/messages/message-components.cjs +8 -4
  380. package/dist/chat-ui/messages/message-components.cjs.map +1 -1
  381. package/dist/chat-ui/messages/message-components.js +5 -1
  382. package/dist/chat-ui/messages/message-components.js.map +1 -1
  383. package/dist/chat-ui/messages/message-images.cjs +66 -0
  384. package/dist/chat-ui/messages/message-images.cjs.map +1 -0
  385. package/dist/chat-ui/messages/message-images.d.ts +16 -0
  386. package/dist/chat-ui/messages/message-images.js +66 -0
  387. package/dist/chat-ui/messages/message-images.js.map +1 -0
  388. package/dist/chat-ui/messages/user-edit-composer.cjs +2 -2
  389. package/dist/chat-ui/messages/user-edit-composer.cjs.map +1 -1
  390. package/dist/chat-ui/messages/wake-marker.cjs +3 -3
  391. package/dist/chat-ui/messages/wake-marker.cjs.map +1 -1
  392. package/dist/chat-ui/rich-text/chat-link.cjs +2 -2
  393. package/dist/chat-ui/rich-text/chat-link.cjs.map +1 -1
  394. package/dist/chat-ui/rich-text/chat-message-body.cjs +8 -8
  395. package/dist/chat-ui/rich-text/chat-message-body.cjs.map +1 -1
  396. package/dist/chat-ui/rich-text/chat-node-views.cjs +6 -6
  397. package/dist/chat-ui/rich-text/chat-node-views.cjs.map +1 -1
  398. package/dist/chat-ui/rich-text/dom-output-spec.cjs +2 -2
  399. package/dist/chat-ui/rich-text/dom-output-spec.cjs.map +1 -1
  400. package/dist/chat-ui/statewire.cjs +3 -0
  401. package/dist/chat-ui/statewire.cjs.map +1 -1
  402. package/dist/chat-ui/statewire.d.ts +2 -1
  403. package/dist/chat-ui/statewire.js +3 -0
  404. package/dist/chat-ui/statewire.js.map +1 -1
  405. package/dist/chat-ui/thread/chat-thread-shell.cjs +43 -14
  406. package/dist/chat-ui/thread/chat-thread-shell.cjs.map +1 -1
  407. package/dist/chat-ui/thread/chat-thread-shell.d.ts +16 -2
  408. package/dist/chat-ui/thread/chat-thread-shell.js +35 -6
  409. package/dist/chat-ui/thread/chat-thread-shell.js.map +1 -1
  410. package/dist/chat-ui/thread/composer-send-or-stop.cjs +30 -20
  411. package/dist/chat-ui/thread/composer-send-or-stop.cjs.map +1 -1
  412. package/dist/chat-ui/thread/composer-send-or-stop.d.ts +8 -0
  413. package/dist/chat-ui/thread/composer-send-or-stop.js +29 -19
  414. package/dist/chat-ui/thread/composer-send-or-stop.js.map +1 -1
  415. package/dist/chat-ui/thread/statewire-history-edge.cjs +20 -21
  416. package/dist/chat-ui/thread/statewire-history-edge.cjs.map +1 -1
  417. package/dist/chat-ui/thread/statewire-history-edge.js +3 -4
  418. package/dist/chat-ui/thread/statewire-history-edge.js.map +1 -1
  419. package/dist/chat-ui/thread/thread-loading-overlay.cjs +5 -5
  420. package/dist/chat-ui/thread/thread-loading-overlay.cjs.map +1 -1
  421. package/dist/collab/client.cjs +40 -3
  422. package/dist/collab/client.cjs.map +1 -1
  423. package/dist/collab/client.d.ts +25 -0
  424. package/dist/collab/client.js +40 -3
  425. package/dist/collab/client.js.map +1 -1
  426. package/dist/collab/document-status.cjs +150 -0
  427. package/dist/collab/document-status.cjs.map +1 -0
  428. package/dist/collab/document-status.d.ts +68 -0
  429. package/dist/collab/document-status.js +150 -0
  430. package/dist/collab/document-status.js.map +1 -0
  431. package/dist/collab/index.cjs +7 -0
  432. package/dist/collab/index.cjs.map +1 -1
  433. package/dist/collab/index.d.ts +6 -1
  434. package/dist/collab/index.js +7 -0
  435. package/dist/collab/index.js.map +1 -1
  436. package/dist/collab/presence-react.cjs +11 -11
  437. package/dist/collab/presence-react.cjs.map +1 -1
  438. package/dist/collab/react.cjs +6 -6
  439. package/dist/collab/react.cjs.map +1 -1
  440. package/dist/composer/AttachmentContext.cjs +24 -11
  441. package/dist/composer/AttachmentContext.cjs.map +1 -1
  442. package/dist/composer/AttachmentContext.js +18 -5
  443. package/dist/composer/AttachmentContext.js.map +1 -1
  444. package/dist/composer/ComposerAttachmentPreview.cjs +78 -23
  445. package/dist/composer/ComposerAttachmentPreview.cjs.map +1 -1
  446. package/dist/composer/ComposerAttachmentPreview.d.ts +5 -3
  447. package/dist/composer/ComposerAttachmentPreview.js +79 -24
  448. package/dist/composer/ComposerAttachmentPreview.js.map +1 -1
  449. package/dist/composer/ComposerDropZone.cjs +7 -7
  450. package/dist/composer/ComposerDropZone.cjs.map +1 -1
  451. package/dist/composer/FileUploadButton.cjs +37 -22
  452. package/dist/composer/FileUploadButton.cjs.map +1 -1
  453. package/dist/composer/FileUploadButton.d.ts +6 -0
  454. package/dist/composer/FileUploadButton.js +34 -19
  455. package/dist/composer/FileUploadButton.js.map +1 -1
  456. package/dist/composer/QuoteContext.cjs +8 -8
  457. package/dist/composer/QuoteContext.cjs.map +1 -1
  458. package/dist/composer/composer-handoff.cjs +4 -4
  459. package/dist/composer/composer-handoff.cjs.map +1 -1
  460. package/dist/composer/useAppendToComposer.cjs +4 -4
  461. package/dist/composer/useAppendToComposer.cjs.map +1 -1
  462. package/dist/composer/useAttachFiles.cjs +23 -6
  463. package/dist/composer/useAttachFiles.cjs.map +1 -1
  464. package/dist/composer/useAttachFiles.d.ts +15 -7
  465. package/dist/composer/useAttachFiles.js +22 -5
  466. package/dist/composer/useAttachFiles.js.map +1 -1
  467. package/dist/composer/useComposerAttachment.cjs +4 -4
  468. package/dist/composer/useComposerAttachment.cjs.map +1 -1
  469. package/dist/composer/useFileUpload.cjs +21 -16
  470. package/dist/composer/useFileUpload.cjs.map +1 -1
  471. package/dist/composer/useFileUpload.d.ts +12 -0
  472. package/dist/composer/useFileUpload.js +12 -7
  473. package/dist/composer/useFileUpload.js.map +1 -1
  474. package/dist/composer/useReadComposerDraft.cjs +2 -2
  475. package/dist/composer/useReadComposerDraft.cjs.map +1 -1
  476. package/dist/composer/useSendMessage.cjs +4 -4
  477. package/dist/composer/useSendMessage.cjs.map +1 -1
  478. package/dist/diagnostics/useAthenaDiagnostics.cjs +4 -4
  479. package/dist/diagnostics/useAthenaDiagnostics.cjs.map +1 -1
  480. package/dist/dictation/audio-level-history.cjs +3 -3
  481. package/dist/dictation/audio-level-history.cjs.map +1 -1
  482. package/dist/dictation/dictation-controls.cjs +24 -20
  483. package/dist/dictation/dictation-controls.cjs.map +1 -1
  484. package/dist/dictation/dictation-controls.d.ts +6 -1
  485. package/dist/dictation/dictation-controls.js +24 -20
  486. package/dist/dictation/dictation-controls.js.map +1 -1
  487. package/dist/dictation/use-athena-dictation-engine.cjs +3 -3
  488. package/dist/dictation/use-athena-dictation-engine.cjs.map +1 -1
  489. package/dist/dictation/use-dictation.cjs +22 -22
  490. package/dist/dictation/use-dictation.cjs.map +1 -1
  491. package/dist/index.cjs +26 -2
  492. package/dist/index.cjs.map +1 -1
  493. package/dist/index.d.ts +15 -3
  494. package/dist/index.js +26 -2
  495. package/dist/index.js.map +1 -1
  496. package/dist/keryx-http/src/receive-only-socket.cjs +40 -0
  497. package/dist/keryx-http/src/receive-only-socket.cjs.map +1 -0
  498. package/dist/keryx-http/src/receive-only-socket.d.ts +27 -0
  499. package/dist/keryx-http/src/receive-only-socket.js +40 -0
  500. package/dist/keryx-http/src/receive-only-socket.js.map +1 -0
  501. package/dist/keryx-http/src/update-attributions.cjs +111 -0
  502. package/dist/keryx-http/src/update-attributions.cjs.map +1 -0
  503. package/dist/keryx-http/src/update-attributions.d.ts +75 -0
  504. package/dist/keryx-http/src/update-attributions.js +111 -0
  505. package/dist/keryx-http/src/update-attributions.js.map +1 -0
  506. package/dist/lib/owner-document.cjs +6 -6
  507. package/dist/lib/owner-document.cjs.map +1 -1
  508. package/dist/lib/use-athena-rest-query.cjs +4 -4
  509. package/dist/lib/use-athena-rest-query.cjs.map +1 -1
  510. package/dist/lib/use-document-active.cjs +4 -4
  511. package/dist/lib/use-document-active.cjs.map +1 -1
  512. package/dist/lib/use-prefers-reduced-motion.cjs +2 -2
  513. package/dist/lib/use-prefers-reduced-motion.cjs.map +1 -1
  514. package/dist/offline/offline-history.cjs +7 -7
  515. package/dist/offline/offline-history.cjs.map +1 -1
  516. package/dist/provider/AthenaContext.cjs +3 -3
  517. package/dist/provider/AthenaContext.cjs.map +1 -1
  518. package/dist/provider/AthenaProvider.cjs +116 -79
  519. package/dist/provider/AthenaProvider.cjs.map +1 -1
  520. package/dist/provider/AthenaProvider.js +40 -3
  521. package/dist/provider/AthenaProvider.js.map +1 -1
  522. package/dist/provider/PostHogProvider.cjs +2 -2
  523. package/dist/provider/PostHogProvider.cjs.map +1 -1
  524. package/dist/provider/agent-selection-context.cjs +2 -2
  525. package/dist/provider/agent-selection-context.cjs.map +1 -1
  526. package/dist/provider/chat-mode-context.cjs +2 -2
  527. package/dist/provider/chat-mode-context.cjs.map +1 -1
  528. package/dist/provider/session-persistence-context.cjs +10 -0
  529. package/dist/provider/session-persistence-context.cjs.map +1 -0
  530. package/dist/provider/session-persistence-context.d.ts +15 -0
  531. package/dist/provider/session-persistence-context.js +10 -0
  532. package/dist/provider/session-persistence-context.js.map +1 -0
  533. package/dist/provider/statewire-history-context.cjs +4 -4
  534. package/dist/provider/statewire-history-context.cjs.map +1 -1
  535. package/dist/provider/statewire-lifecycle-context.cjs +3 -3
  536. package/dist/provider/statewire-lifecycle-context.cjs.map +1 -1
  537. package/dist/provider/statewire-window-context.cjs +3 -3
  538. package/dist/provider/statewire-window-context.cjs.map +1 -1
  539. package/dist/provider/theme-style-context.cjs +3 -3
  540. package/dist/provider/theme-style-context.cjs.map +1 -1
  541. package/dist/react/package.json.cjs +1 -1
  542. package/dist/react/package.json.js +1 -1
  543. package/dist/runtime/StatewireThreadConfigLaneSync.cjs +10 -10
  544. package/dist/runtime/StatewireThreadConfigLaneSync.cjs.map +1 -1
  545. package/dist/runtime/auth-refusal-restart.cjs +7 -7
  546. package/dist/runtime/auth-refusal-restart.cjs.map +1 -1
  547. package/dist/runtime/auth.cjs +13 -13
  548. package/dist/runtime/auth.cjs.map +1 -1
  549. package/dist/runtime/statewire-lifecycle.cjs +1 -0
  550. package/dist/runtime/statewire-lifecycle.cjs.map +1 -1
  551. package/dist/runtime/statewire-lifecycle.d.ts +3 -1
  552. package/dist/runtime/statewire-lifecycle.js +2 -1
  553. package/dist/runtime/statewire-lifecycle.js.map +1 -1
  554. package/dist/runtime/statewire-server-lane-context.cjs +2 -2
  555. package/dist/runtime/statewire-server-lane-context.cjs.map +1 -1
  556. package/dist/runtime/statewire-session-lane.cjs +4 -4
  557. package/dist/runtime/statewire-session-lane.cjs.map +1 -1
  558. package/dist/runtime/useAthenaStatewireRuntime.cjs +10 -8
  559. package/dist/runtime/useAthenaStatewireRuntime.cjs.map +1 -1
  560. package/dist/runtime/useAthenaStatewireRuntime.d.ts +2 -0
  561. package/dist/runtime/useAthenaStatewireRuntime.js +2 -0
  562. package/dist/runtime/useAthenaStatewireRuntime.js.map +1 -1
  563. package/dist/styles.css +1 -1
  564. package/dist/threads/Inbox.cjs +8 -8
  565. package/dist/threads/Inbox.cjs.map +1 -1
  566. package/dist/threads/SessionList.cjs +9 -9
  567. package/dist/threads/SessionList.cjs.map +1 -1
  568. package/dist/threads/SessionsPage.cjs +11 -11
  569. package/dist/threads/SessionsPage.cjs.map +1 -1
  570. package/dist/threads/index-triggered-refresh.cjs +10 -10
  571. package/dist/threads/index-triggered-refresh.cjs.map +1 -1
  572. package/dist/threads/mark-viewed-thread-read.cjs +12 -12
  573. package/dist/threads/mark-viewed-thread-read.cjs.map +1 -1
  574. package/dist/threads/offline-session-list.cjs +3 -3
  575. package/dist/threads/offline-session-list.cjs.map +1 -1
  576. package/dist/threads/session-list-tab-share.cjs +5 -5
  577. package/dist/threads/session-list-tab-share.cjs.map +1 -1
  578. package/dist/threads/statewire-thread-list.cjs +51 -51
  579. package/dist/threads/statewire-thread-list.cjs.map +1 -1
  580. package/dist/threads/thread-id-context.cjs +5 -5
  581. package/dist/threads/thread-id-context.cjs.map +1 -1
  582. package/dist/threads/use-athena-session-attention.cjs +2 -2
  583. package/dist/threads/use-athena-session-attention.cjs.map +1 -1
  584. package/dist/threads/use-athena-sessions.cjs +10 -10
  585. package/dist/threads/use-athena-sessions.cjs.map +1 -1
  586. package/dist/threads/use-athena-thread-model.cjs +3 -3
  587. package/dist/threads/use-athena-thread-model.cjs.map +1 -1
  588. package/dist/threads/use-rest-conversation-history.cjs +3 -3
  589. package/dist/threads/use-rest-conversation-history.cjs.map +1 -1
  590. package/dist/threads/use-statewire-conversation-history.cjs +8 -8
  591. package/dist/threads/use-statewire-conversation-history.cjs.map +1 -1
  592. package/dist/threads/use-thread-archive.cjs +9 -9
  593. package/dist/threads/use-thread-archive.cjs.map +1 -1
  594. package/dist/threads/use-thread-favorite.cjs +2 -2
  595. package/dist/threads/use-thread-favorite.cjs.map +1 -1
  596. package/dist/threads/use-thread-field-override.cjs +20 -20
  597. package/dist/threads/use-thread-field-override.cjs.map +1 -1
  598. package/dist/threads/use-thread-read-state.cjs +4 -4
  599. package/dist/threads/use-thread-read-state.cjs.map +1 -1
  600. package/dist/threads/use-thread-rename.cjs +2 -2
  601. package/dist/threads/use-thread-rename.cjs.map +1 -1
  602. package/dist/threads/useAthenaThreadManager.cjs +2 -2
  603. package/dist/threads/useAthenaThreadManager.cjs.map +1 -1
  604. package/dist/tools/NestedPtcMessages.cjs +6 -6
  605. package/dist/tools/NestedPtcMessages.cjs.map +1 -1
  606. package/dist/tools/append-document-tool-ui.cjs +7 -7
  607. package/dist/tools/append-document-tool-ui.cjs.map +1 -1
  608. package/dist/tools/file-tool-uis.cjs +2 -2
  609. package/dist/tools/file-tool-uis.cjs.map +1 -1
  610. package/dist/tools/misc-tool-uis.cjs +2 -2
  611. package/dist/tools/misc-tool-uis.cjs.map +1 -1
  612. package/dist/tools/primitives.cjs +6 -6
  613. package/dist/tools/primitives.cjs.map +1 -1
  614. package/dist/tools/read-asset-tool-ui.cjs +6 -6
  615. package/dist/tools/read-asset-tool-ui.cjs.map +1 -1
  616. package/dist/tools/subagent-task-tool-ui.cjs +21 -21
  617. package/dist/tools/subagent-task-tool-ui.cjs.map +1 -1
  618. package/dist/tools/test-recording-tool-uis.cjs +16 -16
  619. package/dist/tools/test-recording-tool-uis.cjs.map +1 -1
  620. package/dist/tools/todo-plan-store.cjs +4 -4
  621. package/dist/tools/todo-plan-store.cjs.map +1 -1
  622. package/dist/tools/tool-appearance.cjs +3 -3
  623. package/dist/tools/tool-appearance.cjs.map +1 -1
  624. package/dist/tools/tool-fallback.cjs +14 -14
  625. package/dist/tools/tool-fallback.cjs.map +1 -1
  626. package/dist/tools/tool-uis.cjs +74 -74
  627. package/dist/tools/tool-uis.cjs.map +1 -1
  628. package/dist/tools/use-elapsed-seconds.cjs +3 -3
  629. package/dist/tools/use-elapsed-seconds.cjs.map +1 -1
  630. package/dist/tools/write-todos-tool-ui.cjs +9 -9
  631. package/dist/tools/write-todos-tool-ui.cjs.map +1 -1
  632. package/dist/ui/image-viewer.cjs +382 -0
  633. package/dist/ui/image-viewer.cjs.map +1 -0
  634. package/dist/ui/image-viewer.d.ts +50 -0
  635. package/dist/ui/image-viewer.js +382 -0
  636. package/dist/ui/image-viewer.js.map +1 -0
  637. package/dist/voice/chat.cjs +6 -0
  638. package/dist/voice/chat.cjs.map +1 -1
  639. package/dist/voice/chat.d.ts +1 -1
  640. package/dist/voice/chat.js +8 -2
  641. package/dist/voice/livekit-join.cjs +52 -101
  642. package/dist/voice/livekit-join.cjs.map +1 -1
  643. package/dist/voice/livekit-join.d.ts +1 -6
  644. package/dist/voice/livekit-join.js +52 -101
  645. package/dist/voice/livekit-join.js.map +1 -1
  646. package/dist/voice/livekit.cjs.map +1 -1
  647. package/dist/voice/livekit.d.ts +11 -1
  648. package/dist/voice/livekit.js.map +1 -1
  649. package/dist/voice/use-athena-voice-session.cjs +34 -34
  650. package/dist/voice/use-athena-voice-session.cjs.map +1 -1
  651. package/dist/workbench/ComputerLiveDesktop.cjs +13 -13
  652. package/dist/workbench/ComputerLiveDesktop.cjs.map +1 -1
  653. package/dist/workbench/SessionWorkbench.cjs +22 -22
  654. package/dist/workbench/SessionWorkbench.cjs.map +1 -1
  655. package/dist/workbench/session-workbench-context.cjs +3 -3
  656. package/dist/workbench/session-workbench-context.cjs.map +1 -1
  657. package/dist/workbench/session-workbench-panes.cjs +8 -8
  658. package/dist/workbench/session-workbench-panes.cjs.map +1 -1
  659. package/dist/workbench/workbench-layout-context.cjs +3 -3
  660. package/dist/workbench/workbench-layout-context.cjs.map +1 -1
  661. package/package.json +2 -1
@@ -1,10 +1,10 @@
1
1
  "use strict";
2
2
  Object.defineProperty(exports, Symbol.toStringTag, { value: "Module" });
3
- const react = require("react");
3
+ const require$$0 = require("react");
4
4
  const ELAPSED_COUNTER_AFTER_SECONDS = 3;
5
5
  function useElapsedSeconds(active) {
6
- const [seconds, setSeconds] = react.useState(0);
7
- react.useEffect(() => {
6
+ const [seconds, setSeconds] = require$$0.useState(0);
7
+ require$$0.useEffect(() => {
8
8
  setSeconds(0);
9
9
  if (!active) return;
10
10
  const startedAt = Date.now();
@@ -1 +1 @@
1
- {"version":3,"file":"use-elapsed-seconds.cjs","sources":["../../src/tools/use-elapsed-seconds.ts"],"sourcesContent":["import { useEffect, useState } from \"react\";\n\n/** Seconds a running row waits before it starts showing its elapsed counter. */\nexport const ELAPSED_COUNTER_AFTER_SECONDS = 3;\n\n/**\n * Whole seconds since `active` last became true; `0` while inactive. Ticks\n * once a second off the wall clock, so a tab that was throttled catches up on\n * its next tick instead of drifting.\n */\nexport function useElapsedSeconds(active: boolean): number {\n const [seconds, setSeconds] = useState(0);\n useEffect(() => {\n setSeconds(0);\n if (!active) return;\n const startedAt = Date.now();\n const timer = setInterval(() => {\n setSeconds(Math.floor((Date.now() - startedAt) / 1000));\n }, 1000);\n return () => clearInterval(timer);\n }, [active]);\n return active ? seconds : 0;\n}\n\n/** `· 4s` once the counter is due, else nothing to append. */\nexport function elapsedSuffix(seconds: number): string | null {\n return seconds >= ELAPSED_COUNTER_AFTER_SECONDS ? `${seconds}s` : null;\n}\n"],"names":["useState","useEffect"],"mappings":";;;AAGO,MAAM,gCAAgC;AAOtC,SAAS,kBAAkB,QAAyB;AACzD,QAAM,CAAC,SAAS,UAAU,IAAIA,MAAAA,SAAS,CAAC;AACxCC,QAAAA,UAAU,MAAM;AACd,eAAW,CAAC;AACZ,QAAI,CAAC,OAAQ;AACb,UAAM,YAAY,KAAK,IAAA;AACvB,UAAM,QAAQ,YAAY,MAAM;AAC9B,iBAAW,KAAK,OAAO,KAAK,QAAQ,aAAa,GAAI,CAAC;AAAA,IACxD,GAAG,GAAI;AACP,WAAO,MAAM,cAAc,KAAK;AAAA,EAClC,GAAG,CAAC,MAAM,CAAC;AACX,SAAO,SAAS,UAAU;AAC5B;AAGO,SAAS,cAAc,SAAgC;AAC5D,SAAO,WAAW,gCAAgC,GAAG,OAAO,MAAM;AACpE;;;;"}
1
+ {"version":3,"file":"use-elapsed-seconds.cjs","sources":["../../src/tools/use-elapsed-seconds.ts"],"sourcesContent":["import { useEffect, useState } from \"react\";\n\n/** Seconds a running row waits before it starts showing its elapsed counter. */\nexport const ELAPSED_COUNTER_AFTER_SECONDS = 3;\n\n/**\n * Whole seconds since `active` last became true; `0` while inactive. Ticks\n * once a second off the wall clock, so a tab that was throttled catches up on\n * its next tick instead of drifting.\n */\nexport function useElapsedSeconds(active: boolean): number {\n const [seconds, setSeconds] = useState(0);\n useEffect(() => {\n setSeconds(0);\n if (!active) return;\n const startedAt = Date.now();\n const timer = setInterval(() => {\n setSeconds(Math.floor((Date.now() - startedAt) / 1000));\n }, 1000);\n return () => clearInterval(timer);\n }, [active]);\n return active ? seconds : 0;\n}\n\n/** `· 4s` once the counter is due, else nothing to append. */\nexport function elapsedSuffix(seconds: number): string | null {\n return seconds >= ELAPSED_COUNTER_AFTER_SECONDS ? `${seconds}s` : null;\n}\n"],"names":["useState","useEffect"],"mappings":";;;AAGO,MAAM,gCAAgC;AAOtC,SAAS,kBAAkB,QAAyB;AACzD,QAAM,CAAC,SAAS,UAAU,IAAIA,WAAAA,SAAS,CAAC;AACxCC,aAAAA,UAAU,MAAM;AACd,eAAW,CAAC;AACZ,QAAI,CAAC,OAAQ;AACb,UAAM,YAAY,KAAK,IAAA;AACvB,UAAM,QAAQ,YAAY,MAAM;AAC9B,iBAAW,KAAK,OAAO,KAAK,QAAQ,aAAa,GAAI,CAAC;AAAA,IACxD,GAAG,GAAI;AACP,WAAO,MAAM,cAAc,KAAK;AAAA,EAClC,GAAG,CAAC,MAAM,CAAC;AACX,SAAO,SAAS,UAAU;AAC5B;AAGO,SAAS,cAAc,SAAgC;AAC5D,SAAO,WAAW,gCAAgC,GAAG,OAAO,MAAM;AACpE;;;;"}
@@ -1,7 +1,7 @@
1
1
  "use strict";
2
2
  Object.defineProperty(exports, Symbol.toStringTag, { value: "Module" });
3
3
  const jsxRuntime = require("react/jsx-runtime");
4
- const react = require("react");
4
+ const require$$0 = require("react");
5
5
  const lucideReact = require("lucide-react");
6
6
  const todoPlanStore = require("./todo-plan-store.cjs");
7
7
  const cnfast = require("cnfast");
@@ -120,12 +120,12 @@ function PlanBadge({
120
120
  }
121
121
  function usePlanCardRegistration(plan, isWriting) {
122
122
  const scope = todoPlanStore.usePlanScope();
123
- const [seq] = react.useState(todoPlanStore.allocatePlanSeq);
124
- react.useEffect(() => {
123
+ const [seq] = require$$0.useState(todoPlanStore.allocatePlanSeq);
124
+ require$$0.useEffect(() => {
125
125
  todoPlanStore.registerPlanCard(scope, seq, plan, isWriting);
126
126
  return () => todoPlanStore.unregisterPlanCard(scope, seq);
127
127
  }, [scope, seq]);
128
- react.useEffect(() => {
128
+ require$$0.useEffect(() => {
129
129
  todoPlanStore.updatePlanCard(scope, seq, plan, isWriting);
130
130
  }, [scope, seq, plan, isWriting]);
131
131
  return todoPlanStore.useIsLatestPlanCard(scope, seq);
@@ -136,14 +136,14 @@ const HiddenWriteTodosToolUIImpl = ({
136
136
  result,
137
137
  status
138
138
  }) => {
139
- const plan = react.useMemo(
139
+ const plan = require$$0.useMemo(
140
140
  () => parseTodoPlan({ args, argsText, result }),
141
141
  [args, argsText, result]
142
142
  );
143
143
  usePlanCardRegistration(plan, (status == null ? void 0 : status.type) === "running");
144
144
  return null;
145
145
  };
146
- const HiddenWriteTodosToolUI = react.memo(
146
+ const HiddenWriteTodosToolUI = require$$0.memo(
147
147
  HiddenWriteTodosToolUIImpl
148
148
  );
149
149
  HiddenWriteTodosToolUI.displayName = "HiddenWriteTodosToolUI";
@@ -153,12 +153,12 @@ const WriteTodosToolUIImpl = ({
153
153
  result,
154
154
  status
155
155
  }) => {
156
- const plan = react.useMemo(
156
+ const plan = require$$0.useMemo(
157
157
  () => parseTodoPlan({ args, argsText, result }),
158
158
  [args, argsText, result]
159
159
  );
160
160
  const { steps, changeDescription } = plan;
161
- const [collapsed, setCollapsed] = react.useState(false);
161
+ const [collapsed, setCollapsed] = require$$0.useState(false);
162
162
  const isWriting = (status == null ? void 0 : status.type) === "running";
163
163
  const isLatest = usePlanCardRegistration(plan, isWriting);
164
164
  if (!isLatest) return null;
@@ -260,7 +260,7 @@ const WriteTodosToolUIImpl = ({
260
260
  )) })
261
261
  ] });
262
262
  };
263
- const WriteTodosToolUI = react.memo(
263
+ const WriteTodosToolUI = require$$0.memo(
264
264
  WriteTodosToolUIImpl
265
265
  );
266
266
  WriteTodosToolUI.displayName = "WriteTodosToolUI";
@@ -1 +1 @@
1
- {"version":3,"file":"write-todos-tool-ui.cjs","sources":["../../src/tools/write-todos-tool-ui.tsx"],"sourcesContent":["\"use client\";\n\nimport { memo, useEffect, useMemo, useState } from \"react\";\nimport type { ToolCallMessagePartComponent } from \"@assistant-ui/react\";\nimport {\n CheckIcon,\n ChevronDownIcon,\n ListChecksIcon,\n LoaderIcon,\n XIcon,\n} from \"lucide-react\";\nimport { cn } from \"../lib/utils\";\nimport {\n allocatePlanSeq,\n registerPlanCard,\n unregisterPlanCard,\n updatePlanCard,\n useIsLatestPlanCard,\n usePlanScope,\n} from \"./todo-plan-store\";\n\n// ─── Types ───────────────────────────────────────────────────────────\n\nexport type PlanStepStatus =\n | \"pending\"\n | \"in_progress\"\n | \"completed\"\n | \"cancelled\"\n | \"failed\";\n\nexport type PlanStep = {\n id?: string;\n content: string;\n status: PlanStepStatus;\n};\n\nexport type TodoPlan = {\n steps: PlanStep[];\n changeDescription?: string;\n};\n\nconst STEP_STATUSES: readonly PlanStepStatus[] = [\n \"pending\",\n \"in_progress\",\n \"completed\",\n \"cancelled\",\n \"failed\",\n];\n\n// ─── Parsing ─────────────────────────────────────────────────────────\n\nfunction asRecord(value: unknown): Record<string, unknown> | null {\n return typeof value === \"object\" && value !== null\n ? (value as Record<string, unknown>)\n : null;\n}\n\nfunction asStatus(value: unknown): PlanStepStatus {\n return typeof value === \"string\" &&\n (STEP_STATUSES as readonly string[]).includes(value)\n ? (value as PlanStepStatus)\n : \"pending\";\n}\n\nfunction parseSteps(value: unknown): PlanStep[] {\n if (!Array.isArray(value)) return [];\n const steps: PlanStep[] = [];\n for (const raw of value) {\n const record = asRecord(raw);\n if (!record) continue;\n const content = record.content ?? record.task ?? record.title;\n if (typeof content !== \"string\" || content.trim() === \"\") continue;\n steps.push({\n id: typeof record.id === \"string\" ? record.id : undefined,\n content: content.trim(),\n status: asStatus(record.status),\n });\n }\n return steps;\n}\n\nfunction asDescription(value: unknown): string | undefined {\n return typeof value === \"string\" && value.trim() !== \"\"\n ? value.trim()\n : undefined;\n}\n\nfunction parsePartialSteps(argsText: string | undefined): PlanStep[] {\n if (!argsText) return [];\n const steps: PlanStep[] = [];\n const objectPattern = /\\{(?:[^{}\\\\\"]|\"(?:[^\"\\\\]|\\\\.)*\")*\\}?/g;\n for (const [chunk] of argsText.matchAll(objectPattern)) {\n const contentMatch = /\"(?:content|task|title)\"\\s*:\\s*\"((?:[^\"\\\\]|\\\\.)*)\"/.exec(\n chunk,\n );\n if (!contentMatch) continue;\n let content: string;\n try {\n content = JSON.parse(`\"${contentMatch[1]}\"`) as string;\n } catch {\n content = contentMatch[1];\n }\n if (content.trim() === \"\") continue;\n const statusMatch = /\"status\"\\s*:\\s*\"([a-z_]+)\"/.exec(chunk);\n steps.push({\n content: content.trim(),\n status: asStatus(statusMatch?.[1]),\n });\n }\n return steps;\n}\n\nexport function parseTodoPlan({\n args,\n argsText,\n result,\n}: {\n args?: unknown;\n argsText?: string;\n result?: unknown;\n}): TodoPlan {\n const argsRecord = asRecord(args);\n const argSteps = parseSteps(argsRecord?.todos);\n\n let resultRecord = asRecord(result);\n if (!resultRecord && typeof result === \"string\") {\n try {\n resultRecord = asRecord(JSON.parse(result));\n } catch {\n resultRecord = null;\n }\n }\n\n const hasResultTodos = Array.isArray(resultRecord?.todos);\n const steps = hasResultTodos\n ? parseSteps(resultRecord?.todos)\n : argSteps.length > 0\n ? argSteps\n : parsePartialSteps(argsText);\n\n return {\n steps,\n changeDescription:\n asDescription(resultRecord?.description) ??\n asDescription(resultRecord?.todoChangeDescription),\n };\n}\n\n// ─── Presentation ────────────────────────────────────────────────────\n\n/** A plan step's status glyph (its number while pending) — shared with the workbench's Tasks pane. */\nexport function PlanStepMarker({\n status,\n index,\n}: {\n status: PlanStepStatus;\n index: number;\n}) {\n if (status === \"completed\") {\n return (\n <span className=\"flex size-[18px] shrink-0 items-center justify-center rounded-full bg-emerald-500 text-white\">\n <CheckIcon className=\"size-3\" strokeWidth={3} />\n </span>\n );\n }\n if (status === \"in_progress\") {\n return (\n <span className=\"flex size-[18px] shrink-0 items-center justify-center rounded-full bg-primary/10 text-primary\">\n <LoaderIcon className=\"size-3 animate-spin\" strokeWidth={3} />\n </span>\n );\n }\n if (status === \"failed\") {\n return (\n <span className=\"flex size-[18px] shrink-0 items-center justify-center rounded-full bg-destructive/10 text-destructive\">\n <XIcon className=\"size-3\" strokeWidth={3} />\n </span>\n );\n }\n if (status === \"cancelled\") {\n return (\n <span className=\"flex size-[18px] shrink-0 items-center justify-center rounded-full border border-border text-muted-foreground\">\n <XIcon className=\"size-3\" strokeWidth={3} />\n </span>\n );\n }\n return (\n <span className=\"flex size-[18px] shrink-0 items-center justify-center rounded-full border border-dashed border-border text-[9px] font-medium text-muted-foreground\">\n {index + 1}\n </span>\n );\n}\n\nfunction PlanBadge({\n resolved,\n total,\n}: {\n resolved: number;\n total: number;\n}) {\n const isDone = total > 0 && resolved === total;\n\n return (\n <span\n className={cn(\n \"flex size-8 shrink-0 items-center justify-center rounded-lg\",\n isDone && \"bg-emerald-50 text-emerald-600\",\n !isDone && \"bg-primary/10 text-primary\",\n )}\n >\n {isDone ? (\n <CheckIcon className=\"size-4\" strokeWidth={3} />\n ) : (\n <ListChecksIcon className=\"size-4\" />\n )}\n </span>\n );\n}\n\n/**\n * Register this card in its chat's plan registry and report whether it is the\n * newest mounted one. Shared by the visible card (which hides superseded\n * instances) and {@link HiddenWriteTodosToolUI} (which renders nothing but\n * keeps the registry — and so `useLatestTodoPlan` — fed).\n */\nfunction usePlanCardRegistration(plan: TodoPlan, isWriting: boolean): boolean {\n const scope = usePlanScope();\n const [seq] = useState(allocatePlanSeq);\n useEffect(() => {\n registerPlanCard(scope, seq, plan, isWriting);\n return () => unregisterPlanCard(scope, seq);\n // Registration is keyed to this instance's lifetime (and its chat's\n // scope); content updates ride the effect below.\n // eslint-disable-next-line react-hooks/exhaustive-deps\n }, [scope, seq]);\n useEffect(() => {\n updatePlanCard(scope, seq, plan, isWriting);\n }, [scope, seq, plan, isWriting]);\n return useIsLatestPlanCard(scope, seq);\n}\n\n/**\n * Inline-invisible `write_todos` for hosts that pin the plan elsewhere:\n * feeds the plan registry exactly like the visible card, renders nothing.\n * Register it via `toolUIs={{ write_todos: HiddenWriteTodosToolUI }}` and\n * read the plan with `useLatestTodoPlan()` — a bare `() => null` override\n * would leave the registry (and the hook) permanently empty.\n */\nconst HiddenWriteTodosToolUIImpl: ToolCallMessagePartComponent = ({\n args,\n argsText,\n result,\n status,\n}) => {\n const plan = useMemo(\n () => parseTodoPlan({ args, argsText, result }),\n [args, argsText, result],\n );\n usePlanCardRegistration(plan, status?.type === \"running\");\n return null;\n};\n\nexport const HiddenWriteTodosToolUI = memo(\n HiddenWriteTodosToolUIImpl,\n) as unknown as ToolCallMessagePartComponent;\nHiddenWriteTodosToolUI.displayName = \"HiddenWriteTodosToolUI\";\n\nconst WriteTodosToolUIImpl: ToolCallMessagePartComponent = ({\n args,\n argsText,\n result,\n status,\n}) => {\n const plan = useMemo(\n () => parseTodoPlan({ args, argsText, result }),\n [args, argsText, result],\n );\n const { steps, changeDescription } = plan;\n const [collapsed, setCollapsed] = useState(false);\n\n // Newest-plan dedupe: a run updates its plan by calling write_todos again,\n // so a conversation stacks cards that all describe the same plan. Only the\n // newest mounted card in this chat's scope renders (see todo-plan-store.ts).\n const isWriting = status?.type === \"running\";\n const isLatest = usePlanCardRegistration(plan, isWriting);\n if (!isLatest) return null;\n\n const completed = steps.filter((s) => s.status === \"completed\").length;\n const stopped = steps.filter(\n (s) => s.status === \"cancelled\" || s.status === \"failed\",\n ).length;\n const current = steps.find((s) => s.status === \"in_progress\");\n const total = steps.length;\n const resolved = completed + stopped;\n const isDone = total > 0 && resolved === total;\n\n if (total === 0) {\n return isWriting ? (\n <div className=\"my-3 flex w-full items-center gap-2 rounded-xl border border-border/60 bg-background px-4 py-3 shadow-sm\">\n <LoaderIcon className=\"size-3.5 animate-spin text-primary\" />\n <span className=\"text-[13px] font-medium text-foreground\">\n Planning...\n </span>\n </div>\n ) : null;\n }\n\n const heading = isWriting\n ? \"Updating plan\"\n : isDone\n ? \"Plan complete\"\n : completed === 0 && !current\n ? \"Plan\"\n : \"Plan in progress\";\n\n const subtitle =\n changeDescription ?? (current ? current.content : undefined);\n\n return (\n <div className=\"my-3 w-full rounded-xl border border-border/60 bg-background shadow-sm\">\n <div className=\"sticky top-0 z-20 overflow-hidden rounded-t-xl bg-background\">\n <button\n type=\"button\"\n onClick={() => setCollapsed((prev) => !prev)}\n className=\"flex w-full items-center gap-3 px-4 py-3 text-left transition-colors hover:bg-muted/30\"\n aria-expanded={!collapsed}\n >\n <PlanBadge resolved={resolved} total={total} />\n <span className=\"min-w-0 flex-1\">\n <span className=\"flex items-baseline gap-2\">\n <span className=\"text-[13px] font-medium text-foreground\">\n {heading}\n </span>\n <span className=\"text-[11px] tabular-nums text-muted-foreground\">\n {resolved}/{total} steps\n </span>\n </span>\n {subtitle && (\n <span className=\"block truncate text-[12px] text-muted-foreground\">\n {subtitle}\n </span>\n )}\n </span>\n <ChevronDownIcon\n className={cn(\n \"size-4 shrink-0 text-muted-foreground transition-transform duration-200\",\n collapsed && \"-rotate-90\",\n )}\n />\n </button>\n\n <div className=\"h-0.5 w-full bg-muted\">\n <div\n className={cn(\n \"h-full transition-all duration-500\",\n isDone ? \"bg-emerald-500\" : \"bg-primary\",\n )}\n style={{ width: `${total > 0 ? (resolved / total) * 100 : 0}%` }}\n />\n </div>\n </div>\n\n {!collapsed && (\n <ol className=\"flex max-h-72 flex-col overflow-y-auto rounded-b-xl border-t border-border/40 py-1\">\n {steps.map((step, index) => (\n <li\n key={step.id ?? `${index}-${step.content}`}\n className={cn(\n \"relative flex items-start gap-2.5 px-4 py-1.5\",\n step.status === \"in_progress\" && \"bg-primary/5\",\n )}\n >\n {index < steps.length - 1 && (\n <span\n aria-hidden\n className=\"absolute left-[calc(1rem+8px)] top-[26px] h-[calc(100%-18px)] w-px bg-border/60\"\n />\n )}\n <span className=\"relative z-10 mt-[3px]\">\n <PlanStepMarker status={step.status} index={index} />\n </span>\n <span\n className={cn(\n \"text-[12.5px] leading-relaxed text-foreground\",\n step.status === \"completed\" &&\n \"text-muted-foreground line-through decoration-muted-foreground/40\",\n step.status === \"cancelled\" &&\n \"text-muted-foreground/70 line-through decoration-muted-foreground/40\",\n step.status === \"failed\" && \"text-destructive\",\n step.status === \"in_progress\" && \"font-medium text-primary\",\n step.status === \"pending\" && \"text-muted-foreground\",\n )}\n >\n {step.content}\n </span>\n </li>\n ))}\n </ol>\n )}\n </div>\n );\n};\n\nexport const WriteTodosToolUI = memo(\n WriteTodosToolUIImpl,\n) as unknown as ToolCallMessagePartComponent;\nWriteTodosToolUI.displayName = \"WriteTodosToolUI\";\n"],"names":["jsx","CheckIcon","LoaderIcon","XIcon","cn","ListChecksIcon","usePlanScope","useState","allocatePlanSeq","useEffect","registerPlanCard","unregisterPlanCard","updatePlanCard","useIsLatestPlanCard","useMemo","memo","jsxs","ChevronDownIcon"],"mappings":"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"}
1
+ {"version":3,"file":"write-todos-tool-ui.cjs","sources":["../../src/tools/write-todos-tool-ui.tsx"],"sourcesContent":["\"use client\";\n\nimport { memo, useEffect, useMemo, useState } from \"react\";\nimport type { ToolCallMessagePartComponent } from \"@assistant-ui/react\";\nimport {\n CheckIcon,\n ChevronDownIcon,\n ListChecksIcon,\n LoaderIcon,\n XIcon,\n} from \"lucide-react\";\nimport { cn } from \"../lib/utils\";\nimport {\n allocatePlanSeq,\n registerPlanCard,\n unregisterPlanCard,\n updatePlanCard,\n useIsLatestPlanCard,\n usePlanScope,\n} from \"./todo-plan-store\";\n\n// ─── Types ───────────────────────────────────────────────────────────\n\nexport type PlanStepStatus =\n | \"pending\"\n | \"in_progress\"\n | \"completed\"\n | \"cancelled\"\n | \"failed\";\n\nexport type PlanStep = {\n id?: string;\n content: string;\n status: PlanStepStatus;\n};\n\nexport type TodoPlan = {\n steps: PlanStep[];\n changeDescription?: string;\n};\n\nconst STEP_STATUSES: readonly PlanStepStatus[] = [\n \"pending\",\n \"in_progress\",\n \"completed\",\n \"cancelled\",\n \"failed\",\n];\n\n// ─── Parsing ─────────────────────────────────────────────────────────\n\nfunction asRecord(value: unknown): Record<string, unknown> | null {\n return typeof value === \"object\" && value !== null\n ? (value as Record<string, unknown>)\n : null;\n}\n\nfunction asStatus(value: unknown): PlanStepStatus {\n return typeof value === \"string\" &&\n (STEP_STATUSES as readonly string[]).includes(value)\n ? (value as PlanStepStatus)\n : \"pending\";\n}\n\nfunction parseSteps(value: unknown): PlanStep[] {\n if (!Array.isArray(value)) return [];\n const steps: PlanStep[] = [];\n for (const raw of value) {\n const record = asRecord(raw);\n if (!record) continue;\n const content = record.content ?? record.task ?? record.title;\n if (typeof content !== \"string\" || content.trim() === \"\") continue;\n steps.push({\n id: typeof record.id === \"string\" ? record.id : undefined,\n content: content.trim(),\n status: asStatus(record.status),\n });\n }\n return steps;\n}\n\nfunction asDescription(value: unknown): string | undefined {\n return typeof value === \"string\" && value.trim() !== \"\"\n ? value.trim()\n : undefined;\n}\n\nfunction parsePartialSteps(argsText: string | undefined): PlanStep[] {\n if (!argsText) return [];\n const steps: PlanStep[] = [];\n const objectPattern = /\\{(?:[^{}\\\\\"]|\"(?:[^\"\\\\]|\\\\.)*\")*\\}?/g;\n for (const [chunk] of argsText.matchAll(objectPattern)) {\n const contentMatch = /\"(?:content|task|title)\"\\s*:\\s*\"((?:[^\"\\\\]|\\\\.)*)\"/.exec(\n chunk,\n );\n if (!contentMatch) continue;\n let content: string;\n try {\n content = JSON.parse(`\"${contentMatch[1]}\"`) as string;\n } catch {\n content = contentMatch[1];\n }\n if (content.trim() === \"\") continue;\n const statusMatch = /\"status\"\\s*:\\s*\"([a-z_]+)\"/.exec(chunk);\n steps.push({\n content: content.trim(),\n status: asStatus(statusMatch?.[1]),\n });\n }\n return steps;\n}\n\nexport function parseTodoPlan({\n args,\n argsText,\n result,\n}: {\n args?: unknown;\n argsText?: string;\n result?: unknown;\n}): TodoPlan {\n const argsRecord = asRecord(args);\n const argSteps = parseSteps(argsRecord?.todos);\n\n let resultRecord = asRecord(result);\n if (!resultRecord && typeof result === \"string\") {\n try {\n resultRecord = asRecord(JSON.parse(result));\n } catch {\n resultRecord = null;\n }\n }\n\n const hasResultTodos = Array.isArray(resultRecord?.todos);\n const steps = hasResultTodos\n ? parseSteps(resultRecord?.todos)\n : argSteps.length > 0\n ? argSteps\n : parsePartialSteps(argsText);\n\n return {\n steps,\n changeDescription:\n asDescription(resultRecord?.description) ??\n asDescription(resultRecord?.todoChangeDescription),\n };\n}\n\n// ─── Presentation ────────────────────────────────────────────────────\n\n/** A plan step's status glyph (its number while pending) — shared with the workbench's Tasks pane. */\nexport function PlanStepMarker({\n status,\n index,\n}: {\n status: PlanStepStatus;\n index: number;\n}) {\n if (status === \"completed\") {\n return (\n <span className=\"flex size-[18px] shrink-0 items-center justify-center rounded-full bg-emerald-500 text-white\">\n <CheckIcon className=\"size-3\" strokeWidth={3} />\n </span>\n );\n }\n if (status === \"in_progress\") {\n return (\n <span className=\"flex size-[18px] shrink-0 items-center justify-center rounded-full bg-primary/10 text-primary\">\n <LoaderIcon className=\"size-3 animate-spin\" strokeWidth={3} />\n </span>\n );\n }\n if (status === \"failed\") {\n return (\n <span className=\"flex size-[18px] shrink-0 items-center justify-center rounded-full bg-destructive/10 text-destructive\">\n <XIcon className=\"size-3\" strokeWidth={3} />\n </span>\n );\n }\n if (status === \"cancelled\") {\n return (\n <span className=\"flex size-[18px] shrink-0 items-center justify-center rounded-full border border-border text-muted-foreground\">\n <XIcon className=\"size-3\" strokeWidth={3} />\n </span>\n );\n }\n return (\n <span className=\"flex size-[18px] shrink-0 items-center justify-center rounded-full border border-dashed border-border text-[9px] font-medium text-muted-foreground\">\n {index + 1}\n </span>\n );\n}\n\nfunction PlanBadge({\n resolved,\n total,\n}: {\n resolved: number;\n total: number;\n}) {\n const isDone = total > 0 && resolved === total;\n\n return (\n <span\n className={cn(\n \"flex size-8 shrink-0 items-center justify-center rounded-lg\",\n isDone && \"bg-emerald-50 text-emerald-600\",\n !isDone && \"bg-primary/10 text-primary\",\n )}\n >\n {isDone ? (\n <CheckIcon className=\"size-4\" strokeWidth={3} />\n ) : (\n <ListChecksIcon className=\"size-4\" />\n )}\n </span>\n );\n}\n\n/**\n * Register this card in its chat's plan registry and report whether it is the\n * newest mounted one. Shared by the visible card (which hides superseded\n * instances) and {@link HiddenWriteTodosToolUI} (which renders nothing but\n * keeps the registry — and so `useLatestTodoPlan` — fed).\n */\nfunction usePlanCardRegistration(plan: TodoPlan, isWriting: boolean): boolean {\n const scope = usePlanScope();\n const [seq] = useState(allocatePlanSeq);\n useEffect(() => {\n registerPlanCard(scope, seq, plan, isWriting);\n return () => unregisterPlanCard(scope, seq);\n // Registration is keyed to this instance's lifetime (and its chat's\n // scope); content updates ride the effect below.\n // eslint-disable-next-line react-hooks/exhaustive-deps\n }, [scope, seq]);\n useEffect(() => {\n updatePlanCard(scope, seq, plan, isWriting);\n }, [scope, seq, plan, isWriting]);\n return useIsLatestPlanCard(scope, seq);\n}\n\n/**\n * Inline-invisible `write_todos` for hosts that pin the plan elsewhere:\n * feeds the plan registry exactly like the visible card, renders nothing.\n * Register it via `toolUIs={{ write_todos: HiddenWriteTodosToolUI }}` and\n * read the plan with `useLatestTodoPlan()` — a bare `() => null` override\n * would leave the registry (and the hook) permanently empty.\n */\nconst HiddenWriteTodosToolUIImpl: ToolCallMessagePartComponent = ({\n args,\n argsText,\n result,\n status,\n}) => {\n const plan = useMemo(\n () => parseTodoPlan({ args, argsText, result }),\n [args, argsText, result],\n );\n usePlanCardRegistration(plan, status?.type === \"running\");\n return null;\n};\n\nexport const HiddenWriteTodosToolUI = memo(\n HiddenWriteTodosToolUIImpl,\n) as unknown as ToolCallMessagePartComponent;\nHiddenWriteTodosToolUI.displayName = \"HiddenWriteTodosToolUI\";\n\nconst WriteTodosToolUIImpl: ToolCallMessagePartComponent = ({\n args,\n argsText,\n result,\n status,\n}) => {\n const plan = useMemo(\n () => parseTodoPlan({ args, argsText, result }),\n [args, argsText, result],\n );\n const { steps, changeDescription } = plan;\n const [collapsed, setCollapsed] = useState(false);\n\n // Newest-plan dedupe: a run updates its plan by calling write_todos again,\n // so a conversation stacks cards that all describe the same plan. Only the\n // newest mounted card in this chat's scope renders (see todo-plan-store.ts).\n const isWriting = status?.type === \"running\";\n const isLatest = usePlanCardRegistration(plan, isWriting);\n if (!isLatest) return null;\n\n const completed = steps.filter((s) => s.status === \"completed\").length;\n const stopped = steps.filter(\n (s) => s.status === \"cancelled\" || s.status === \"failed\",\n ).length;\n const current = steps.find((s) => s.status === \"in_progress\");\n const total = steps.length;\n const resolved = completed + stopped;\n const isDone = total > 0 && resolved === total;\n\n if (total === 0) {\n return isWriting ? (\n <div className=\"my-3 flex w-full items-center gap-2 rounded-xl border border-border/60 bg-background px-4 py-3 shadow-sm\">\n <LoaderIcon className=\"size-3.5 animate-spin text-primary\" />\n <span className=\"text-[13px] font-medium text-foreground\">\n Planning...\n </span>\n </div>\n ) : null;\n }\n\n const heading = isWriting\n ? \"Updating plan\"\n : isDone\n ? \"Plan complete\"\n : completed === 0 && !current\n ? \"Plan\"\n : \"Plan in progress\";\n\n const subtitle =\n changeDescription ?? (current ? current.content : undefined);\n\n return (\n <div className=\"my-3 w-full rounded-xl border border-border/60 bg-background shadow-sm\">\n <div className=\"sticky top-0 z-20 overflow-hidden rounded-t-xl bg-background\">\n <button\n type=\"button\"\n onClick={() => setCollapsed((prev) => !prev)}\n className=\"flex w-full items-center gap-3 px-4 py-3 text-left transition-colors hover:bg-muted/30\"\n aria-expanded={!collapsed}\n >\n <PlanBadge resolved={resolved} total={total} />\n <span className=\"min-w-0 flex-1\">\n <span className=\"flex items-baseline gap-2\">\n <span className=\"text-[13px] font-medium text-foreground\">\n {heading}\n </span>\n <span className=\"text-[11px] tabular-nums text-muted-foreground\">\n {resolved}/{total} steps\n </span>\n </span>\n {subtitle && (\n <span className=\"block truncate text-[12px] text-muted-foreground\">\n {subtitle}\n </span>\n )}\n </span>\n <ChevronDownIcon\n className={cn(\n \"size-4 shrink-0 text-muted-foreground transition-transform duration-200\",\n collapsed && \"-rotate-90\",\n )}\n />\n </button>\n\n <div className=\"h-0.5 w-full bg-muted\">\n <div\n className={cn(\n \"h-full transition-all duration-500\",\n isDone ? \"bg-emerald-500\" : \"bg-primary\",\n )}\n style={{ width: `${total > 0 ? (resolved / total) * 100 : 0}%` }}\n />\n </div>\n </div>\n\n {!collapsed && (\n <ol className=\"flex max-h-72 flex-col overflow-y-auto rounded-b-xl border-t border-border/40 py-1\">\n {steps.map((step, index) => (\n <li\n key={step.id ?? `${index}-${step.content}`}\n className={cn(\n \"relative flex items-start gap-2.5 px-4 py-1.5\",\n step.status === \"in_progress\" && \"bg-primary/5\",\n )}\n >\n {index < steps.length - 1 && (\n <span\n aria-hidden\n className=\"absolute left-[calc(1rem+8px)] top-[26px] h-[calc(100%-18px)] w-px bg-border/60\"\n />\n )}\n <span className=\"relative z-10 mt-[3px]\">\n <PlanStepMarker status={step.status} index={index} />\n </span>\n <span\n className={cn(\n \"text-[12.5px] leading-relaxed text-foreground\",\n step.status === \"completed\" &&\n \"text-muted-foreground line-through decoration-muted-foreground/40\",\n step.status === \"cancelled\" &&\n \"text-muted-foreground/70 line-through decoration-muted-foreground/40\",\n step.status === \"failed\" && \"text-destructive\",\n step.status === \"in_progress\" && \"font-medium text-primary\",\n step.status === \"pending\" && \"text-muted-foreground\",\n )}\n >\n {step.content}\n </span>\n </li>\n ))}\n </ol>\n )}\n </div>\n );\n};\n\nexport const WriteTodosToolUI = memo(\n WriteTodosToolUIImpl,\n) as unknown as ToolCallMessagePartComponent;\nWriteTodosToolUI.displayName = \"WriteTodosToolUI\";\n"],"names":["jsx","CheckIcon","LoaderIcon","XIcon","cn","ListChecksIcon","usePlanScope","useState","allocatePlanSeq","useEffect","registerPlanCard","unregisterPlanCard","updatePlanCard","useIsLatestPlanCard","useMemo","memo","jsxs","ChevronDownIcon"],"mappings":"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"}
@@ -0,0 +1,382 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, Symbol.toStringTag, { value: "Module" });
3
+ const jsxRuntime = require("react/jsx-runtime");
4
+ const lucideReact = require("lucide-react");
5
+ const require$$0 = require("react");
6
+ const reactDom = require("react-dom");
7
+ const lib_ownerDocument = require("../lib/owner-document.cjs");
8
+ const cnfast = require("cnfast");
9
+ const IMAGE_VIEWER_ZOOM_STEPS = [
10
+ 0.1,
11
+ 0.25,
12
+ 0.33,
13
+ 0.5,
14
+ 0.67,
15
+ 0.75,
16
+ 0.9,
17
+ 1,
18
+ 1.25,
19
+ 1.5,
20
+ 2,
21
+ 3,
22
+ 4
23
+ ];
24
+ const FIT_MARGIN_X_PX = 48;
25
+ const FIT_MARGIN_Y_PX = 120;
26
+ function fitScaleOf({ natural, window }) {
27
+ if (!natural || !window || natural.width <= 0 || natural.height <= 0) return 1;
28
+ const byWidth = (window.width - FIT_MARGIN_X_PX) / natural.width;
29
+ const byHeight = (window.height - FIT_MARGIN_Y_PX) / natural.height;
30
+ return Math.max(0.01, Math.min(1, byWidth, byHeight));
31
+ }
32
+ function nextImageViewerZoom({ scale, direction }) {
33
+ const epsilon = 5e-3;
34
+ if (direction === 1) return IMAGE_VIEWER_ZOOM_STEPS.find((step) => step > scale + epsilon) ?? scale;
35
+ return [...IMAGE_VIEWER_ZOOM_STEPS].reverse().find((step) => step < scale - epsilon) ?? scale;
36
+ }
37
+ function displayName({ image, index, count }) {
38
+ var _a;
39
+ const name = (_a = image.name) == null ? void 0 : _a.trim();
40
+ if (name) return name;
41
+ return count > 1 ? `Image ${index + 1}` : "Image";
42
+ }
43
+ function downloadName({ image, index }) {
44
+ var _a;
45
+ return ((_a = image.name) == null ? void 0 : _a.trim()) || `image-${index + 1}`;
46
+ }
47
+ function imageViewerNeedsFetchedDownload({ src, pageOrigin }) {
48
+ let url;
49
+ try {
50
+ url = new URL(src, pageOrigin);
51
+ } catch {
52
+ return false;
53
+ }
54
+ return (url.protocol === "http:" || url.protocol === "https:") && url.origin !== pageOrigin;
55
+ }
56
+ function saveBlob({ blob, name, doc }) {
57
+ const url = URL.createObjectURL(blob);
58
+ const link = doc.createElement("a");
59
+ link.href = url;
60
+ link.download = name;
61
+ doc.body.appendChild(link);
62
+ link.click();
63
+ link.remove();
64
+ setTimeout(() => URL.revokeObjectURL(url), 0);
65
+ }
66
+ const FOCUSABLE_SELECTOR = 'button:not([disabled]), a[href], [tabindex]:not([tabindex="-1"])';
67
+ const TOOLBAR_BUTTON_CLASS = "inline-flex size-8 shrink-0 items-center justify-center rounded-lg text-white/85 transition-colors hover:bg-white/10 hover:text-white focus-visible:outline-none focus-visible:ring-2 focus-visible:ring-white/70 disabled:pointer-events-none disabled:opacity-35";
68
+ const BACKDROP_STYLE = {
69
+ position: "fixed",
70
+ inset: 0,
71
+ zIndex: 1e3,
72
+ backgroundColor: "rgba(0, 0, 0, 0.82)",
73
+ cursor: "default"
74
+ };
75
+ const VIEWER_STYLE = {
76
+ position: "fixed",
77
+ left: "50%",
78
+ top: "50%",
79
+ transform: "translate(-50%, -50%)",
80
+ zIndex: 1e3,
81
+ display: "flex",
82
+ flexDirection: "column",
83
+ alignItems: "center",
84
+ gap: 12,
85
+ maxWidth: "100vw",
86
+ maxHeight: "100vh",
87
+ padding: 24
88
+ };
89
+ const stopPropagation = (event) => event.stopPropagation();
90
+ function ImageViewer({ images, index, onIndexChange }) {
91
+ const ownerDocument = lib_ownerDocument.useOwnerDocument();
92
+ const open = index !== null && index >= 0 && index < images.length;
93
+ const current = open ? images[index] : void 0;
94
+ const count = images.length;
95
+ const [zoom, setZoom] = require$$0.useState("fit");
96
+ const [natural, setNatural] = require$$0.useState(null);
97
+ const [windowSize, setWindowSize] = require$$0.useState(null);
98
+ const shownSrc = require$$0.useRef(null);
99
+ const imageRef = require$$0.useRef(null);
100
+ const viewerRef = require$$0.useRef(null);
101
+ const handleKeyRef = require$$0.useRef(() => void 0);
102
+ const src = (current == null ? void 0 : current.src) ?? null;
103
+ require$$0.useEffect(() => {
104
+ if (shownSrc.current === src) return;
105
+ shownSrc.current = src;
106
+ setZoom("fit");
107
+ setNatural(null);
108
+ }, [src]);
109
+ require$$0.useEffect(() => {
110
+ const image = imageRef.current;
111
+ if (!src || !image) return void 0;
112
+ const read = () => {
113
+ if (image.naturalWidth > 0) setNatural({ width: image.naturalWidth, height: image.naturalHeight });
114
+ };
115
+ if (image.complete) read();
116
+ image.addEventListener("load", read);
117
+ return () => image.removeEventListener("load", read);
118
+ }, [src]);
119
+ require$$0.useLayoutEffect(() => {
120
+ const view = ownerDocument == null ? void 0 : ownerDocument.defaultView;
121
+ if (!src || !view) return void 0;
122
+ const measure = () => setWindowSize({ width: view.innerWidth, height: view.innerHeight });
123
+ measure();
124
+ view.addEventListener("resize", measure);
125
+ return () => view.removeEventListener("resize", measure);
126
+ }, [ownerDocument, src]);
127
+ require$$0.useEffect(() => {
128
+ var _a, _b;
129
+ if (!open || !ownerDocument) return void 0;
130
+ const previouslyFocused = ownerDocument.activeElement;
131
+ const body = ownerDocument.body;
132
+ const previousOverflow = body.style.overflow;
133
+ body.style.overflow = "hidden";
134
+ (_b = (_a = viewerRef.current) == null ? void 0 : _a.querySelector('[data-slot="image-viewer-close"]')) == null ? void 0 : _b.focus();
135
+ const onKeyDown = (event) => handleKeyRef.current(event);
136
+ ownerDocument.addEventListener("keydown", onKeyDown, true);
137
+ return () => {
138
+ ownerDocument.removeEventListener("keydown", onKeyDown, true);
139
+ body.style.overflow = previousOverflow;
140
+ if (previouslyFocused instanceof HTMLElement && previouslyFocused.isConnected) previouslyFocused.focus();
141
+ };
142
+ }, [open, ownerDocument]);
143
+ const fitScale = fitScaleOf({ natural, window: windowSize });
144
+ const scale = zoom === "fit" ? fitScale : zoom;
145
+ const close = () => onIndexChange(null);
146
+ const show = (next) => {
147
+ if (next >= 0 && next < count) onIndexChange(next);
148
+ };
149
+ const zoomBy = (direction) => setZoom(nextImageViewerZoom({ scale, direction }));
150
+ require$$0.useLayoutEffect(() => {
151
+ handleKeyRef.current = (event) => {
152
+ var _a, _b;
153
+ if (index === null) return;
154
+ const handled = () => {
155
+ event.preventDefault();
156
+ event.stopPropagation();
157
+ };
158
+ if (event.key === "Escape") {
159
+ handled();
160
+ close();
161
+ return;
162
+ }
163
+ if (event.key === "Tab") {
164
+ const focusable = Array.from(((_a = viewerRef.current) == null ? void 0 : _a.querySelectorAll(FOCUSABLE_SELECTOR)) ?? []);
165
+ const first = focusable[0];
166
+ const last = focusable.at(-1);
167
+ if (!first || !last) return;
168
+ const active = ownerDocument == null ? void 0 : ownerDocument.activeElement;
169
+ const inside = active instanceof Node && ((_b = viewerRef.current) == null ? void 0 : _b.contains(active)) === true;
170
+ if (!inside || event.shiftKey && active === first || !event.shiftKey && active === last) {
171
+ handled();
172
+ (event.shiftKey ? last : first).focus();
173
+ }
174
+ return;
175
+ }
176
+ if (event.metaKey || event.ctrlKey || event.altKey) return;
177
+ if (event.key === "ArrowLeft") show(index - 1);
178
+ else if (event.key === "ArrowRight") show(index + 1);
179
+ else if (event.key === "+" || event.key === "=") zoomBy(1);
180
+ else if (event.key === "-" || event.key === "_") zoomBy(-1);
181
+ else if (event.key === "0") setZoom("fit");
182
+ else return;
183
+ handled();
184
+ };
185
+ });
186
+ if (!open || current === void 0 || !ownerDocument) return null;
187
+ const percent = `${Math.round(scale * 100)}%`;
188
+ const name = displayName({ image: current, index, count });
189
+ const fileName = downloadName({ image: current, index });
190
+ const hasPrevious = index > 0;
191
+ const hasNext = index < count - 1;
192
+ const handleDownload = (event) => {
193
+ var _a;
194
+ const pageOrigin = ((_a = ownerDocument.defaultView) == null ? void 0 : _a.location.origin) ?? "";
195
+ if (!imageViewerNeedsFetchedDownload({ src: current.src, pageOrigin })) return;
196
+ event.preventDefault();
197
+ const view = ownerDocument.defaultView;
198
+ void fetch(current.src).then((response) => {
199
+ if (!response.ok) throw new Error(`HTTP ${response.status}`);
200
+ return response.blob();
201
+ }).then((blob) => saveBlob({ blob, name: fileName, doc: ownerDocument })).catch(() => {
202
+ view == null ? void 0 : view.open(current.src, "_blank", "noopener,noreferrer");
203
+ });
204
+ };
205
+ const imageStyle = zoom !== "fit" && natural ? { width: natural.width * zoom, height: natural.height * zoom, maxWidth: "none", maxHeight: "none" } : void 0;
206
+ return reactDom.createPortal(
207
+ // The SDK's scope classes bring its scoped reset to the portaled tree;
208
+ // `display: contents` leaves the layout to the fixed layers below.
209
+ /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "athena-sdk athena-sdk-chrome", "data-slot": "image-viewer", children: [
210
+ /* @__PURE__ */ jsxRuntime.jsx(
211
+ "button",
212
+ {
213
+ type: "button",
214
+ tabIndex: -1,
215
+ "aria-label": "Close the image viewer",
216
+ onClick: close,
217
+ className: "animate-in fade-in-0 duration-150 motion-reduce:animate-none",
218
+ style: BACKDROP_STYLE,
219
+ "data-slot": "image-viewer-backdrop"
220
+ }
221
+ ),
222
+ /* @__PURE__ */ jsxRuntime.jsxs(
223
+ "div",
224
+ {
225
+ ref: viewerRef,
226
+ role: "dialog",
227
+ "aria-modal": "true",
228
+ "aria-label": name,
229
+ style: VIEWER_STYLE,
230
+ onClick: stopPropagation,
231
+ onPointerDown: stopPropagation,
232
+ onKeyDown: stopPropagation,
233
+ onFocus: stopPropagation,
234
+ onBlur: stopPropagation,
235
+ children: [
236
+ /* @__PURE__ */ jsxRuntime.jsx(
237
+ "div",
238
+ {
239
+ "data-slot": "image-viewer-stage",
240
+ className: "max-h-[calc(100vh-7.5rem)] max-w-[calc(100vw-3rem)] overflow-auto rounded-sm shadow-2xl",
241
+ children: /* @__PURE__ */ jsxRuntime.jsx(
242
+ "img",
243
+ {
244
+ ref: imageRef,
245
+ src: current.src,
246
+ alt: name,
247
+ draggable: false,
248
+ "data-slot": "image-viewer-image",
249
+ style: imageStyle,
250
+ className: cnfast.cn(
251
+ "block select-none",
252
+ zoom === "fit" && "max-h-[calc(100vh-7.5rem)] max-w-[calc(100vw-3rem)] object-contain"
253
+ )
254
+ },
255
+ current.src
256
+ )
257
+ }
258
+ ),
259
+ /* @__PURE__ */ jsxRuntime.jsx("div", { className: "flex max-w-full shrink-0 justify-center", children: /* @__PURE__ */ jsxRuntime.jsxs(
260
+ "div",
261
+ {
262
+ role: "toolbar",
263
+ "aria-label": "Image viewer",
264
+ className: "flex max-w-full items-center gap-0.5 rounded-xl bg-neutral-900/95 p-1 text-sm text-white shadow-lg ring-1 ring-white/10",
265
+ children: [
266
+ count > 1 ? /* @__PURE__ */ jsxRuntime.jsxs(jsxRuntime.Fragment, { children: [
267
+ /* @__PURE__ */ jsxRuntime.jsx(
268
+ "button",
269
+ {
270
+ type: "button",
271
+ className: TOOLBAR_BUTTON_CLASS,
272
+ onClick: () => show(index - 1),
273
+ disabled: !hasPrevious,
274
+ "aria-label": "Previous image",
275
+ title: "Previous (←)",
276
+ children: /* @__PURE__ */ jsxRuntime.jsx(lucideReact.ChevronLeftIcon, { className: "size-4" })
277
+ }
278
+ ),
279
+ /* @__PURE__ */ jsxRuntime.jsx(
280
+ "button",
281
+ {
282
+ type: "button",
283
+ className: TOOLBAR_BUTTON_CLASS,
284
+ onClick: () => show(index + 1),
285
+ disabled: !hasNext,
286
+ "aria-label": "Next image",
287
+ title: "Next (→)",
288
+ children: /* @__PURE__ */ jsxRuntime.jsx(lucideReact.ChevronRightIcon, { className: "size-4" })
289
+ }
290
+ )
291
+ ] }) : null,
292
+ /* @__PURE__ */ jsxRuntime.jsx(
293
+ "span",
294
+ {
295
+ className: "min-w-0 max-w-[40vw] truncate px-2 font-medium text-white/90",
296
+ title: name,
297
+ "data-slot": "image-viewer-name",
298
+ children: name
299
+ }
300
+ ),
301
+ count > 1 ? /* @__PURE__ */ jsxRuntime.jsxs("span", { className: "shrink-0 pr-2 text-white/50 tabular-nums", "data-slot": "image-viewer-position", children: [
302
+ index + 1,
303
+ " / ",
304
+ count
305
+ ] }) : null,
306
+ /* @__PURE__ */ jsxRuntime.jsx("span", { "aria-hidden": "true", className: "mx-1 h-5 w-px shrink-0 bg-white/15" }),
307
+ /* @__PURE__ */ jsxRuntime.jsx(
308
+ "button",
309
+ {
310
+ type: "button",
311
+ className: TOOLBAR_BUTTON_CLASS,
312
+ onClick: () => zoomBy(-1),
313
+ disabled: scale <= (IMAGE_VIEWER_ZOOM_STEPS[0] ?? 0) + 5e-3,
314
+ "aria-label": "Zoom out",
315
+ title: "Zoom out (−)",
316
+ children: /* @__PURE__ */ jsxRuntime.jsx(lucideReact.MinusIcon, { className: "size-4" })
317
+ }
318
+ ),
319
+ /* @__PURE__ */ jsxRuntime.jsx(
320
+ "button",
321
+ {
322
+ type: "button",
323
+ className: cnfast.cn(TOOLBAR_BUTTON_CLASS, "w-auto min-w-12 px-1.5 text-xs tabular-nums"),
324
+ onClick: () => setZoom("fit"),
325
+ "aria-label": `Zoom ${percent}, fit to window`,
326
+ title: "Fit to window (0)",
327
+ "data-slot": "image-viewer-zoom",
328
+ children: percent
329
+ }
330
+ ),
331
+ /* @__PURE__ */ jsxRuntime.jsx(
332
+ "button",
333
+ {
334
+ type: "button",
335
+ className: TOOLBAR_BUTTON_CLASS,
336
+ onClick: () => zoomBy(1),
337
+ disabled: scale >= (IMAGE_VIEWER_ZOOM_STEPS.at(-1) ?? 4) - 5e-3,
338
+ "aria-label": "Zoom in",
339
+ title: "Zoom in (+)",
340
+ children: /* @__PURE__ */ jsxRuntime.jsx(lucideReact.PlusIcon, { className: "size-4" })
341
+ }
342
+ ),
343
+ /* @__PURE__ */ jsxRuntime.jsx("span", { "aria-hidden": "true", className: "mx-1 h-5 w-px shrink-0 bg-white/15" }),
344
+ /* @__PURE__ */ jsxRuntime.jsx(
345
+ "a",
346
+ {
347
+ href: current.src,
348
+ download: fileName,
349
+ onClick: handleDownload,
350
+ className: TOOLBAR_BUTTON_CLASS,
351
+ "aria-label": "Download",
352
+ title: "Download",
353
+ children: /* @__PURE__ */ jsxRuntime.jsx(lucideReact.DownloadIcon, { className: "size-4" })
354
+ }
355
+ ),
356
+ /* @__PURE__ */ jsxRuntime.jsx(
357
+ "button",
358
+ {
359
+ type: "button",
360
+ className: TOOLBAR_BUTTON_CLASS,
361
+ onClick: close,
362
+ "aria-label": "Close",
363
+ title: "Close (Esc)",
364
+ "data-slot": "image-viewer-close",
365
+ children: /* @__PURE__ */ jsxRuntime.jsx(lucideReact.XIcon, { className: "size-4" })
366
+ }
367
+ )
368
+ ]
369
+ }
370
+ ) })
371
+ ]
372
+ }
373
+ )
374
+ ] }),
375
+ ownerDocument.body
376
+ );
377
+ }
378
+ exports.IMAGE_VIEWER_ZOOM_STEPS = IMAGE_VIEWER_ZOOM_STEPS;
379
+ exports.ImageViewer = ImageViewer;
380
+ exports.imageViewerNeedsFetchedDownload = imageViewerNeedsFetchedDownload;
381
+ exports.nextImageViewerZoom = nextImageViewerZoom;
382
+ //# sourceMappingURL=image-viewer.cjs.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"image-viewer.cjs","sources":["../../src/ui/image-viewer.tsx"],"sourcesContent":["\"use client\"\n\nimport {\n ChevronLeftIcon,\n ChevronRightIcon,\n DownloadIcon,\n MinusIcon,\n PlusIcon,\n XIcon,\n} from \"lucide-react\"\nimport type { CSSProperties, MouseEvent, ReactNode, SyntheticEvent } from \"react\"\nimport { useEffect, useLayoutEffect, useRef, useState } from \"react\"\nimport { createPortal } from \"react-dom\"\nimport { useOwnerDocument } from \"../lib/owner-document\"\nimport { cn } from \"../lib/utils\"\n\n/** One picture the viewer can show. */\nexport interface ImageViewerImage {\n /** What the image loads: an http(s), `blob:` or `data:` URL. */\n src: string\n /** Its file name: the toolbar's label and the download's name. */\n name?: string\n}\n\nexport interface ImageViewerProps {\n /** The pictures the viewer pages through, in order. */\n images: readonly ImageViewerImage[]\n /** The picture on screen, or `null` while the viewer is closed. */\n index: number | null\n /** Called with the picture to show next, or `null` to close the viewer. */\n onIndexChange: (index: number | null) => void\n}\n\n/** The scale factors the zoom buttons step between. */\nexport const IMAGE_VIEWER_ZOOM_STEPS: readonly number[] = [\n 0.1, 0.25, 0.33, 0.5, 0.67, 0.75, 0.9, 1, 1.25, 1.5, 2, 3, 4,\n]\n\n/** The room a fitted picture leaves in the window: the viewer's padding, and the toolbar below it. */\nconst FIT_MARGIN_X_PX = 48\nconst FIT_MARGIN_Y_PX = 120\n\ntype Zoom = \"fit\" | number\n\ninterface NaturalSize {\n width: number\n height: number\n}\n\n/** The scale that fits `natural` in the `window`, never above 100%. */\nfunction fitScaleOf({ natural, window }: { natural: NaturalSize | null; window: NaturalSize | null }): number {\n if (!natural || !window || natural.width <= 0 || natural.height <= 0) return 1\n const byWidth = (window.width - FIT_MARGIN_X_PX) / natural.width\n const byHeight = (window.height - FIT_MARGIN_Y_PX) / natural.height\n return Math.max(0.01, Math.min(1, byWidth, byHeight))\n}\n\n/** The next zoom step past `scale`, in `direction`; `scale` itself at either end. */\nexport function nextImageViewerZoom({ scale, direction }: { scale: number; direction: 1 | -1 }): number {\n const epsilon = 0.005\n if (direction === 1) return IMAGE_VIEWER_ZOOM_STEPS.find((step) => step > scale + epsilon) ?? scale\n return [...IMAGE_VIEWER_ZOOM_STEPS].reverse().find((step) => step < scale - epsilon) ?? scale\n}\n\n/** A picture's name for people: its file name, else its place in the set. */\nfunction displayName({ image, index, count }: { image: ImageViewerImage; index: number; count: number }): string {\n const name = image.name?.trim()\n if (name) return name\n return count > 1 ? `Image ${index + 1}` : \"Image\"\n}\n\n/** What a download saves the picture as. */\nfunction downloadName({ image, index }: { image: ImageViewerImage; index: number }): string {\n return image.name?.trim() || `image-${index + 1}`\n}\n\n/**\n * Whether the browser would ignore a link's `download` for `src`: an http(s)\n * address on another origin, which it opens instead of saving unless the\n * server sends it as an attachment. `data:`, `blob:` and same-origin pictures\n * download as they are.\n */\nexport function imageViewerNeedsFetchedDownload({ src, pageOrigin }: { src: string; pageOrigin: string }): boolean {\n let url: URL\n try {\n url = new URL(src, pageOrigin)\n } catch {\n return false\n }\n return (url.protocol === \"http:\" || url.protocol === \"https:\") && url.origin !== pageOrigin\n}\n\n/** Saves `blob` as `name` through a link in `doc`, then frees it. */\nfunction saveBlob({ blob, name, doc }: { blob: Blob; name: string; doc: Document }): void {\n const url = URL.createObjectURL(blob)\n const link = doc.createElement(\"a\")\n link.href = url\n link.download = name\n doc.body.appendChild(link)\n link.click()\n link.remove()\n // The click has started the download by the time the next task runs.\n setTimeout(() => URL.revokeObjectURL(url), 0)\n}\n\nconst FOCUSABLE_SELECTOR = 'button:not([disabled]), a[href], [tabindex]:not([tabindex=\"-1\"])'\n\nconst TOOLBAR_BUTTON_CLASS =\n \"inline-flex size-8 shrink-0 items-center justify-center rounded-lg text-white/85 transition-colors hover:bg-white/10 hover:text-white focus-visible:outline-none focus-visible:ring-2 focus-visible:ring-white/70 disabled:pointer-events-none disabled:opacity-35\"\n\n// The backdrop and the viewer carry their box inline: no host stylesheet can\n// take a full-screen viewer's position away (see lib/portal-surface.ts).\nconst BACKDROP_STYLE: CSSProperties = {\n position: \"fixed\",\n inset: 0,\n zIndex: 1000,\n backgroundColor: \"rgba(0, 0, 0, 0.82)\",\n cursor: \"default\",\n}\nconst VIEWER_STYLE: CSSProperties = {\n position: \"fixed\",\n left: \"50%\",\n top: \"50%\",\n transform: \"translate(-50%, -50%)\",\n zIndex: 1000,\n display: \"flex\",\n flexDirection: \"column\",\n alignItems: \"center\",\n gap: 12,\n maxWidth: \"100vw\",\n maxHeight: \"100vh\",\n padding: 24,\n}\n\nconst stopPropagation = (event: SyntheticEvent) => event.stopPropagation()\n\n/**\n * A full-screen look at a picture, as Devin opens an attached image: the page\n * dims, the picture fits the window, and a toolbar below it pages through the\n * set, names the file, zooms, downloads and closes.\n *\n * Keys: ← and → page through the set, + and − zoom, 0 fits the window again,\n * Esc closes; Tab stays inside the viewer. A click on the dimmed backdrop\n * (outside the picture and its toolbar) closes too.\n *\n * A modal dialog of its own, not Radix's: it is the SDK's only dialog, and the\n * Office add-in's bundle budget has no room for Radix's focus scope and scroll\n * lock. It portals into the document its host renders in (popouts included),\n * focuses its close button, locks the page's scroll and gives focus back when\n * it closes, and keeps its events to itself so a click or a focus in it never\n * reaches the composer or the message it was opened from.\n */\nexport function ImageViewer({ images, index, onIndexChange }: ImageViewerProps): ReactNode {\n const ownerDocument = useOwnerDocument()\n const open = index !== null && index >= 0 && index < images.length\n const current = open ? images[index] : undefined\n const count = images.length\n\n const [zoom, setZoom] = useState<Zoom>(\"fit\")\n const [natural, setNatural] = useState<NaturalSize | null>(null)\n const [windowSize, setWindowSize] = useState<NaturalSize | null>(null)\n const shownSrc = useRef<string | null>(null)\n const imageRef = useRef<HTMLImageElement | null>(null)\n const viewerRef = useRef<HTMLDivElement | null>(null)\n const handleKeyRef = useRef<(event: KeyboardEvent) => void>(() => undefined)\n\n // Each picture opens fitted, measured afresh once it loads.\n const src = current?.src ?? null\n useEffect(() => {\n if (shownSrc.current === src) return\n shownSrc.current = src\n setZoom(\"fit\")\n setNatural(null)\n }, [src])\n\n // The picture's own size, once it has loaded, for the scale the toolbar shows.\n useEffect(() => {\n const image = imageRef.current\n if (!src || !image) return undefined\n const read = () => {\n if (image.naturalWidth > 0) setNatural({ width: image.naturalWidth, height: image.naturalHeight })\n }\n if (image.complete) read()\n image.addEventListener(\"load\", read)\n return () => image.removeEventListener(\"load\", read)\n }, [src])\n\n // The window the viewer fills, for the fitted scale it reports.\n useLayoutEffect(() => {\n const view = ownerDocument?.defaultView\n if (!src || !view) return undefined\n const measure = () => setWindowSize({ width: view.innerWidth, height: view.innerHeight })\n measure()\n view.addEventListener(\"resize\", measure)\n return () => view.removeEventListener(\"resize\", measure)\n }, [ownerDocument, src])\n\n // Opening takes the keyboard and the page's scroll; closing gives both back,\n // with focus on whatever had it before (the thumbnail that opened it).\n useEffect(() => {\n if (!open || !ownerDocument) return undefined\n const previouslyFocused = ownerDocument.activeElement\n const body = ownerDocument.body\n const previousOverflow = body.style.overflow\n body.style.overflow = \"hidden\"\n viewerRef.current?.querySelector<HTMLElement>('[data-slot=\"image-viewer-close\"]')?.focus()\n const onKeyDown = (event: KeyboardEvent) => handleKeyRef.current(event)\n ownerDocument.addEventListener(\"keydown\", onKeyDown, true)\n return () => {\n ownerDocument.removeEventListener(\"keydown\", onKeyDown, true)\n body.style.overflow = previousOverflow\n if (previouslyFocused instanceof HTMLElement && previouslyFocused.isConnected) previouslyFocused.focus()\n }\n }, [open, ownerDocument])\n\n const fitScale = fitScaleOf({ natural, window: windowSize })\n const scale = zoom === \"fit\" ? fitScale : zoom\n const close = () => onIndexChange(null)\n const show = (next: number) => {\n if (next >= 0 && next < count) onIndexChange(next)\n }\n const zoomBy = (direction: 1 | -1) => setZoom(nextImageViewerZoom({ scale, direction }))\n\n // Read at key time from the latest render (the listener above is bound once per opening).\n useLayoutEffect(() => {\n handleKeyRef.current = (event) => {\n if (index === null) return\n const handled = () => {\n event.preventDefault()\n event.stopPropagation()\n }\n if (event.key === \"Escape\") {\n handled()\n close()\n return\n }\n if (event.key === \"Tab\") {\n const focusable = Array.from(viewerRef.current?.querySelectorAll<HTMLElement>(FOCUSABLE_SELECTOR) ?? [])\n const first = focusable[0]\n const last = focusable.at(-1)\n if (!first || !last) return\n const active = ownerDocument?.activeElement\n const inside = active instanceof Node && viewerRef.current?.contains(active) === true\n if (!inside || (event.shiftKey && active === first) || (!event.shiftKey && active === last)) {\n handled()\n ;(event.shiftKey ? last : first).focus()\n }\n return\n }\n if (event.metaKey || event.ctrlKey || event.altKey) return\n if (event.key === \"ArrowLeft\") show(index - 1)\n else if (event.key === \"ArrowRight\") show(index + 1)\n else if (event.key === \"+\" || event.key === \"=\") zoomBy(1)\n else if (event.key === \"-\" || event.key === \"_\") zoomBy(-1)\n else if (event.key === \"0\") setZoom(\"fit\")\n else return\n handled()\n }\n })\n\n if (!open || current === undefined || !ownerDocument) return null\n\n const percent = `${Math.round(scale * 100)}%`\n const name = displayName({ image: current, index, count })\n const fileName = downloadName({ image: current, index })\n const hasPrevious = index > 0\n const hasNext = index < count - 1\n\n // A picture from another origin downloads through a fetched copy: the\n // browser would open it in a tab instead of saving it.\n const handleDownload = (event: MouseEvent<HTMLAnchorElement>) => {\n const pageOrigin = ownerDocument.defaultView?.location.origin ?? \"\"\n if (!imageViewerNeedsFetchedDownload({ src: current.src, pageOrigin })) return\n event.preventDefault()\n const view = ownerDocument.defaultView\n void fetch(current.src)\n .then((response) => {\n if (!response.ok) throw new Error(`HTTP ${response.status}`)\n return response.blob()\n })\n .then((blob) => saveBlob({ blob, name: fileName, doc: ownerDocument }))\n .catch(() => {\n // Unreadable here (no CORS): the browser's own view of it is the fallback.\n view?.open(current.src, \"_blank\", \"noopener,noreferrer\")\n })\n }\n\n const imageStyle: CSSProperties | undefined =\n zoom !== \"fit\" && natural\n ? { width: natural.width * zoom, height: natural.height * zoom, maxWidth: \"none\", maxHeight: \"none\" }\n : undefined\n\n return createPortal(\n // The SDK's scope classes bring its scoped reset to the portaled tree;\n // `display: contents` leaves the layout to the fixed layers below.\n <div className=\"athena-sdk athena-sdk-chrome\" data-slot=\"image-viewer\">\n <button\n type=\"button\"\n tabIndex={-1}\n aria-label=\"Close the image viewer\"\n onClick={close}\n className=\"animate-in fade-in-0 duration-150 motion-reduce:animate-none\"\n style={BACKDROP_STYLE}\n data-slot=\"image-viewer-backdrop\"\n />\n {/* The event boundary: a click, a focus or a key in the viewer bubbles\n through React to the component that opened it (a portal keeps its\n React parent), so it stops here. */}\n {/* biome-ignore lint/a11y/noNoninteractiveElementInteractions: an event boundary for the portaled dialog, not a control */}\n <div\n ref={viewerRef}\n role=\"dialog\"\n aria-modal=\"true\"\n aria-label={name}\n style={VIEWER_STYLE}\n onClick={stopPropagation}\n onPointerDown={stopPropagation}\n onKeyDown={stopPropagation}\n onFocus={stopPropagation}\n onBlur={stopPropagation}\n >\n {/* Fitted, the picture fills the window but the toolbar's room;\n zoomed past it, the picture scrolls inside that same box. */}\n <div\n data-slot=\"image-viewer-stage\"\n className=\"max-h-[calc(100vh-7.5rem)] max-w-[calc(100vw-3rem)] overflow-auto rounded-sm shadow-2xl\"\n >\n <img\n key={current.src}\n ref={imageRef}\n src={current.src}\n alt={name}\n draggable={false}\n data-slot=\"image-viewer-image\"\n style={imageStyle}\n className={cn(\n \"block select-none\",\n zoom === \"fit\" && \"max-h-[calc(100vh-7.5rem)] max-w-[calc(100vw-3rem)] object-contain\",\n )}\n />\n </div>\n <div className=\"flex max-w-full shrink-0 justify-center\">\n <div\n role=\"toolbar\"\n aria-label=\"Image viewer\"\n className=\"flex max-w-full items-center gap-0.5 rounded-xl bg-neutral-900/95 p-1 text-sm text-white shadow-lg ring-1 ring-white/10\"\n >\n {count > 1 ? (\n <>\n <button\n type=\"button\"\n className={TOOLBAR_BUTTON_CLASS}\n onClick={() => show(index - 1)}\n disabled={!hasPrevious}\n aria-label=\"Previous image\"\n title=\"Previous (←)\"\n >\n <ChevronLeftIcon className=\"size-4\" />\n </button>\n <button\n type=\"button\"\n className={TOOLBAR_BUTTON_CLASS}\n onClick={() => show(index + 1)}\n disabled={!hasNext}\n aria-label=\"Next image\"\n title=\"Next (→)\"\n >\n <ChevronRightIcon className=\"size-4\" />\n </button>\n </>\n ) : null}\n <span\n className=\"min-w-0 max-w-[40vw] truncate px-2 font-medium text-white/90\"\n title={name}\n data-slot=\"image-viewer-name\"\n >\n {name}\n </span>\n {count > 1 ? (\n <span className=\"shrink-0 pr-2 text-white/50 tabular-nums\" data-slot=\"image-viewer-position\">\n {index + 1} / {count}\n </span>\n ) : null}\n <span aria-hidden=\"true\" className=\"mx-1 h-5 w-px shrink-0 bg-white/15\" />\n <button\n type=\"button\"\n className={TOOLBAR_BUTTON_CLASS}\n onClick={() => zoomBy(-1)}\n disabled={scale <= (IMAGE_VIEWER_ZOOM_STEPS[0] ?? 0) + 0.005}\n aria-label=\"Zoom out\"\n title=\"Zoom out (−)\"\n >\n <MinusIcon className=\"size-4\" />\n </button>\n <button\n type=\"button\"\n className={cn(TOOLBAR_BUTTON_CLASS, \"w-auto min-w-12 px-1.5 text-xs tabular-nums\")}\n onClick={() => setZoom(\"fit\")}\n aria-label={`Zoom ${percent}, fit to window`}\n title=\"Fit to window (0)\"\n data-slot=\"image-viewer-zoom\"\n >\n {percent}\n </button>\n <button\n type=\"button\"\n className={TOOLBAR_BUTTON_CLASS}\n onClick={() => zoomBy(1)}\n disabled={scale >= (IMAGE_VIEWER_ZOOM_STEPS.at(-1) ?? 4) - 0.005}\n aria-label=\"Zoom in\"\n title=\"Zoom in (+)\"\n >\n <PlusIcon className=\"size-4\" />\n </button>\n <span aria-hidden=\"true\" className=\"mx-1 h-5 w-px shrink-0 bg-white/15\" />\n <a\n href={current.src}\n download={fileName}\n onClick={handleDownload}\n className={TOOLBAR_BUTTON_CLASS}\n aria-label=\"Download\"\n title=\"Download\"\n >\n <DownloadIcon className=\"size-4\" />\n </a>\n <button\n type=\"button\"\n className={TOOLBAR_BUTTON_CLASS}\n onClick={close}\n aria-label=\"Close\"\n title=\"Close (Esc)\"\n data-slot=\"image-viewer-close\"\n >\n <XIcon className=\"size-4\" />\n </button>\n </div>\n </div>\n </div>\n </div>,\n ownerDocument.body,\n )\n}\n"],"names":["useOwnerDocument","useState","useRef","useEffect","useLayoutEffect","createPortal","jsxs","jsx","cn","Fragment","ChevronLeftIcon","ChevronRightIcon","MinusIcon","PlusIcon","DownloadIcon","XIcon"],"mappings":"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"}