@athenaintel/react 0.41.2 → 0.42.1

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 (451) hide show
  1. package/README.md +108 -9
  2. package/dist/agent-runtime/src/asset-attachment.d.ts +98 -0
  3. package/dist/agent-runtime/src/athena-asset-drag.d.ts +32 -0
  4. package/dist/agent-runtime/src/auth-denial.d.ts +29 -0
  5. package/dist/agent-runtime/src/chat-outbox-attachments.cjs +41 -0
  6. package/dist/agent-runtime/src/chat-outbox-attachments.cjs.map +1 -0
  7. package/dist/agent-runtime/src/chat-outbox-attachments.d.ts +38 -0
  8. package/dist/agent-runtime/src/chat-outbox-attachments.js +41 -0
  9. package/dist/agent-runtime/src/chat-outbox-attachments.js.map +1 -0
  10. package/dist/agent-runtime/src/chat-outbox-signals.cjs +63 -0
  11. package/dist/agent-runtime/src/chat-outbox-signals.cjs.map +1 -0
  12. package/dist/agent-runtime/src/chat-outbox-signals.d.ts +12 -0
  13. package/dist/agent-runtime/src/chat-outbox-signals.js +63 -0
  14. package/dist/agent-runtime/src/chat-outbox-signals.js.map +1 -0
  15. package/dist/agent-runtime/src/chat-outbox-store.cjs +509 -0
  16. package/dist/agent-runtime/src/chat-outbox-store.cjs.map +1 -0
  17. package/dist/agent-runtime/src/chat-outbox-store.d.ts +203 -0
  18. package/dist/agent-runtime/src/chat-outbox-store.js +509 -0
  19. package/dist/agent-runtime/src/chat-outbox-store.js.map +1 -0
  20. package/dist/agent-runtime/src/chat-outbox-thread.cjs +136 -0
  21. package/dist/agent-runtime/src/chat-outbox-thread.cjs.map +1 -0
  22. package/dist/agent-runtime/src/chat-outbox-thread.d.ts +118 -0
  23. package/dist/agent-runtime/src/chat-outbox-thread.js +136 -0
  24. package/dist/agent-runtime/src/chat-outbox-thread.js.map +1 -0
  25. package/dist/agent-runtime/src/chat-outbox.cjs +696 -0
  26. package/dist/agent-runtime/src/chat-outbox.cjs.map +1 -0
  27. package/dist/agent-runtime/src/chat-outbox.d.ts +285 -0
  28. package/dist/agent-runtime/src/chat-outbox.js +696 -0
  29. package/dist/agent-runtime/src/chat-outbox.js.map +1 -0
  30. package/dist/agent-runtime/src/chat-socket-reachability.d.ts +45 -0
  31. package/dist/agent-runtime/src/client-tool-bridge.d.ts +152 -0
  32. package/dist/agent-runtime/src/client-tools.d.ts +133 -0
  33. package/dist/agent-runtime/src/composer-markdown.cjs +10 -0
  34. package/dist/agent-runtime/src/composer-markdown.cjs.map +1 -1
  35. package/dist/agent-runtime/src/composer-markdown.d.ts +108 -0
  36. package/dist/agent-runtime/src/composer-markdown.js +10 -0
  37. package/dist/agent-runtime/src/composer-markdown.js.map +1 -1
  38. package/dist/agent-runtime/src/config-mutations.d.ts +51 -0
  39. package/dist/agent-runtime/src/conversation-index.d.ts +110 -0
  40. package/dist/agent-runtime/src/conversation-list.d.ts +343 -0
  41. package/dist/agent-runtime/src/deep-agent-transport-recipe.cjs +3 -2
  42. package/dist/agent-runtime/src/deep-agent-transport-recipe.cjs.map +1 -1
  43. package/dist/agent-runtime/src/deep-agent-transport-recipe.d.ts +166 -0
  44. package/dist/agent-runtime/src/deep-agent-transport-recipe.js +3 -2
  45. package/dist/agent-runtime/src/deep-agent-transport-recipe.js.map +1 -1
  46. package/dist/agent-runtime/src/desktop-handoff.d.ts +139 -0
  47. package/dist/agent-runtime/src/durable-thread-snapshot-cache.cjs +158 -0
  48. package/dist/agent-runtime/src/durable-thread-snapshot-cache.cjs.map +1 -0
  49. package/dist/agent-runtime/src/durable-thread-snapshot-cache.d.ts +60 -0
  50. package/dist/agent-runtime/src/durable-thread-snapshot-cache.js +158 -0
  51. package/dist/agent-runtime/src/durable-thread-snapshot-cache.js.map +1 -0
  52. package/dist/agent-runtime/src/edit-command.d.ts +156 -0
  53. package/dist/agent-runtime/src/errors.d.ts +174 -0
  54. package/dist/agent-runtime/src/execute-output.d.ts +31 -0
  55. package/dist/agent-runtime/src/generated/runconfig-contract.cjs +16 -2
  56. package/dist/agent-runtime/src/generated/runconfig-contract.cjs.map +1 -1
  57. package/dist/agent-runtime/src/generated/runconfig-contract.d.ts +202 -0
  58. package/dist/agent-runtime/src/generated/runconfig-contract.js +16 -2
  59. package/dist/agent-runtime/src/generated/runconfig-contract.js.map +1 -1
  60. package/dist/agent-runtime/src/github-wake-event.d.ts +77 -0
  61. package/dist/agent-runtime/src/index.d.ts +74 -0
  62. package/dist/agent-runtime/src/interrupts.cjs +17 -0
  63. package/dist/agent-runtime/src/interrupts.cjs.map +1 -1
  64. package/dist/agent-runtime/src/interrupts.d.ts +348 -0
  65. package/dist/agent-runtime/src/interrupts.js +17 -0
  66. package/dist/agent-runtime/src/interrupts.js.map +1 -1
  67. package/dist/agent-runtime/src/lane-follow.d.ts +121 -0
  68. package/dist/agent-runtime/src/lane-history.cjs +209 -0
  69. package/dist/agent-runtime/src/lane-history.cjs.map +1 -0
  70. package/dist/agent-runtime/src/lane-history.d.ts +175 -0
  71. package/dist/agent-runtime/src/lane-history.js +209 -0
  72. package/dist/agent-runtime/src/lane-history.js.map +1 -0
  73. package/dist/agent-runtime/src/lane-images.d.ts +184 -0
  74. package/dist/agent-runtime/src/message-author.d.ts +43 -0
  75. package/dist/agent-runtime/src/message-text.cjs +15 -0
  76. package/dist/agent-runtime/src/message-text.cjs.map +1 -0
  77. package/dist/agent-runtime/src/message-text.d.ts +47 -0
  78. package/dist/agent-runtime/src/message-text.js +15 -0
  79. package/dist/agent-runtime/src/message-text.js.map +1 -0
  80. package/dist/agent-runtime/src/message-window.cjs +15 -1
  81. package/dist/agent-runtime/src/message-window.cjs.map +1 -1
  82. package/dist/agent-runtime/src/message-window.d.ts +159 -0
  83. package/dist/agent-runtime/src/message-window.js +16 -2
  84. package/dist/agent-runtime/src/message-window.js.map +1 -1
  85. package/dist/agent-runtime/src/messages.cjs +88 -4
  86. package/dist/agent-runtime/src/messages.cjs.map +1 -1
  87. package/dist/agent-runtime/src/messages.d.ts +603 -0
  88. package/dist/agent-runtime/src/messages.js +88 -4
  89. package/dist/agent-runtime/src/messages.js.map +1 -1
  90. package/dist/agent-runtime/src/model-context.d.ts +22 -0
  91. package/dist/agent-runtime/src/offline-status.d.ts +157 -0
  92. package/dist/agent-runtime/src/optimistic-content.d.ts +21 -0
  93. package/dist/agent-runtime/src/protocol.cjs +12 -4
  94. package/dist/agent-runtime/src/protocol.cjs.map +1 -1
  95. package/dist/agent-runtime/src/protocol.d.ts +119 -0
  96. package/dist/agent-runtime/src/protocol.js +13 -5
  97. package/dist/agent-runtime/src/protocol.js.map +1 -1
  98. package/dist/agent-runtime/src/ptc-subcalls.d.ts +51 -0
  99. package/dist/agent-runtime/src/queue.d.ts +138 -0
  100. package/dist/agent-runtime/src/quota-safe-local-storage-session.d.ts +154 -0
  101. package/dist/agent-runtime/src/running-tool-placeholder.cjs +11 -0
  102. package/dist/agent-runtime/src/running-tool-placeholder.cjs.map +1 -0
  103. package/dist/agent-runtime/src/running-tool-placeholder.d.ts +25 -0
  104. package/dist/agent-runtime/src/running-tool-placeholder.js +11 -0
  105. package/dist/agent-runtime/src/running-tool-placeholder.js.map +1 -0
  106. package/dist/agent-runtime/src/runtime-messages.d.ts +104 -0
  107. package/dist/agent-runtime/src/screen-point.d.ts +151 -0
  108. package/dist/agent-runtime/src/sealed-idb.cjs +112 -0
  109. package/dist/agent-runtime/src/sealed-idb.cjs.map +1 -0
  110. package/dist/agent-runtime/src/sealed-idb.d.ts +106 -0
  111. package/dist/agent-runtime/src/sealed-idb.js +112 -0
  112. package/dist/agent-runtime/src/sealed-idb.js.map +1 -0
  113. package/dist/agent-runtime/src/send-recovery.d.ts +40 -0
  114. package/dist/agent-runtime/src/statewire-attach-observer.d.ts +194 -0
  115. package/dist/agent-runtime/src/statewire-diagnostics.d.ts +74 -0
  116. package/dist/agent-runtime/src/statewire-state.d.ts +29 -0
  117. package/dist/agent-runtime/src/statewire-suspended.cjs.map +1 -1
  118. package/dist/agent-runtime/src/statewire-suspended.d.ts +27 -0
  119. package/dist/agent-runtime/src/statewire-suspended.js.map +1 -1
  120. package/dist/agent-runtime/src/statewire-transport.d.ts +40 -0
  121. package/dist/agent-runtime/src/streaming-markdown.d.ts +46 -0
  122. package/dist/agent-runtime/src/subagent-transcripts.cjs +209 -0
  123. package/dist/agent-runtime/src/subagent-transcripts.cjs.map +1 -0
  124. package/dist/agent-runtime/src/subagent-transcripts.d.ts +71 -0
  125. package/dist/agent-runtime/src/subagent-transcripts.js +209 -0
  126. package/dist/agent-runtime/src/subagent-transcripts.js.map +1 -0
  127. package/dist/agent-runtime/src/subagents.cjs +253 -0
  128. package/dist/agent-runtime/src/subagents.cjs.map +1 -0
  129. package/dist/agent-runtime/src/subagents.d.ts +311 -0
  130. package/dist/agent-runtime/src/subagents.js +253 -0
  131. package/dist/agent-runtime/src/subagents.js.map +1 -0
  132. package/dist/agent-runtime/src/subscription-wake-event.d.ts +111 -0
  133. package/dist/agent-runtime/src/thread-extras.d.ts +43 -0
  134. package/dist/agent-runtime/src/thread-handoff.d.ts +364 -0
  135. package/dist/agent-runtime/src/thread-prewarm-controller.d.ts +76 -0
  136. package/dist/agent-runtime/src/thread-prewarm.d.ts +118 -0
  137. package/dist/agent-runtime/src/thread-snapshot-cache.d.ts +99 -0
  138. package/dist/agent-runtime/src/thread-snapshot-mirror.cjs +329 -0
  139. package/dist/agent-runtime/src/thread-snapshot-mirror.cjs.map +1 -0
  140. package/dist/agent-runtime/src/thread-snapshot-mirror.d.ts +101 -0
  141. package/dist/agent-runtime/src/thread-snapshot-mirror.js +329 -0
  142. package/dist/agent-runtime/src/thread-snapshot-mirror.js.map +1 -0
  143. package/dist/agent-runtime/src/thread-status.d.ts +53 -0
  144. package/dist/agent-runtime/src/tool-metadata.d.ts +146 -0
  145. package/dist/agent-runtime/src/tool-names.cjs +67 -0
  146. package/dist/agent-runtime/src/tool-names.cjs.map +1 -1
  147. package/dist/agent-runtime/src/tool-names.d.ts +60 -0
  148. package/dist/agent-runtime/src/tool-names.js +68 -1
  149. package/dist/agent-runtime/src/tool-names.js.map +1 -1
  150. package/dist/agent-runtime/src/tool-outputs.d.ts +35 -0
  151. package/dist/agent-runtime/src/tool-result.cjs +1 -0
  152. package/dist/agent-runtime/src/tool-result.cjs.map +1 -1
  153. package/dist/agent-runtime/src/tool-result.d.ts +126 -0
  154. package/dist/agent-runtime/src/tool-result.js +1 -0
  155. package/dist/agent-runtime/src/tool-result.js.map +1 -1
  156. package/dist/agent-runtime/src/types.d.ts +159 -0
  157. package/dist/agent-runtime/src/use-conversation-list.d.ts +76 -0
  158. package/dist/agent-runtime/src/use-deep-agent-chat-outbox.cjs +136 -0
  159. package/dist/agent-runtime/src/use-deep-agent-chat-outbox.cjs.map +1 -0
  160. package/dist/agent-runtime/src/use-deep-agent-chat-outbox.d.ts +64 -0
  161. package/dist/agent-runtime/src/use-deep-agent-chat-outbox.js +136 -0
  162. package/dist/agent-runtime/src/use-deep-agent-chat-outbox.js.map +1 -0
  163. package/dist/agent-runtime/src/use-deep-agent-config.d.ts +169 -0
  164. package/dist/agent-runtime/src/use-deep-agent-edit-submit.cjs +13 -0
  165. package/dist/agent-runtime/src/use-deep-agent-edit-submit.cjs.map +1 -1
  166. package/dist/agent-runtime/src/use-deep-agent-edit-submit.d.ts +22 -0
  167. package/dist/agent-runtime/src/use-deep-agent-edit-submit.js +13 -0
  168. package/dist/agent-runtime/src/use-deep-agent-edit-submit.js.map +1 -1
  169. package/dist/agent-runtime/src/use-deep-agent-runtime.cjs +20 -2
  170. package/dist/agent-runtime/src/use-deep-agent-runtime.cjs.map +1 -1
  171. package/dist/agent-runtime/src/use-deep-agent-runtime.d.ts +168 -0
  172. package/dist/agent-runtime/src/use-deep-agent-runtime.js +20 -2
  173. package/dist/agent-runtime/src/use-deep-agent-runtime.js.map +1 -1
  174. package/dist/agent-runtime/src/use-deep-agent-thread.cjs +12 -4
  175. package/dist/agent-runtime/src/use-deep-agent-thread.cjs.map +1 -1
  176. package/dist/agent-runtime/src/use-deep-agent-thread.d.ts +320 -0
  177. package/dist/agent-runtime/src/use-deep-agent-thread.js +12 -4
  178. package/dist/agent-runtime/src/use-deep-agent-thread.js.map +1 -1
  179. package/dist/agent-runtime/src/use-deep-agent-voice.cjs +999 -0
  180. package/dist/agent-runtime/src/use-deep-agent-voice.cjs.map +1 -0
  181. package/dist/agent-runtime/src/use-deep-agent-voice.d.ts +409 -0
  182. package/dist/agent-runtime/src/use-deep-agent-voice.js +999 -0
  183. package/dist/agent-runtime/src/use-deep-agent-voice.js.map +1 -0
  184. package/dist/agent-runtime/src/use-deep-agent-window-sync.d.ts +102 -0
  185. package/dist/agent-runtime/src/use-historical-edit-attachments.d.ts +2 -0
  186. package/dist/agent-runtime/src/use-thread-handoff-flow.d.ts +84 -0
  187. package/dist/agent-runtime/src/voice-presentation.d.ts +80 -0
  188. package/dist/agent-runtime/src/voice-turn-grouping.d.ts +28 -0
  189. package/dist/agent-runtime/src/voice-wire-types.d.ts +15 -0
  190. package/dist/agent-runtime/src/withdrawn-turns.d.ts +97 -0
  191. package/dist/chat/AthenaChat.cjs +77 -6
  192. package/dist/chat/AthenaChat.cjs.map +1 -1
  193. package/dist/chat/AthenaChat.js +78 -7
  194. package/dist/chat/AthenaChat.js.map +1 -1
  195. package/dist/chat/StatewireApprovalCard.d.ts +1 -1
  196. package/dist/chat/StatewireClientToolBridge.d.ts +1 -1
  197. package/dist/chat/StatewireQueuedMessages.cjs +11 -4
  198. package/dist/chat/StatewireQueuedMessages.cjs.map +1 -1
  199. package/dist/chat/StatewireQueuedMessages.d.ts +1 -1
  200. package/dist/chat/StatewireQueuedMessages.js +11 -4
  201. package/dist/chat/StatewireQueuedMessages.js.map +1 -1
  202. package/dist/chat/chat-outbox-rows.cjs +223 -0
  203. package/dist/chat/chat-outbox-rows.cjs.map +1 -0
  204. package/dist/chat/chat-outbox-rows.d.ts +29 -0
  205. package/dist/chat/chat-outbox-rows.js +223 -0
  206. package/dist/chat/chat-outbox-rows.js.map +1 -0
  207. package/dist/chat/statewire-approval.d.ts +1 -1
  208. package/dist/chat/statewire-client-tools.d.ts +1 -1
  209. package/dist/chat/super-grouping/SuperGroupingCard.cjs +3 -1
  210. package/dist/chat/super-grouping/SuperGroupingCard.cjs.map +1 -1
  211. package/dist/chat/super-grouping/SuperGroupingCard.d.ts +7 -1
  212. package/dist/chat/super-grouping/SuperGroupingCard.js +3 -1
  213. package/dist/chat/super-grouping/SuperGroupingCard.js.map +1 -1
  214. package/dist/chat/super-grouping/SuperGroupingTranscript.cjs +7 -2
  215. package/dist/chat/super-grouping/SuperGroupingTranscript.cjs.map +1 -1
  216. package/dist/chat/super-grouping/SuperGroupingTranscript.d.ts +2 -2
  217. package/dist/chat/super-grouping/SuperGroupingTranscript.js +7 -2
  218. package/dist/chat/super-grouping/SuperGroupingTranscript.js.map +1 -1
  219. package/dist/chat/super-grouping/activity-timeline.cjs +19 -11
  220. package/dist/chat/super-grouping/activity-timeline.cjs.map +1 -1
  221. package/dist/chat/super-grouping/activity-timeline.d.ts +25 -9
  222. package/dist/chat/super-grouping/activity-timeline.js +19 -11
  223. package/dist/chat/super-grouping/activity-timeline.js.map +1 -1
  224. package/dist/chat/use-statewire-approval-request.cjs +36 -0
  225. package/dist/chat/use-statewire-approval-request.cjs.map +1 -1
  226. package/dist/chat/use-statewire-approval-request.d.ts +49 -1
  227. package/dist/chat/use-statewire-approval-request.js +39 -3
  228. package/dist/chat/use-statewire-approval-request.js.map +1 -1
  229. package/dist/chat-ui/composer/tiptap-composer.cjs +102 -3
  230. package/dist/chat-ui/composer/tiptap-composer.cjs.map +1 -1
  231. package/dist/chat-ui/composer/tiptap-composer.d.ts +32 -1
  232. package/dist/chat-ui/composer/tiptap-composer.js +103 -4
  233. package/dist/chat-ui/composer/tiptap-composer.js.map +1 -1
  234. package/dist/chat-ui/header/conversation-history-panel.d.ts +1 -1
  235. package/dist/chat-ui/index.d.ts +1 -1
  236. package/dist/chat-ui/messages/message-components.cjs +15 -0
  237. package/dist/chat-ui/messages/message-components.cjs.map +1 -1
  238. package/dist/chat-ui/messages/message-components.js +15 -0
  239. package/dist/chat-ui/messages/message-components.js.map +1 -1
  240. package/dist/chat-ui/messages/runtime-message.d.ts +1 -1
  241. package/dist/chat-ui/messages/statewire-continue-run.d.ts +1 -1
  242. package/dist/chat-ui/messages/user-edit-composer.cjs +15 -2
  243. package/dist/chat-ui/messages/user-edit-composer.cjs.map +1 -1
  244. package/dist/chat-ui/messages/user-edit-composer.d.ts +4 -2
  245. package/dist/chat-ui/messages/user-edit-composer.js +15 -2
  246. package/dist/chat-ui/messages/user-edit-composer.js.map +1 -1
  247. package/dist/chat-ui/messages/wake-marker.d.ts +1 -1
  248. package/dist/chat-ui/rich-text/chat-text-schema.cjs +1 -0
  249. package/dist/chat-ui/rich-text/chat-text-schema.cjs.map +1 -1
  250. package/dist/chat-ui/rich-text/chat-text-schema.d.ts +3 -0
  251. package/dist/chat-ui/rich-text/chat-text-schema.js +1 -0
  252. package/dist/chat-ui/rich-text/chat-text-schema.js.map +1 -1
  253. package/dist/chat-ui/statewire.cjs +1 -0
  254. package/dist/chat-ui/statewire.cjs.map +1 -1
  255. package/dist/chat-ui/statewire.d.ts +2 -2
  256. package/dist/chat-ui/statewire.js +2 -1
  257. package/dist/chat-ui/thread/statewire-history-edge.d.ts +1 -1
  258. package/dist/composer/AttachmentContext.cjs +8 -4
  259. package/dist/composer/AttachmentContext.cjs.map +1 -1
  260. package/dist/composer/AttachmentContext.d.ts +7 -0
  261. package/dist/composer/AttachmentContext.js +8 -4
  262. package/dist/composer/AttachmentContext.js.map +1 -1
  263. package/dist/composer/build-composed-message.cjs +34 -0
  264. package/dist/composer/build-composed-message.cjs.map +1 -1
  265. package/dist/composer/build-composed-message.d.ts +20 -0
  266. package/dist/composer/build-composed-message.js +35 -1
  267. package/dist/composer/build-composed-message.js.map +1 -1
  268. package/dist/composer/composer-handoff.cjs +39 -2
  269. package/dist/composer/composer-handoff.cjs.map +1 -1
  270. package/dist/composer/composer-handoff.d.ts +28 -3
  271. package/dist/composer/composer-handoff.js +39 -2
  272. package/dist/composer/composer-handoff.js.map +1 -1
  273. package/dist/composer/useAttachFiles.cjs +15 -2
  274. package/dist/composer/useAttachFiles.cjs.map +1 -1
  275. package/dist/composer/useAttachFiles.d.ts +11 -0
  276. package/dist/composer/useAttachFiles.js +15 -2
  277. package/dist/composer/useAttachFiles.js.map +1 -1
  278. package/dist/composer/useSendMessage.cjs.map +1 -1
  279. package/dist/composer/useSendMessage.d.ts +4 -3
  280. package/dist/composer/useSendMessage.js.map +1 -1
  281. package/dist/diagnostics/athena-diagnostics.cjs.map +1 -1
  282. package/dist/diagnostics/athena-diagnostics.d.ts +3 -1
  283. package/dist/diagnostics/athena-diagnostics.js.map +1 -1
  284. package/dist/index.cjs +18 -0
  285. package/dist/index.cjs.map +1 -1
  286. package/dist/index.d.ts +15 -6
  287. package/dist/index.js +19 -1
  288. package/dist/index.js.map +1 -1
  289. package/dist/offline/chat-outbox.cjs +57 -0
  290. package/dist/offline/chat-outbox.cjs.map +1 -0
  291. package/dist/offline/chat-outbox.d.ts +80 -0
  292. package/dist/offline/chat-outbox.js +57 -0
  293. package/dist/offline/chat-outbox.js.map +1 -0
  294. package/dist/offline/offline-history.cjs +77 -0
  295. package/dist/offline/offline-history.cjs.map +1 -0
  296. package/dist/offline/offline-history.d.ts +60 -0
  297. package/dist/offline/offline-history.js +77 -0
  298. package/dist/offline/offline-history.js.map +1 -0
  299. package/dist/provider/AthenaProvider.cjs +206 -9
  300. package/dist/provider/AthenaProvider.cjs.map +1 -1
  301. package/dist/provider/AthenaProvider.d.ts +22 -1
  302. package/dist/provider/AthenaProvider.js +207 -10
  303. package/dist/provider/AthenaProvider.js.map +1 -1
  304. package/dist/provider/statewire-window-context.d.ts +1 -1
  305. package/dist/react/package.json.cjs +1 -1
  306. package/dist/react/package.json.js +1 -1
  307. package/dist/references/src/anchors/file-line-range.d.ts +58 -0
  308. package/dist/references/src/anchors/format.d.ts +21 -0
  309. package/dist/references/src/anchors/message-anchors.d.ts +71 -0
  310. package/dist/references/src/anchors/parse.d.ts +8 -0
  311. package/dist/references/src/anchors/registry-contract.d.ts +24 -0
  312. package/dist/references/src/anchors/registry.d.ts +19 -0
  313. package/dist/references/src/anchors/schemas.d.ts +194 -0
  314. package/dist/references/src/anchors/serialize.d.ts +8 -0
  315. package/dist/references/src/anchors/time.d.ts +78 -0
  316. package/dist/references/src/anchors/types.d.ts +474 -0
  317. package/dist/references/src/asset-bounds.d.ts +27 -0
  318. package/dist/references/src/asset-links.d.ts +23 -0
  319. package/dist/references/src/asset-reference.d.ts +16 -0
  320. package/dist/references/src/formats/format-catalog.d.ts +79 -0
  321. package/dist/references/src/formats/markdown/parse-reference-markdown.d.ts +28 -0
  322. package/dist/references/src/formats/markdown/reference-display-name.d.ts +6 -0
  323. package/dist/references/src/formats/object/asset-object.d.ts +9 -0
  324. package/dist/references/src/formats/object/callable-object.d.ts +6 -0
  325. package/dist/references/src/formats/object/decode-reference-object-payload.d.ts +3 -0
  326. package/dist/references/src/formats/object/external-url-object.d.ts +9 -0
  327. package/dist/references/src/formats/object/group-object.d.ts +9 -0
  328. package/dist/references/src/formats/object/navigation-object.d.ts +9 -0
  329. package/dist/references/src/formats/object/parse-reference-object.d.ts +11 -0
  330. package/dist/references/src/formats/object/person-object.d.ts +9 -0
  331. package/dist/references/src/formats/uri/asset-mention-uri.d.ts +9 -0
  332. package/dist/references/src/formats/uri/asset-spaces-url.d.ts +9 -0
  333. package/dist/references/src/formats/uri/callable-mention-uris.d.ts +9 -0
  334. package/dist/references/src/formats/uri/detect-uri-wire.d.ts +9 -0
  335. package/dist/references/src/formats/uri/group-mention-uri.d.ts +12 -0
  336. package/dist/references/src/formats/uri/navigation-spaces-url.d.ts +14 -0
  337. package/dist/references/src/formats/uri/parse-reference-uri.d.ts +20 -0
  338. package/dist/references/src/formats/uri/person-mention-uri.d.ts +9 -0
  339. package/dist/references/src/formats/uri/template-placeholder.d.ts +12 -0
  340. package/dist/references/src/index.d.ts +47 -0
  341. package/dist/references/src/legacy/index.d.ts +14 -0
  342. package/dist/references/src/legacy/pre-reference-asset-url.d.ts +57 -0
  343. package/dist/references/src/legacy/pre-reference-citation-bridge.d.ts +22 -0
  344. package/dist/references/src/legacy/pre-reference-citation.d.ts +138 -0
  345. package/dist/references/src/legacy/pre-reference-external-url.d.ts +31 -0
  346. package/dist/references/src/legacy/pre-reference-format.d.ts +8 -0
  347. package/dist/references/src/legacy/pre-reference-mention.d.ts +27 -0
  348. package/dist/references/src/legacy/pre-reference-object.d.ts +8 -0
  349. package/dist/references/src/legacy/pre-reference-uri.d.ts +12 -0
  350. package/dist/references/src/legacy.d.ts +2 -0
  351. package/dist/references/src/mention-href-patterns.d.ts +19 -0
  352. package/dist/references/src/mention-node/index.d.ts +5 -0
  353. package/dist/references/src/mention-node/mention-node.d.ts +31 -0
  354. package/dist/references/src/mention-node/resolve-node-attrs.d.ts +27 -0
  355. package/dist/references/src/parse-reference.d.ts +23 -0
  356. package/dist/references/src/schemas.d.ts +463 -0
  357. package/dist/references/src/serialize-reference.d.ts +50 -0
  358. package/dist/references/src/sheet-name.d.ts +10 -0
  359. package/dist/references/src/tool-option-schemas.d.ts +597 -0
  360. package/dist/references/src/types.d.ts +125 -0
  361. package/dist/references/src/version-ref.d.ts +30 -0
  362. package/dist/runtime/statewire-lifecycle.d.ts +1 -1
  363. package/dist/runtime/statewire-model-lane.d.ts +1 -1
  364. package/dist/runtime/statewire-server-lane-context.d.ts +1 -1
  365. package/dist/runtime/statewire-session-key.cjs +7 -0
  366. package/dist/runtime/statewire-session-key.cjs.map +1 -1
  367. package/dist/runtime/statewire-session-key.d.ts +16 -0
  368. package/dist/runtime/statewire-session-key.js +8 -1
  369. package/dist/runtime/statewire-session-key.js.map +1 -1
  370. package/dist/runtime/statewire-session-lane.cjs +48 -0
  371. package/dist/runtime/statewire-session-lane.cjs.map +1 -0
  372. package/dist/runtime/statewire-session-lane.d.ts +29 -0
  373. package/dist/runtime/statewire-session-lane.js +48 -0
  374. package/dist/runtime/statewire-session-lane.js.map +1 -0
  375. package/dist/runtime/statewire-thread-config-lane.d.ts +1 -1
  376. package/dist/runtime/useAthenaStatewireRuntime.cjs +16 -5
  377. package/dist/runtime/useAthenaStatewireRuntime.cjs.map +1 -1
  378. package/dist/runtime/useAthenaStatewireRuntime.d.ts +15 -1
  379. package/dist/runtime/useAthenaStatewireRuntime.js +17 -6
  380. package/dist/runtime/useAthenaStatewireRuntime.js.map +1 -1
  381. package/dist/styles.css +1 -1
  382. package/dist/threads/api.d.ts +1 -1
  383. package/dist/threads/conversation-list-fetcher.d.ts +1 -1
  384. package/dist/threads/index-triggered-refresh.cjs +164 -0
  385. package/dist/threads/index-triggered-refresh.cjs.map +1 -0
  386. package/dist/threads/index-triggered-refresh.d.ts +70 -0
  387. package/dist/threads/index-triggered-refresh.js +164 -0
  388. package/dist/threads/index-triggered-refresh.js.map +1 -0
  389. package/dist/threads/offline-session-list.cjs +75 -0
  390. package/dist/threads/offline-session-list.cjs.map +1 -0
  391. package/dist/threads/offline-session-list.d.ts +27 -0
  392. package/dist/threads/offline-session-list.js +75 -0
  393. package/dist/threads/offline-session-list.js.map +1 -0
  394. package/dist/threads/pull-request-display.d.ts +1 -1
  395. package/dist/threads/session-list-model.d.ts +1 -1
  396. package/dist/threads/session-list-tab-share.cjs +150 -0
  397. package/dist/threads/session-list-tab-share.cjs.map +1 -0
  398. package/dist/threads/session-list-tab-share.d.ts +73 -0
  399. package/dist/threads/session-list-tab-share.js +150 -0
  400. package/dist/threads/session-list-tab-share.js.map +1 -0
  401. package/dist/threads/session-row-parts.d.ts +1 -1
  402. package/dist/threads/sessions-query.d.ts +1 -1
  403. package/dist/threads/statewire-thread-list.cjs +105 -20
  404. package/dist/threads/statewire-thread-list.cjs.map +1 -1
  405. package/dist/threads/statewire-thread-list.d.ts +31 -3
  406. package/dist/threads/statewire-thread-list.js +107 -22
  407. package/dist/threads/statewire-thread-list.js.map +1 -1
  408. package/dist/threads/thread-prefetcher.d.ts +1 -1
  409. package/dist/threads/use-athena-session-attention.d.ts +1 -1
  410. package/dist/threads/use-athena-sessions.cjs +32 -22
  411. package/dist/threads/use-athena-sessions.cjs.map +1 -1
  412. package/dist/threads/use-athena-sessions.js +33 -23
  413. package/dist/threads/use-athena-sessions.js.map +1 -1
  414. package/dist/threads/use-rest-conversation-history.d.ts +1 -1
  415. package/dist/threads/use-statewire-conversation-history.d.ts +5 -5
  416. package/dist/tiptap-markdown-table/src/markdown-table-serializer.d.ts +56 -0
  417. package/dist/tools/NestedPtcMessages.cjs +14 -9
  418. package/dist/tools/NestedPtcMessages.cjs.map +1 -1
  419. package/dist/tools/NestedPtcMessages.d.ts +9 -0
  420. package/dist/tools/NestedPtcMessages.js +6 -1
  421. package/dist/tools/NestedPtcMessages.js.map +1 -1
  422. package/dist/tools/index.d.ts +1 -1
  423. package/dist/tools/primitives.d.ts +1 -1
  424. package/dist/tools/subagent-task-tool-ui.cjs +494 -0
  425. package/dist/tools/subagent-task-tool-ui.cjs.map +1 -0
  426. package/dist/tools/subagent-task-tool-ui.d.ts +109 -0
  427. package/dist/tools/subagent-task-tool-ui.js +494 -0
  428. package/dist/tools/subagent-task-tool-ui.js.map +1 -0
  429. package/dist/tools/tool-fallback.d.ts +1 -1
  430. package/dist/tools/tool-icons.d.ts +1 -1
  431. package/dist/tools/tool-summary.d.ts +1 -1
  432. package/dist/tools/tool-uis.cjs +4 -0
  433. package/dist/tools/tool-uis.cjs.map +1 -1
  434. package/dist/tools/tool-uis.js +4 -0
  435. package/dist/tools/tool-uis.js.map +1 -1
  436. package/dist/voice/chat.cjs +6 -0
  437. package/dist/voice/chat.cjs.map +1 -0
  438. package/dist/voice/chat.d.ts +2 -0
  439. package/dist/voice/chat.js +6 -0
  440. package/dist/voice/chat.js.map +1 -0
  441. package/dist/voice/livekit-join.cjs +119 -0
  442. package/dist/voice/livekit-join.cjs.map +1 -0
  443. package/dist/voice/livekit-join.d.ts +8 -0
  444. package/dist/voice/livekit-join.js +119 -0
  445. package/dist/voice/livekit-join.js.map +1 -0
  446. package/dist/voice/livekit.cjs +32 -0
  447. package/dist/voice/livekit.cjs.map +1 -0
  448. package/dist/voice/livekit.d.ts +80 -0
  449. package/dist/voice/livekit.js +32 -0
  450. package/dist/voice/livekit.js.map +1 -0
  451. package/package.json +20 -10
@@ -0,0 +1,75 @@
1
+ import { useRef, useEffect } from "react";
2
+ import { CONVERSATION_LIST_QUERY_KEY_ROOT } from "../agent-runtime/src/conversation-list.js";
3
+ const OFFLINE_SESSION_LIST_KEY = "session-list";
4
+ const MAX_OFFLINE_SESSION_LIST_PAGES = 4;
5
+ const RESTORED_UPDATED_AT = 1;
6
+ function isSessionListFirstPage(queryKey) {
7
+ return queryKey[0] === CONVERSATION_LIST_QUERY_KEY_ROOT && queryKey[4] === "first-page";
8
+ }
9
+ function isFirstPageKey(queryKey) {
10
+ return Array.isArray(queryKey) && queryKey.length === 5 && isSessionListFirstPage(queryKey) && typeof queryKey[1] === "string" && typeof queryKey[2] === "string" && typeof queryKey[3] === "number";
11
+ }
12
+ function isConversationRow(row) {
13
+ if (typeof row !== "object" || row === null) return false;
14
+ const { threadId, title, updatedAt } = row;
15
+ return typeof threadId === "string" && typeof title === "string" && typeof updatedAt === "string";
16
+ }
17
+ function isConversationListPage(value) {
18
+ if (typeof value !== "object" || value === null) return false;
19
+ const { items, hasMore, totalCount } = value;
20
+ return Array.isArray(items) && items.every(isConversationRow) && typeof hasMore === "boolean" && (totalCount === null || typeof totalCount === "number");
21
+ }
22
+ function isKeptPage(value) {
23
+ if (typeof value !== "object" || value === null) return false;
24
+ const { queryKey, data } = value;
25
+ return isFirstPageKey(queryKey) && isConversationListPage(data);
26
+ }
27
+ function useOfflineSessionList({
28
+ queryClient,
29
+ offlineList
30
+ }) {
31
+ const mirror = offlineList == null ? void 0 : offlineList.mirror;
32
+ const ownerId = offlineList == null ? void 0 : offlineList.ownerId;
33
+ const boundOwner = useRef(null);
34
+ useEffect(() => {
35
+ if (!mirror || !ownerId) return;
36
+ if (boundOwner.current !== null && boundOwner.current !== ownerId) {
37
+ void queryClient.cancelQueries({ queryKey: [CONVERSATION_LIST_QUERY_KEY_ROOT] });
38
+ queryClient.removeQueries({ queryKey: [CONVERSATION_LIST_QUERY_KEY_ROOT] });
39
+ }
40
+ boundOwner.current = ownerId;
41
+ const boundAt = Date.now();
42
+ let stopped = false;
43
+ void mirror.loadList({ ownerId, listKey: OFFLINE_SESSION_LIST_KEY }).then((kept) => {
44
+ if (stopped || !kept || !Array.isArray(kept.value)) return;
45
+ for (const page of kept.value) {
46
+ if (!isKeptPage(page)) continue;
47
+ if (queryClient.getQueryData(page.queryKey) !== void 0) continue;
48
+ queryClient.setQueryData(page.queryKey, page.data, { updatedAt: RESTORED_UPDATED_AT });
49
+ }
50
+ });
51
+ const write = () => {
52
+ const pages = queryClient.getQueryCache().findAll({ predicate: (query) => isSessionListFirstPage(query.queryKey) }).filter(
53
+ (query) => query.state.status === "success" && query.state.dataUpdatedAt >= boundAt && isConversationListPage(query.state.data)
54
+ ).sort((a, b) => b.state.dataUpdatedAt - a.state.dataUpdatedAt).slice(0, MAX_OFFLINE_SESSION_LIST_PAGES).map((query) => ({ queryKey: query.queryKey, data: query.state.data }));
55
+ if (pages.length > 0) mirror.writeList({ ownerId, listKey: OFFLINE_SESSION_LIST_KEY, value: pages });
56
+ };
57
+ const unsubscribe = queryClient.getQueryCache().subscribe((event) => {
58
+ if (event.type !== "updated" || event.action.type !== "success") return;
59
+ if (!isSessionListFirstPage(event.query.queryKey)) return;
60
+ if (event.query.state.dataUpdatedAt === RESTORED_UPDATED_AT) return;
61
+ write();
62
+ });
63
+ return () => {
64
+ stopped = true;
65
+ unsubscribe();
66
+ };
67
+ }, [queryClient, mirror, ownerId]);
68
+ }
69
+ export {
70
+ MAX_OFFLINE_SESSION_LIST_PAGES,
71
+ OFFLINE_SESSION_LIST_KEY,
72
+ isSessionListFirstPage,
73
+ useOfflineSessionList
74
+ };
75
+ //# sourceMappingURL=offline-session-list.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"offline-session-list.js","sources":["../../src/threads/offline-session-list.ts"],"sourcesContent":["import {\n CONVERSATION_LIST_QUERY_KEY_ROOT,\n type ConversationListPage,\n type ThreadSnapshotMirror,\n} from '@athenaintel/agent-runtime';\nimport type { QueryClient, QueryKey } from '@tanstack/react-query';\nimport { useEffect, useRef } from 'react';\n\n/** Under this name the list's pages are kept, per owner. */\nexport const OFFLINE_SESSION_LIST_KEY = 'session-list';\n/** The first pages kept: one per filter the list was read with, the newest first. */\nexport const MAX_OFFLINE_SESSION_LIST_PAGES = 4;\n/**\n * Restored pages are stamped this old, so they paint at once and are read again on mount whenever\n * Athena can be reached (and never replace a page already read in this provider).\n */\nconst RESTORED_UPDATED_AT = 1;\n\ninterface KeptPage {\n queryKey: QueryKey;\n data: ConversationListPage;\n}\n\n/** A conversation list's live first page (`conversationListQueryKeys.firstPage`). */\nexport function isSessionListFirstPage(queryKey: QueryKey): boolean {\n return queryKey[0] === CONVERSATION_LIST_QUERY_KEY_ROOT && queryKey[4] === 'first-page';\n}\n\n/** Exactly `conversationListQueryKeys.firstPage(scopeKey, filterKey, pageSize)`. */\nfunction isFirstPageKey(queryKey: unknown): queryKey is QueryKey {\n return (\n Array.isArray(queryKey) &&\n queryKey.length === 5 &&\n isSessionListFirstPage(queryKey) &&\n typeof queryKey[1] === 'string' &&\n typeof queryKey[2] === 'string' &&\n typeof queryKey[3] === 'number'\n );\n}\n\nfunction isConversationRow(row: unknown): boolean {\n if (typeof row !== 'object' || row === null) return false;\n const { threadId, title, updatedAt } = row as Record<string, unknown>;\n return typeof threadId === 'string' && typeof title === 'string' && typeof updatedAt === 'string';\n}\n\n/** A page the list can render: its rows carry the fields every row reads. */\nfunction isConversationListPage(value: unknown): value is ConversationListPage {\n if (typeof value !== 'object' || value === null) return false;\n const { items, hasMore, totalCount } = value as Record<string, unknown>;\n return (\n Array.isArray(items) &&\n items.every(isConversationRow) &&\n typeof hasMore === 'boolean' &&\n (totalCount === null || typeof totalCount === 'number')\n );\n}\n\nfunction isKeptPage(value: unknown): value is KeptPage {\n if (typeof value !== 'object' || value === null) return false;\n const { queryKey, data } = value as Record<string, unknown>;\n return isFirstPageKey(queryKey) && isConversationListPage(data);\n}\n\n/**\n * The session list's first pages, kept on this device sealed under the host's key\n * (`offlineList`'s mirror, `AthenaProvider`'s `offlineHistory`): restored into the list's own query\n * client before it is read, so the list paints at once and reads while Athena can't be reached,\n * and written back (debounced by the mirror) each time a first page is read. Without `offlineList`,\n * nothing.\n *\n * Owner-bound. A list kept for one owner is never restored for another, and a change of owner\n * drops every page of the list's cache before the new owner's are restored (in API-key mode two\n * people read the same list keys); only pages read since the owner was bound are kept for them. A\n * restored page that is not a list page the rows can render is left out.\n */\nexport function useOfflineSessionList({\n queryClient,\n offlineList,\n}: {\n queryClient: QueryClient;\n offlineList: { mirror: ThreadSnapshotMirror; ownerId: string } | undefined;\n}): void {\n const mirror = offlineList?.mirror;\n const ownerId = offlineList?.ownerId;\n const boundOwner = useRef<string | null>(null);\n useEffect(() => {\n if (!mirror || !ownerId) return;\n if (boundOwner.current !== null && boundOwner.current !== ownerId) {\n void queryClient.cancelQueries({ queryKey: [CONVERSATION_LIST_QUERY_KEY_ROOT] });\n queryClient.removeQueries({ queryKey: [CONVERSATION_LIST_QUERY_KEY_ROOT] });\n }\n boundOwner.current = ownerId;\n const boundAt = Date.now();\n let stopped = false;\n void mirror.loadList({ ownerId, listKey: OFFLINE_SESSION_LIST_KEY }).then((kept) => {\n if (stopped || !kept || !Array.isArray(kept.value)) return;\n for (const page of kept.value) {\n if (!isKeptPage(page)) continue;\n if (queryClient.getQueryData(page.queryKey) !== undefined) continue;\n queryClient.setQueryData(page.queryKey, page.data, { updatedAt: RESTORED_UPDATED_AT });\n }\n });\n const write = (): void => {\n const pages: KeptPage[] = queryClient\n .getQueryCache()\n .findAll({ predicate: (query) => isSessionListFirstPage(query.queryKey) })\n .filter(\n (query) =>\n query.state.status === 'success' &&\n query.state.dataUpdatedAt >= boundAt &&\n isConversationListPage(query.state.data),\n )\n .sort((a, b) => b.state.dataUpdatedAt - a.state.dataUpdatedAt)\n .slice(0, MAX_OFFLINE_SESSION_LIST_PAGES)\n .map((query) => ({ queryKey: query.queryKey, data: query.state.data as ConversationListPage }));\n if (pages.length > 0) mirror.writeList({ ownerId, listKey: OFFLINE_SESSION_LIST_KEY, value: pages });\n };\n const unsubscribe = queryClient.getQueryCache().subscribe((event) => {\n if (event.type !== 'updated' || event.action.type !== 'success') return;\n if (!isSessionListFirstPage(event.query.queryKey)) return;\n // A page restored from the device is not news to write back.\n if (event.query.state.dataUpdatedAt === RESTORED_UPDATED_AT) return;\n write();\n });\n return () => {\n stopped = true;\n unsubscribe();\n };\n }, [queryClient, mirror, ownerId]);\n}\n"],"names":[],"mappings":"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"}
@@ -4,7 +4,7 @@
4
4
  * workbench's Pull requests pane: one icon and one colour per state, one
5
5
  * phrase per checks state.
6
6
  */
7
- import type { ConversationPullRequest } from '@athenaintel/agent-runtime';
7
+ import type { ConversationPullRequest } from '../agent-runtime/src/index';
8
8
  import type { FC } from 'react';
9
9
  import type { PullRequestChipState } from './session-list-model';
10
10
  export declare const PR_STATE_ICON: Record<PullRequestChipState, FC<{
@@ -6,7 +6,7 @@
6
6
  * hosts that draw their own rows (`useAthenaSessionAttention`) can reuse the
7
7
  * same rules.
8
8
  */
9
- import type { ConversationPullRequest } from '@athenaintel/agent-runtime';
9
+ import type { ConversationPullRequest } from '../agent-runtime/src/index';
10
10
  import type { AthenaStatewireThreadSummary } from './statewire-thread-list';
11
11
  export type SessionListGroup = 'Needs you' | 'Working' | 'Pinned' | 'Recent';
12
12
  /** Display order; a session appears once, in the FIRST group that applies. */
@@ -0,0 +1,150 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, Symbol.toStringTag, { value: "Module" });
3
+ const react = require("react");
4
+ const useAthenaRestQuery = require("../lib/use-athena-rest-query.cjs");
5
+ const conversationList = require("../agent-runtime/src/conversation-list.cjs");
6
+ const TAB_SHARE_CLAIM_MS = 5e3;
7
+ const CHANNEL_PREFIX = "athena-sdk:session-list:";
8
+ const MESSAGE_VERSION = 1;
9
+ const NO_SHARE = {
10
+ claimedUntil: () => null,
11
+ claim: () => void 0
12
+ };
13
+ function sessionListShareKey(queryKey) {
14
+ return JSON.stringify(queryKey);
15
+ }
16
+ function isFirstPageKey(queryKey) {
17
+ return Array.isArray(queryKey) && queryKey[0] === conversationList.CONVERSATION_LIST_QUERY_KEY_ROOT && queryKey[queryKey.length - 1] === "first-page";
18
+ }
19
+ function isPage(value) {
20
+ if (typeof value !== "object" || value === null) return false;
21
+ const { items, hasMore } = value;
22
+ return Array.isArray(items) && typeof hasMore === "boolean";
23
+ }
24
+ function parseTabShareMessage(raw) {
25
+ if (typeof raw !== "object" || raw === null) return null;
26
+ const message = raw;
27
+ if (message.v !== MESSAGE_VERSION || typeof message.key !== "string") return null;
28
+ if (message.kind === "claim") return { v: MESSAGE_VERSION, kind: "claim", key: message.key };
29
+ if (message.kind === "page" && isFirstPageKey(message.queryKey) && sessionListShareKey(message.queryKey) === message.key && isPage(message.data) && typeof message.updatedAt === "number") {
30
+ return {
31
+ v: MESSAGE_VERSION,
32
+ kind: "page",
33
+ key: message.key,
34
+ queryKey: message.queryKey,
35
+ data: message.data,
36
+ updatedAt: message.updatedAt
37
+ };
38
+ }
39
+ return null;
40
+ }
41
+ function applySharedPage(queryClient, message) {
42
+ const state = queryClient.getQueryState(message.queryKey);
43
+ if (!state) return false;
44
+ if (state.dataUpdatedAt >= message.updatedAt) return false;
45
+ queryClient.setQueryData(message.queryKey, message.data, { updatedAt: message.updatedAt });
46
+ return true;
47
+ }
48
+ function useSessionListTabShare({
49
+ queryClient,
50
+ identity
51
+ }) {
52
+ const channelName = identity ? `${CHANNEL_PREFIX}${useAthenaRestQuery.keyPartFingerprint(
53
+ [identity.backendUrl, identity.userId, identity.workspaceId].join("\0")
54
+ )}` : null;
55
+ const claims = react.useMemo(() => /* @__PURE__ */ new Map(), [channelName]);
56
+ const channelRef = react.useRef(null);
57
+ const isSupported = channelName !== null && typeof BroadcastChannel !== "undefined";
58
+ react.useEffect(() => {
59
+ if (!channelName || typeof BroadcastChannel === "undefined") return;
60
+ let channel;
61
+ try {
62
+ channel = new BroadcastChannel(channelName);
63
+ } catch {
64
+ return;
65
+ }
66
+ channelRef.current = channel;
67
+ const post = (message) => {
68
+ try {
69
+ channel.postMessage(message);
70
+ } catch {
71
+ }
72
+ };
73
+ channel.onmessage = (event) => {
74
+ const message = parseTabShareMessage(event.data);
75
+ if (!message) return;
76
+ if (message.kind === "claim") {
77
+ claims.set(message.key, Date.now() + TAB_SHARE_CLAIM_MS);
78
+ return;
79
+ }
80
+ applySharedPage(queryClient, message);
81
+ };
82
+ const startedHere = /* @__PURE__ */ new Set();
83
+ const unsubscribe = queryClient.getQueryCache().subscribe((event) => {
84
+ if (event.type === "removed") {
85
+ startedHere.delete(event.query.queryHash);
86
+ return;
87
+ }
88
+ if (event.type !== "updated") return;
89
+ const { queryKey, queryHash } = event.query;
90
+ if (!isFirstPageKey(queryKey)) return;
91
+ if (event.action.type === "fetch") {
92
+ startedHere.add(queryHash);
93
+ return;
94
+ }
95
+ if (event.action.type === "error") {
96
+ startedHere.delete(queryHash);
97
+ return;
98
+ }
99
+ if (event.action.type !== "success") return;
100
+ if (event.action.manual) return;
101
+ if (!startedHere.delete(queryHash)) return;
102
+ if (!isPage(event.query.state.data)) return;
103
+ post({
104
+ v: MESSAGE_VERSION,
105
+ kind: "page",
106
+ key: sessionListShareKey(queryKey),
107
+ queryKey,
108
+ data: event.query.state.data,
109
+ updatedAt: event.query.state.dataUpdatedAt
110
+ });
111
+ });
112
+ return () => {
113
+ unsubscribe();
114
+ if (channelRef.current === channel) channelRef.current = null;
115
+ channel.onmessage = null;
116
+ channel.close();
117
+ };
118
+ }, [channelName, claims, queryClient]);
119
+ return react.useMemo(() => {
120
+ if (!isSupported) return NO_SHARE;
121
+ return {
122
+ claimedUntil: (key) => {
123
+ const until = claims.get(key);
124
+ if (until === void 0) return null;
125
+ if (until <= Date.now()) {
126
+ claims.delete(key);
127
+ return null;
128
+ }
129
+ return until;
130
+ },
131
+ claim: (key) => {
132
+ var _a;
133
+ try {
134
+ (_a = channelRef.current) == null ? void 0 : _a.postMessage({
135
+ v: MESSAGE_VERSION,
136
+ kind: "claim",
137
+ key
138
+ });
139
+ } catch {
140
+ }
141
+ }
142
+ };
143
+ }, [isSupported, claims]);
144
+ }
145
+ exports.TAB_SHARE_CLAIM_MS = TAB_SHARE_CLAIM_MS;
146
+ exports.applySharedPage = applySharedPage;
147
+ exports.parseTabShareMessage = parseTabShareMessage;
148
+ exports.sessionListShareKey = sessionListShareKey;
149
+ exports.useSessionListTabShare = useSessionListTabShare;
150
+ //# sourceMappingURL=session-list-tab-share.cjs.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"session-list-tab-share.cjs","sources":["../../src/threads/session-list-tab-share.ts"],"sourcesContent":["/**\n * Open tabs of one signed-in user share their session-list reads.\n *\n * A pushed conversation-index change reaches every open tab at once, and each\n * one used to re-read the same lists. With this in place:\n *\n * - **Pages are shared.** Whenever a tab reads a list's first page, it posts\n * the page on a `BroadcastChannel` named for the backend, the user and the\n * workspace. A tab that holds the same list (same query key) and has an\n * older copy takes it, so the new row appears there without a request.\n * - **One tab reads for the others.** Before an index-triggered refresh, a tab\n * claims the list on the channel. The other tabs hold their own refresh for\n * that list for {@link TAB_SHARE_CLAIM_MS}; the claimer's page normally\n * lands well before then. If it does not (the claimer failed or closed),\n * they refresh themselves.\n *\n * Only same-origin tabs can hear a `BroadcastChannel`, and only tabs signed in\n * as the same user to the same workspace and backend use the same channel, so\n * a page never reaches another account. Without a signed-in user, a\n * workspace, or `BroadcastChannel` (older browsers, SSR, tests), every call is\n * a no-op and each tab reads for itself, as before.\n */\nimport {\n type ConversationListPage,\n CONVERSATION_LIST_QUERY_KEY_ROOT,\n} from '@athenaintel/agent-runtime';\nimport type { QueryClient, QueryKey } from '@tanstack/react-query';\nimport { useEffect, useMemo, useRef } from 'react';\nimport { keyPartFingerprint } from '../lib/use-athena-rest-query';\n\n/** How long a claim by another tab holds this tab's own refresh of that list. */\nexport const TAB_SHARE_CLAIM_MS = 5_000;\n\nconst CHANNEL_PREFIX = 'athena-sdk:session-list:';\nconst MESSAGE_VERSION = 1;\n\ntype TabShareMessage =\n | { v: number; kind: 'page'; key: string; queryKey: QueryKey; data: ConversationListPage; updatedAt: number }\n | { v: number; kind: 'claim'; key: string };\n\nexport interface SessionListTabShare {\n /**\n * Whether another tab has claimed the list with this query key and its\n * claim still stands: when it lapses (epoch ms), or `null`.\n */\n claimedUntil(key: string): number | null;\n /** Tell the other tabs this one is reading the list now. */\n claim(key: string): void;\n}\n\nconst NO_SHARE: SessionListTabShare = {\n claimedUntil: () => null,\n claim: () => undefined,\n};\n\n/** A list's first-page query key, as the stable string the channel names it by. */\nexport function sessionListShareKey(queryKey: QueryKey): string {\n return JSON.stringify(queryKey);\n}\n\nfunction isFirstPageKey(queryKey: unknown): queryKey is QueryKey {\n return (\n Array.isArray(queryKey) &&\n queryKey[0] === CONVERSATION_LIST_QUERY_KEY_ROOT &&\n queryKey[queryKey.length - 1] === 'first-page'\n );\n}\n\nfunction isPage(value: unknown): value is ConversationListPage {\n if (typeof value !== 'object' || value === null) return false;\n const { items, hasMore } = value as Record<string, unknown>;\n return Array.isArray(items) && typeof hasMore === 'boolean';\n}\n\n/** Parse a channel message, or `null` for anything this version does not send. Exported for tests. */\nexport function parseTabShareMessage(raw: unknown): TabShareMessage | null {\n if (typeof raw !== 'object' || raw === null) return null;\n const message = raw as Record<string, unknown>;\n if (message.v !== MESSAGE_VERSION || typeof message.key !== 'string') return null;\n if (message.kind === 'claim') return { v: MESSAGE_VERSION, kind: 'claim', key: message.key };\n if (\n message.kind === 'page' &&\n isFirstPageKey(message.queryKey) &&\n sessionListShareKey(message.queryKey) === message.key &&\n isPage(message.data) &&\n typeof message.updatedAt === 'number'\n ) {\n return {\n v: MESSAGE_VERSION,\n kind: 'page',\n key: message.key,\n queryKey: message.queryKey,\n data: message.data,\n updatedAt: message.updatedAt,\n };\n }\n return null;\n}\n\n/**\n * Take a page another tab read: only into a list this tab holds, and only\n * when it is newer than this tab's copy. Returns whether it was taken.\n * Exported for tests.\n */\nexport function applySharedPage(\n queryClient: QueryClient,\n message: Extract<TabShareMessage, { kind: 'page' }>,\n): boolean {\n const state = queryClient.getQueryState(message.queryKey);\n if (!state) return false;\n if (state.dataUpdatedAt >= message.updatedAt) return false;\n queryClient.setQueryData(message.queryKey, message.data, { updatedAt: message.updatedAt });\n return true;\n}\n\n/**\n * Share this provider's session-list first pages with the user's other open\n * tabs, and hear theirs. `identity` is `null` when sharing must stay off (no\n * signed-in user or workspace known yet).\n */\nexport function useSessionListTabShare({\n queryClient,\n identity,\n}: {\n queryClient: QueryClient;\n identity: { backendUrl: string; userId: string; workspaceId: string } | null;\n}): SessionListTabShare {\n const channelName = identity\n ? `${CHANNEL_PREFIX}${keyPartFingerprint(\n [identity.backendUrl, identity.userId, identity.workspaceId].join('\\u0000'),\n )}`\n : null;\n const claims = useMemo(() => new Map<string, number>(), [channelName]);\n // The channel is opened by the effect that closes it, so each setup has its\n // own (StrictMode's setup, cleanup, setup included), and `claim` posts on\n // whichever one is open now.\n const channelRef = useRef<BroadcastChannel | null>(null);\n const isSupported = channelName !== null && typeof BroadcastChannel !== 'undefined';\n\n useEffect(() => {\n if (!channelName || typeof BroadcastChannel === 'undefined') return;\n let channel: BroadcastChannel;\n try {\n channel = new BroadcastChannel(channelName);\n } catch {\n return;\n }\n channelRef.current = channel;\n const post = (message: TabShareMessage) => {\n try {\n channel.postMessage(message);\n } catch {\n // A page that cannot be cloned or a closed channel: the other tabs read for themselves.\n }\n };\n channel.onmessage = (event: MessageEvent) => {\n const message = parseTabShareMessage(event.data);\n if (!message) return;\n if (message.kind === 'claim') {\n claims.set(message.key, Date.now() + TAB_SHARE_CLAIM_MS);\n return;\n }\n // The claim stands until it lapses: a tab whose rows the page still\n // leaves out reads for itself once it does, not all of them at once.\n applySharedPage(queryClient, message);\n };\n // Only a read that STARTED while this channel was open is shared on it.\n // The channel is named for the workspace the current credential resolved\n // to; a read started before (under the previous credential, perhaps for\n // another workspace) may still land after the switch, and its rows must\n // never reach this workspace's tabs.\n const startedHere = new Set<string>();\n const unsubscribe = queryClient.getQueryCache().subscribe((event) => {\n if (event.type === 'removed') {\n startedHere.delete(event.query.queryHash);\n return;\n }\n if (event.type !== 'updated') return;\n const { queryKey, queryHash } = event.query;\n if (!isFirstPageKey(queryKey)) return;\n if (event.action.type === 'fetch') {\n startedHere.add(queryHash);\n return;\n }\n if (event.action.type === 'error') {\n startedHere.delete(queryHash);\n return;\n }\n if (event.action.type !== 'success') return;\n // A page set by hand (one another tab shared, an optimistic patch) is not news to them.\n if ((event.action as { manual?: boolean }).manual) return;\n if (!startedHere.delete(queryHash)) return;\n if (!isPage(event.query.state.data)) return;\n post({\n v: MESSAGE_VERSION,\n kind: 'page',\n key: sessionListShareKey(queryKey),\n queryKey,\n data: event.query.state.data,\n updatedAt: event.query.state.dataUpdatedAt,\n });\n });\n return () => {\n unsubscribe();\n if (channelRef.current === channel) channelRef.current = null;\n channel.onmessage = null;\n channel.close();\n };\n }, [channelName, claims, queryClient]);\n\n return useMemo<SessionListTabShare>(() => {\n if (!isSupported) return NO_SHARE;\n return {\n claimedUntil: (key) => {\n const until = claims.get(key);\n if (until === undefined) return null;\n if (until <= Date.now()) {\n claims.delete(key);\n return null;\n }\n return until;\n },\n claim: (key) => {\n try {\n channelRef.current?.postMessage({\n v: MESSAGE_VERSION,\n kind: 'claim',\n key,\n } satisfies TabShareMessage);\n } catch {\n // Closed: nothing to coordinate with.\n }\n },\n };\n }, [isSupported, claims]);\n}\n"],"names":["CONVERSATION_LIST_QUERY_KEY_ROOT","keyPartFingerprint","useMemo","useRef","useEffect"],"mappings":"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"}
@@ -0,0 +1,73 @@
1
+ /**
2
+ * Open tabs of one signed-in user share their session-list reads.
3
+ *
4
+ * A pushed conversation-index change reaches every open tab at once, and each
5
+ * one used to re-read the same lists. With this in place:
6
+ *
7
+ * - **Pages are shared.** Whenever a tab reads a list's first page, it posts
8
+ * the page on a `BroadcastChannel` named for the backend, the user and the
9
+ * workspace. A tab that holds the same list (same query key) and has an
10
+ * older copy takes it, so the new row appears there without a request.
11
+ * - **One tab reads for the others.** Before an index-triggered refresh, a tab
12
+ * claims the list on the channel. The other tabs hold their own refresh for
13
+ * that list for {@link TAB_SHARE_CLAIM_MS}; the claimer's page normally
14
+ * lands well before then. If it does not (the claimer failed or closed),
15
+ * they refresh themselves.
16
+ *
17
+ * Only same-origin tabs can hear a `BroadcastChannel`, and only tabs signed in
18
+ * as the same user to the same workspace and backend use the same channel, so
19
+ * a page never reaches another account. Without a signed-in user, a
20
+ * workspace, or `BroadcastChannel` (older browsers, SSR, tests), every call is
21
+ * a no-op and each tab reads for itself, as before.
22
+ */
23
+ import { type ConversationListPage } from '../agent-runtime/src/index';
24
+ import type { QueryClient, QueryKey } from '@tanstack/react-query';
25
+ /** How long a claim by another tab holds this tab's own refresh of that list. */
26
+ export declare const TAB_SHARE_CLAIM_MS = 5000;
27
+ type TabShareMessage = {
28
+ v: number;
29
+ kind: 'page';
30
+ key: string;
31
+ queryKey: QueryKey;
32
+ data: ConversationListPage;
33
+ updatedAt: number;
34
+ } | {
35
+ v: number;
36
+ kind: 'claim';
37
+ key: string;
38
+ };
39
+ export interface SessionListTabShare {
40
+ /**
41
+ * Whether another tab has claimed the list with this query key and its
42
+ * claim still stands: when it lapses (epoch ms), or `null`.
43
+ */
44
+ claimedUntil(key: string): number | null;
45
+ /** Tell the other tabs this one is reading the list now. */
46
+ claim(key: string): void;
47
+ }
48
+ /** A list's first-page query key, as the stable string the channel names it by. */
49
+ export declare function sessionListShareKey(queryKey: QueryKey): string;
50
+ /** Parse a channel message, or `null` for anything this version does not send. Exported for tests. */
51
+ export declare function parseTabShareMessage(raw: unknown): TabShareMessage | null;
52
+ /**
53
+ * Take a page another tab read: only into a list this tab holds, and only
54
+ * when it is newer than this tab's copy. Returns whether it was taken.
55
+ * Exported for tests.
56
+ */
57
+ export declare function applySharedPage(queryClient: QueryClient, message: Extract<TabShareMessage, {
58
+ kind: 'page';
59
+ }>): boolean;
60
+ /**
61
+ * Share this provider's session-list first pages with the user's other open
62
+ * tabs, and hear theirs. `identity` is `null` when sharing must stay off (no
63
+ * signed-in user or workspace known yet).
64
+ */
65
+ export declare function useSessionListTabShare({ queryClient, identity, }: {
66
+ queryClient: QueryClient;
67
+ identity: {
68
+ backendUrl: string;
69
+ userId: string;
70
+ workspaceId: string;
71
+ } | null;
72
+ }): SessionListTabShare;
73
+ export {};
@@ -0,0 +1,150 @@
1
+ import { useMemo, useRef, useEffect } from "react";
2
+ import { keyPartFingerprint } from "../lib/use-athena-rest-query.js";
3
+ import { CONVERSATION_LIST_QUERY_KEY_ROOT } from "../agent-runtime/src/conversation-list.js";
4
+ const TAB_SHARE_CLAIM_MS = 5e3;
5
+ const CHANNEL_PREFIX = "athena-sdk:session-list:";
6
+ const MESSAGE_VERSION = 1;
7
+ const NO_SHARE = {
8
+ claimedUntil: () => null,
9
+ claim: () => void 0
10
+ };
11
+ function sessionListShareKey(queryKey) {
12
+ return JSON.stringify(queryKey);
13
+ }
14
+ function isFirstPageKey(queryKey) {
15
+ return Array.isArray(queryKey) && queryKey[0] === CONVERSATION_LIST_QUERY_KEY_ROOT && queryKey[queryKey.length - 1] === "first-page";
16
+ }
17
+ function isPage(value) {
18
+ if (typeof value !== "object" || value === null) return false;
19
+ const { items, hasMore } = value;
20
+ return Array.isArray(items) && typeof hasMore === "boolean";
21
+ }
22
+ function parseTabShareMessage(raw) {
23
+ if (typeof raw !== "object" || raw === null) return null;
24
+ const message = raw;
25
+ if (message.v !== MESSAGE_VERSION || typeof message.key !== "string") return null;
26
+ if (message.kind === "claim") return { v: MESSAGE_VERSION, kind: "claim", key: message.key };
27
+ if (message.kind === "page" && isFirstPageKey(message.queryKey) && sessionListShareKey(message.queryKey) === message.key && isPage(message.data) && typeof message.updatedAt === "number") {
28
+ return {
29
+ v: MESSAGE_VERSION,
30
+ kind: "page",
31
+ key: message.key,
32
+ queryKey: message.queryKey,
33
+ data: message.data,
34
+ updatedAt: message.updatedAt
35
+ };
36
+ }
37
+ return null;
38
+ }
39
+ function applySharedPage(queryClient, message) {
40
+ const state = queryClient.getQueryState(message.queryKey);
41
+ if (!state) return false;
42
+ if (state.dataUpdatedAt >= message.updatedAt) return false;
43
+ queryClient.setQueryData(message.queryKey, message.data, { updatedAt: message.updatedAt });
44
+ return true;
45
+ }
46
+ function useSessionListTabShare({
47
+ queryClient,
48
+ identity
49
+ }) {
50
+ const channelName = identity ? `${CHANNEL_PREFIX}${keyPartFingerprint(
51
+ [identity.backendUrl, identity.userId, identity.workspaceId].join("\0")
52
+ )}` : null;
53
+ const claims = useMemo(() => /* @__PURE__ */ new Map(), [channelName]);
54
+ const channelRef = useRef(null);
55
+ const isSupported = channelName !== null && typeof BroadcastChannel !== "undefined";
56
+ useEffect(() => {
57
+ if (!channelName || typeof BroadcastChannel === "undefined") return;
58
+ let channel;
59
+ try {
60
+ channel = new BroadcastChannel(channelName);
61
+ } catch {
62
+ return;
63
+ }
64
+ channelRef.current = channel;
65
+ const post = (message) => {
66
+ try {
67
+ channel.postMessage(message);
68
+ } catch {
69
+ }
70
+ };
71
+ channel.onmessage = (event) => {
72
+ const message = parseTabShareMessage(event.data);
73
+ if (!message) return;
74
+ if (message.kind === "claim") {
75
+ claims.set(message.key, Date.now() + TAB_SHARE_CLAIM_MS);
76
+ return;
77
+ }
78
+ applySharedPage(queryClient, message);
79
+ };
80
+ const startedHere = /* @__PURE__ */ new Set();
81
+ const unsubscribe = queryClient.getQueryCache().subscribe((event) => {
82
+ if (event.type === "removed") {
83
+ startedHere.delete(event.query.queryHash);
84
+ return;
85
+ }
86
+ if (event.type !== "updated") return;
87
+ const { queryKey, queryHash } = event.query;
88
+ if (!isFirstPageKey(queryKey)) return;
89
+ if (event.action.type === "fetch") {
90
+ startedHere.add(queryHash);
91
+ return;
92
+ }
93
+ if (event.action.type === "error") {
94
+ startedHere.delete(queryHash);
95
+ return;
96
+ }
97
+ if (event.action.type !== "success") return;
98
+ if (event.action.manual) return;
99
+ if (!startedHere.delete(queryHash)) return;
100
+ if (!isPage(event.query.state.data)) return;
101
+ post({
102
+ v: MESSAGE_VERSION,
103
+ kind: "page",
104
+ key: sessionListShareKey(queryKey),
105
+ queryKey,
106
+ data: event.query.state.data,
107
+ updatedAt: event.query.state.dataUpdatedAt
108
+ });
109
+ });
110
+ return () => {
111
+ unsubscribe();
112
+ if (channelRef.current === channel) channelRef.current = null;
113
+ channel.onmessage = null;
114
+ channel.close();
115
+ };
116
+ }, [channelName, claims, queryClient]);
117
+ return useMemo(() => {
118
+ if (!isSupported) return NO_SHARE;
119
+ return {
120
+ claimedUntil: (key) => {
121
+ const until = claims.get(key);
122
+ if (until === void 0) return null;
123
+ if (until <= Date.now()) {
124
+ claims.delete(key);
125
+ return null;
126
+ }
127
+ return until;
128
+ },
129
+ claim: (key) => {
130
+ var _a;
131
+ try {
132
+ (_a = channelRef.current) == null ? void 0 : _a.postMessage({
133
+ v: MESSAGE_VERSION,
134
+ kind: "claim",
135
+ key
136
+ });
137
+ } catch {
138
+ }
139
+ }
140
+ };
141
+ }, [isSupported, claims]);
142
+ }
143
+ export {
144
+ TAB_SHARE_CLAIM_MS,
145
+ applySharedPage,
146
+ parseTabShareMessage,
147
+ sessionListShareKey,
148
+ useSessionListTabShare
149
+ };
150
+ //# sourceMappingURL=session-list-tab-share.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"session-list-tab-share.js","sources":["../../src/threads/session-list-tab-share.ts"],"sourcesContent":["/**\n * Open tabs of one signed-in user share their session-list reads.\n *\n * A pushed conversation-index change reaches every open tab at once, and each\n * one used to re-read the same lists. With this in place:\n *\n * - **Pages are shared.** Whenever a tab reads a list's first page, it posts\n * the page on a `BroadcastChannel` named for the backend, the user and the\n * workspace. A tab that holds the same list (same query key) and has an\n * older copy takes it, so the new row appears there without a request.\n * - **One tab reads for the others.** Before an index-triggered refresh, a tab\n * claims the list on the channel. The other tabs hold their own refresh for\n * that list for {@link TAB_SHARE_CLAIM_MS}; the claimer's page normally\n * lands well before then. If it does not (the claimer failed or closed),\n * they refresh themselves.\n *\n * Only same-origin tabs can hear a `BroadcastChannel`, and only tabs signed in\n * as the same user to the same workspace and backend use the same channel, so\n * a page never reaches another account. Without a signed-in user, a\n * workspace, or `BroadcastChannel` (older browsers, SSR, tests), every call is\n * a no-op and each tab reads for itself, as before.\n */\nimport {\n type ConversationListPage,\n CONVERSATION_LIST_QUERY_KEY_ROOT,\n} from '@athenaintel/agent-runtime';\nimport type { QueryClient, QueryKey } from '@tanstack/react-query';\nimport { useEffect, useMemo, useRef } from 'react';\nimport { keyPartFingerprint } from '../lib/use-athena-rest-query';\n\n/** How long a claim by another tab holds this tab's own refresh of that list. */\nexport const TAB_SHARE_CLAIM_MS = 5_000;\n\nconst CHANNEL_PREFIX = 'athena-sdk:session-list:';\nconst MESSAGE_VERSION = 1;\n\ntype TabShareMessage =\n | { v: number; kind: 'page'; key: string; queryKey: QueryKey; data: ConversationListPage; updatedAt: number }\n | { v: number; kind: 'claim'; key: string };\n\nexport interface SessionListTabShare {\n /**\n * Whether another tab has claimed the list with this query key and its\n * claim still stands: when it lapses (epoch ms), or `null`.\n */\n claimedUntil(key: string): number | null;\n /** Tell the other tabs this one is reading the list now. */\n claim(key: string): void;\n}\n\nconst NO_SHARE: SessionListTabShare = {\n claimedUntil: () => null,\n claim: () => undefined,\n};\n\n/** A list's first-page query key, as the stable string the channel names it by. */\nexport function sessionListShareKey(queryKey: QueryKey): string {\n return JSON.stringify(queryKey);\n}\n\nfunction isFirstPageKey(queryKey: unknown): queryKey is QueryKey {\n return (\n Array.isArray(queryKey) &&\n queryKey[0] === CONVERSATION_LIST_QUERY_KEY_ROOT &&\n queryKey[queryKey.length - 1] === 'first-page'\n );\n}\n\nfunction isPage(value: unknown): value is ConversationListPage {\n if (typeof value !== 'object' || value === null) return false;\n const { items, hasMore } = value as Record<string, unknown>;\n return Array.isArray(items) && typeof hasMore === 'boolean';\n}\n\n/** Parse a channel message, or `null` for anything this version does not send. Exported for tests. */\nexport function parseTabShareMessage(raw: unknown): TabShareMessage | null {\n if (typeof raw !== 'object' || raw === null) return null;\n const message = raw as Record<string, unknown>;\n if (message.v !== MESSAGE_VERSION || typeof message.key !== 'string') return null;\n if (message.kind === 'claim') return { v: MESSAGE_VERSION, kind: 'claim', key: message.key };\n if (\n message.kind === 'page' &&\n isFirstPageKey(message.queryKey) &&\n sessionListShareKey(message.queryKey) === message.key &&\n isPage(message.data) &&\n typeof message.updatedAt === 'number'\n ) {\n return {\n v: MESSAGE_VERSION,\n kind: 'page',\n key: message.key,\n queryKey: message.queryKey,\n data: message.data,\n updatedAt: message.updatedAt,\n };\n }\n return null;\n}\n\n/**\n * Take a page another tab read: only into a list this tab holds, and only\n * when it is newer than this tab's copy. Returns whether it was taken.\n * Exported for tests.\n */\nexport function applySharedPage(\n queryClient: QueryClient,\n message: Extract<TabShareMessage, { kind: 'page' }>,\n): boolean {\n const state = queryClient.getQueryState(message.queryKey);\n if (!state) return false;\n if (state.dataUpdatedAt >= message.updatedAt) return false;\n queryClient.setQueryData(message.queryKey, message.data, { updatedAt: message.updatedAt });\n return true;\n}\n\n/**\n * Share this provider's session-list first pages with the user's other open\n * tabs, and hear theirs. `identity` is `null` when sharing must stay off (no\n * signed-in user or workspace known yet).\n */\nexport function useSessionListTabShare({\n queryClient,\n identity,\n}: {\n queryClient: QueryClient;\n identity: { backendUrl: string; userId: string; workspaceId: string } | null;\n}): SessionListTabShare {\n const channelName = identity\n ? `${CHANNEL_PREFIX}${keyPartFingerprint(\n [identity.backendUrl, identity.userId, identity.workspaceId].join('\\u0000'),\n )}`\n : null;\n const claims = useMemo(() => new Map<string, number>(), [channelName]);\n // The channel is opened by the effect that closes it, so each setup has its\n // own (StrictMode's setup, cleanup, setup included), and `claim` posts on\n // whichever one is open now.\n const channelRef = useRef<BroadcastChannel | null>(null);\n const isSupported = channelName !== null && typeof BroadcastChannel !== 'undefined';\n\n useEffect(() => {\n if (!channelName || typeof BroadcastChannel === 'undefined') return;\n let channel: BroadcastChannel;\n try {\n channel = new BroadcastChannel(channelName);\n } catch {\n return;\n }\n channelRef.current = channel;\n const post = (message: TabShareMessage) => {\n try {\n channel.postMessage(message);\n } catch {\n // A page that cannot be cloned or a closed channel: the other tabs read for themselves.\n }\n };\n channel.onmessage = (event: MessageEvent) => {\n const message = parseTabShareMessage(event.data);\n if (!message) return;\n if (message.kind === 'claim') {\n claims.set(message.key, Date.now() + TAB_SHARE_CLAIM_MS);\n return;\n }\n // The claim stands until it lapses: a tab whose rows the page still\n // leaves out reads for itself once it does, not all of them at once.\n applySharedPage(queryClient, message);\n };\n // Only a read that STARTED while this channel was open is shared on it.\n // The channel is named for the workspace the current credential resolved\n // to; a read started before (under the previous credential, perhaps for\n // another workspace) may still land after the switch, and its rows must\n // never reach this workspace's tabs.\n const startedHere = new Set<string>();\n const unsubscribe = queryClient.getQueryCache().subscribe((event) => {\n if (event.type === 'removed') {\n startedHere.delete(event.query.queryHash);\n return;\n }\n if (event.type !== 'updated') return;\n const { queryKey, queryHash } = event.query;\n if (!isFirstPageKey(queryKey)) return;\n if (event.action.type === 'fetch') {\n startedHere.add(queryHash);\n return;\n }\n if (event.action.type === 'error') {\n startedHere.delete(queryHash);\n return;\n }\n if (event.action.type !== 'success') return;\n // A page set by hand (one another tab shared, an optimistic patch) is not news to them.\n if ((event.action as { manual?: boolean }).manual) return;\n if (!startedHere.delete(queryHash)) return;\n if (!isPage(event.query.state.data)) return;\n post({\n v: MESSAGE_VERSION,\n kind: 'page',\n key: sessionListShareKey(queryKey),\n queryKey,\n data: event.query.state.data,\n updatedAt: event.query.state.dataUpdatedAt,\n });\n });\n return () => {\n unsubscribe();\n if (channelRef.current === channel) channelRef.current = null;\n channel.onmessage = null;\n channel.close();\n };\n }, [channelName, claims, queryClient]);\n\n return useMemo<SessionListTabShare>(() => {\n if (!isSupported) return NO_SHARE;\n return {\n claimedUntil: (key) => {\n const until = claims.get(key);\n if (until === undefined) return null;\n if (until <= Date.now()) {\n claims.delete(key);\n return null;\n }\n return until;\n },\n claim: (key) => {\n try {\n channelRef.current?.postMessage({\n v: MESSAGE_VERSION,\n kind: 'claim',\n key,\n } satisfies TabShareMessage);\n } catch {\n // Closed: nothing to coordinate with.\n }\n },\n };\n }, [isSupported, claims]);\n}\n"],"names":[],"mappings":"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"}
@@ -4,7 +4,7 @@
4
4
  * attention-toned status chip, and a labelled icon action that never selects
5
5
  * its row.
6
6
  */
7
- import type { ConversationPullRequest } from '@athenaintel/agent-runtime';
7
+ import type { ConversationPullRequest } from '../agent-runtime/src/index';
8
8
  import type { FC, MouseEvent, ReactNode } from 'react';
9
9
  import { type PullRequestChip as PullRequestChipModel } from './session-list-model';
10
10
  import type { SessionStatusTone } from './sessions-page-model';
@@ -13,7 +13,7 @@
13
13
  * applied at all on that server (`unavailable`: the UI disables those
14
14
  * controls).
15
15
  */
16
- import type { ConversationSummary } from '@athenaintel/agent-runtime';
16
+ import type { ConversationSummary } from '../agent-runtime/src/index';
17
17
  import type { ThreadListFilterBody } from './api';
18
18
  export type AthenaSessionsSort = 'updated' | 'created';
19
19
  export type AthenaSessionsDirection = 'desc' | 'asc';