@athenaintel/react 0.57.2 → 0.60.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 (852) hide show
  1. package/README.md +795 -12
  2. package/dist/agent-runtime/src/addressed-agents.cjs +16 -0
  3. package/dist/agent-runtime/src/addressed-agents.cjs.map +1 -0
  4. package/dist/agent-runtime/src/addressed-agents.d.ts +30 -0
  5. package/dist/agent-runtime/src/addressed-agents.js +16 -0
  6. package/dist/agent-runtime/src/addressed-agents.js.map +1 -0
  7. package/dist/agent-runtime/src/answer-label.cjs +4 -3
  8. package/dist/agent-runtime/src/answer-label.cjs.map +1 -1
  9. package/dist/agent-runtime/src/answer-label.d.ts +13 -6
  10. package/dist/agent-runtime/src/answer-label.js +4 -3
  11. package/dist/agent-runtime/src/answer-label.js.map +1 -1
  12. package/dist/agent-runtime/src/chat-outbox-attachments.cjs.map +1 -1
  13. package/dist/agent-runtime/src/chat-outbox-attachments.d.ts +1 -1
  14. package/dist/agent-runtime/src/chat-outbox-attachments.js.map +1 -1
  15. package/dist/agent-runtime/src/chat-outbox-entry.cjs +101 -0
  16. package/dist/agent-runtime/src/chat-outbox-entry.cjs.map +1 -0
  17. package/dist/agent-runtime/src/chat-outbox-entry.d.ts +99 -0
  18. package/dist/agent-runtime/src/chat-outbox-entry.js +101 -0
  19. package/dist/agent-runtime/src/chat-outbox-entry.js.map +1 -0
  20. package/dist/agent-runtime/src/chat-outbox-legacy.cjs +252 -0
  21. package/dist/agent-runtime/src/chat-outbox-legacy.cjs.map +1 -0
  22. package/dist/agent-runtime/src/chat-outbox-legacy.d.ts +96 -0
  23. package/dist/agent-runtime/src/chat-outbox-legacy.js +252 -0
  24. package/dist/agent-runtime/src/chat-outbox-legacy.js.map +1 -0
  25. package/dist/agent-runtime/src/chat-outbox-policy.cjs +30 -0
  26. package/dist/agent-runtime/src/chat-outbox-policy.cjs.map +1 -0
  27. package/dist/agent-runtime/src/chat-outbox-policy.d.ts +42 -0
  28. package/dist/agent-runtime/src/chat-outbox-policy.js +30 -0
  29. package/dist/agent-runtime/src/chat-outbox-policy.js.map +1 -0
  30. package/dist/agent-runtime/src/chat-outbox-storage.cjs +306 -0
  31. package/dist/agent-runtime/src/chat-outbox-storage.cjs.map +1 -0
  32. package/dist/agent-runtime/src/chat-outbox-storage.d.ts +194 -0
  33. package/dist/agent-runtime/src/chat-outbox-storage.js +306 -0
  34. package/dist/agent-runtime/src/chat-outbox-storage.js.map +1 -0
  35. package/dist/agent-runtime/src/chat-outbox-thread.cjs +21 -94
  36. package/dist/agent-runtime/src/chat-outbox-thread.cjs.map +1 -1
  37. package/dist/agent-runtime/src/chat-outbox-thread.d.ts +22 -18
  38. package/dist/agent-runtime/src/chat-outbox-thread.js +21 -94
  39. package/dist/agent-runtime/src/chat-outbox-thread.js.map +1 -1
  40. package/dist/agent-runtime/src/chat-outbox.cjs +492 -547
  41. package/dist/agent-runtime/src/chat-outbox.cjs.map +1 -1
  42. package/dist/agent-runtime/src/chat-outbox.d.ts +110 -142
  43. package/dist/agent-runtime/src/chat-outbox.js +492 -547
  44. package/dist/agent-runtime/src/chat-outbox.js.map +1 -1
  45. package/dist/agent-runtime/src/composer-markdown.cjs +0 -16
  46. package/dist/agent-runtime/src/composer-markdown.cjs.map +1 -1
  47. package/dist/agent-runtime/src/composer-markdown.d.ts +1 -1
  48. package/dist/agent-runtime/src/composer-markdown.js +1 -17
  49. package/dist/agent-runtime/src/composer-markdown.js.map +1 -1
  50. package/dist/agent-runtime/src/deep-agent-transport-recipe.cjs +3 -1
  51. package/dist/agent-runtime/src/deep-agent-transport-recipe.cjs.map +1 -1
  52. package/dist/agent-runtime/src/deep-agent-transport-recipe.d.ts +8 -1
  53. package/dist/agent-runtime/src/deep-agent-transport-recipe.js +3 -1
  54. package/dist/agent-runtime/src/deep-agent-transport-recipe.js.map +1 -1
  55. package/dist/agent-runtime/src/dictation-preferences.d.ts +356 -0
  56. package/dist/agent-runtime/src/dictation-record.d.ts +279 -0
  57. package/dist/agent-runtime/src/dictation-session.d.ts +106 -7
  58. package/dist/agent-runtime/src/dictation-snippets.d.ts +9 -0
  59. package/dist/agent-runtime/src/dictation-transfer.d.ts +142 -0
  60. package/dist/agent-runtime/src/edit-command.cjs.map +1 -1
  61. package/dist/agent-runtime/src/edit-command.d.ts +1 -1
  62. package/dist/agent-runtime/src/edit-command.js.map +1 -1
  63. package/dist/agent-runtime/src/errors.cjs +1 -0
  64. package/dist/agent-runtime/src/errors.cjs.map +1 -1
  65. package/dist/agent-runtime/src/errors.js +1 -0
  66. package/dist/agent-runtime/src/errors.js.map +1 -1
  67. package/dist/agent-runtime/src/generated/runconfig-contract.cjs +24 -0
  68. package/dist/agent-runtime/src/generated/runconfig-contract.cjs.map +1 -1
  69. package/dist/agent-runtime/src/generated/runconfig-contract.d.ts +3 -3
  70. package/dist/agent-runtime/src/generated/runconfig-contract.js +24 -0
  71. package/dist/agent-runtime/src/generated/runconfig-contract.js.map +1 -1
  72. package/dist/agent-runtime/src/index.d.ts +14 -8
  73. package/dist/agent-runtime/src/lane-follow.cjs +289 -0
  74. package/dist/agent-runtime/src/lane-follow.cjs.map +1 -0
  75. package/dist/agent-runtime/src/lane-follow.js +289 -0
  76. package/dist/agent-runtime/src/lane-follow.js.map +1 -0
  77. package/dist/agent-runtime/src/lane-images.cjs +387 -0
  78. package/dist/agent-runtime/src/lane-images.cjs.map +1 -0
  79. package/dist/agent-runtime/src/lane-images.js +387 -0
  80. package/dist/agent-runtime/src/lane-images.js.map +1 -0
  81. package/dist/agent-runtime/src/message-window.js +1 -1
  82. package/dist/agent-runtime/src/messages.cjs +19 -1
  83. package/dist/agent-runtime/src/messages.cjs.map +1 -1
  84. package/dist/agent-runtime/src/messages.d.ts +8 -0
  85. package/dist/agent-runtime/src/messages.js +21 -3
  86. package/dist/agent-runtime/src/messages.js.map +1 -1
  87. package/dist/agent-runtime/src/named-agents.cjs +301 -0
  88. package/dist/agent-runtime/src/named-agents.cjs.map +1 -0
  89. package/dist/agent-runtime/src/named-agents.d.ts +246 -0
  90. package/dist/agent-runtime/src/named-agents.js +301 -0
  91. package/dist/agent-runtime/src/named-agents.js.map +1 -0
  92. package/dist/agent-runtime/src/offline-status.cjs.map +1 -1
  93. package/dist/agent-runtime/src/offline-status.d.ts +93 -2
  94. package/dist/agent-runtime/src/offline-status.js.map +1 -1
  95. package/dist/agent-runtime/src/ptc-subcalls.cjs +41 -0
  96. package/dist/agent-runtime/src/ptc-subcalls.cjs.map +1 -0
  97. package/dist/agent-runtime/src/ptc-subcalls.js +41 -0
  98. package/dist/agent-runtime/src/ptc-subcalls.js.map +1 -0
  99. package/dist/agent-runtime/src/queue.cjs +2 -2
  100. package/dist/agent-runtime/src/queue.cjs.map +1 -1
  101. package/dist/agent-runtime/src/queue.d.ts +20 -25
  102. package/dist/agent-runtime/src/queue.js +2 -2
  103. package/dist/agent-runtime/src/queue.js.map +1 -1
  104. package/dist/agent-runtime/src/quota-safe-local-storage-session.cjs +314 -84
  105. package/dist/agent-runtime/src/quota-safe-local-storage-session.cjs.map +1 -1
  106. package/dist/agent-runtime/src/quota-safe-local-storage-session.d.ts +137 -40
  107. package/dist/agent-runtime/src/quota-safe-local-storage-session.js +318 -88
  108. package/dist/agent-runtime/src/quota-safe-local-storage-session.js.map +1 -1
  109. package/dist/agent-runtime/src/run-send.cjs +54 -0
  110. package/dist/agent-runtime/src/run-send.cjs.map +1 -0
  111. package/dist/agent-runtime/src/run-send.d.ts +51 -0
  112. package/dist/agent-runtime/src/run-send.js +54 -0
  113. package/dist/agent-runtime/src/run-send.js.map +1 -0
  114. package/dist/agent-runtime/src/running-tool-placeholder.cjs +6 -0
  115. package/dist/agent-runtime/src/running-tool-placeholder.cjs.map +1 -1
  116. package/dist/agent-runtime/src/running-tool-placeholder.js +6 -0
  117. package/dist/agent-runtime/src/running-tool-placeholder.js.map +1 -1
  118. package/dist/agent-runtime/src/runtime.d.ts +9 -5
  119. package/dist/agent-runtime/src/sealed-idb.cjs +64 -0
  120. package/dist/agent-runtime/src/sealed-idb.cjs.map +1 -1
  121. package/dist/agent-runtime/src/sealed-idb.d.ts +16 -0
  122. package/dist/agent-runtime/src/sealed-idb.js +64 -0
  123. package/dist/agent-runtime/src/sealed-idb.js.map +1 -1
  124. package/dist/agent-runtime/src/send-recovery.cjs +90 -118
  125. package/dist/agent-runtime/src/send-recovery.cjs.map +1 -1
  126. package/dist/agent-runtime/src/send-recovery.d.ts +25 -29
  127. package/dist/agent-runtime/src/send-recovery.js +90 -118
  128. package/dist/agent-runtime/src/send-recovery.js.map +1 -1
  129. package/dist/agent-runtime/src/statewire-diagnostics.d.ts +4 -1
  130. package/dist/agent-runtime/src/statewire-held-sends.cjs +191 -0
  131. package/dist/agent-runtime/src/statewire-held-sends.cjs.map +1 -0
  132. package/dist/agent-runtime/src/statewire-held-sends.d.ts +119 -0
  133. package/dist/agent-runtime/src/statewire-held-sends.js +191 -0
  134. package/dist/agent-runtime/src/statewire-held-sends.js.map +1 -0
  135. package/dist/agent-runtime/src/statewire-state.cjs +4 -0
  136. package/dist/agent-runtime/src/statewire-state.cjs.map +1 -1
  137. package/dist/agent-runtime/src/statewire-state.js +4 -0
  138. package/dist/agent-runtime/src/statewire-state.js.map +1 -1
  139. package/dist/agent-runtime/src/statewire-transport.cjs +8 -2
  140. package/dist/agent-runtime/src/statewire-transport.cjs.map +1 -1
  141. package/dist/agent-runtime/src/statewire-transport.d.ts +14 -5
  142. package/dist/agent-runtime/src/statewire-transport.js +8 -2
  143. package/dist/agent-runtime/src/statewire-transport.js.map +1 -1
  144. package/dist/agent-runtime/src/subagent-transcripts.cjs +1 -23
  145. package/dist/agent-runtime/src/subagent-transcripts.cjs.map +1 -1
  146. package/dist/agent-runtime/src/subagent-transcripts.js +3 -25
  147. package/dist/agent-runtime/src/subagent-transcripts.js.map +1 -1
  148. package/dist/agent-runtime/src/subagents.cjs +22 -29
  149. package/dist/agent-runtime/src/subagents.cjs.map +1 -1
  150. package/dist/agent-runtime/src/subagents.js +23 -30
  151. package/dist/agent-runtime/src/subagents.js.map +1 -1
  152. package/dist/agent-runtime/src/thread-extras.cjs +27 -19
  153. package/dist/agent-runtime/src/thread-extras.cjs.map +1 -1
  154. package/dist/agent-runtime/src/thread-extras.d.ts +19 -6
  155. package/dist/agent-runtime/src/thread-extras.js +27 -19
  156. package/dist/agent-runtime/src/thread-extras.js.map +1 -1
  157. package/dist/agent-runtime/src/thread-handoff-flow-machine.d.ts +8 -8
  158. package/dist/agent-runtime/src/tool-metadata.cjs +19 -0
  159. package/dist/agent-runtime/src/tool-metadata.cjs.map +1 -1
  160. package/dist/agent-runtime/src/tool-metadata.js +19 -0
  161. package/dist/agent-runtime/src/tool-metadata.js.map +1 -1
  162. package/dist/agent-runtime/src/tool-names.cjs +21 -0
  163. package/dist/agent-runtime/src/tool-names.cjs.map +1 -1
  164. package/dist/agent-runtime/src/tool-names.d.ts +8 -0
  165. package/dist/agent-runtime/src/tool-names.js +21 -0
  166. package/dist/agent-runtime/src/tool-names.js.map +1 -1
  167. package/dist/agent-runtime/src/typed-interrupt-kinds.cjs +247 -0
  168. package/dist/agent-runtime/src/typed-interrupt-kinds.cjs.map +1 -0
  169. package/dist/agent-runtime/src/typed-interrupt-kinds.d.ts +173 -0
  170. package/dist/agent-runtime/src/typed-interrupt-kinds.js +247 -0
  171. package/dist/agent-runtime/src/typed-interrupt-kinds.js.map +1 -0
  172. package/dist/agent-runtime/src/typed-interrupts.cjs +48 -0
  173. package/dist/agent-runtime/src/typed-interrupts.cjs.map +1 -0
  174. package/dist/agent-runtime/src/typed-interrupts.d.ts +75 -0
  175. package/dist/agent-runtime/src/typed-interrupts.js +48 -0
  176. package/dist/agent-runtime/src/typed-interrupts.js.map +1 -0
  177. package/dist/agent-runtime/src/types.d.ts +1 -1
  178. package/dist/agent-runtime/src/use-conversation-list.cjs +1 -0
  179. package/dist/agent-runtime/src/use-conversation-list.cjs.map +1 -1
  180. package/dist/agent-runtime/src/use-conversation-list.d.ts +7 -0
  181. package/dist/agent-runtime/src/use-conversation-list.js +1 -0
  182. package/dist/agent-runtime/src/use-conversation-list.js.map +1 -1
  183. package/dist/agent-runtime/src/use-deep-agent-chat-outbox.cjs +46 -29
  184. package/dist/agent-runtime/src/use-deep-agent-chat-outbox.cjs.map +1 -1
  185. package/dist/agent-runtime/src/use-deep-agent-chat-outbox.d.ts +14 -22
  186. package/dist/agent-runtime/src/use-deep-agent-chat-outbox.js +46 -29
  187. package/dist/agent-runtime/src/use-deep-agent-chat-outbox.js.map +1 -1
  188. package/dist/agent-runtime/src/use-deep-agent-runtime.cjs +78 -14
  189. package/dist/agent-runtime/src/use-deep-agent-runtime.cjs.map +1 -1
  190. package/dist/agent-runtime/src/use-deep-agent-runtime.d.ts +34 -7
  191. package/dist/agent-runtime/src/use-deep-agent-runtime.js +79 -15
  192. package/dist/agent-runtime/src/use-deep-agent-runtime.js.map +1 -1
  193. package/dist/agent-runtime/src/use-deep-agent-thread.cjs +16 -1
  194. package/dist/agent-runtime/src/use-deep-agent-thread.cjs.map +1 -1
  195. package/dist/agent-runtime/src/use-deep-agent-thread.d.ts +7 -2
  196. package/dist/agent-runtime/src/use-deep-agent-thread.js +16 -1
  197. package/dist/agent-runtime/src/use-deep-agent-thread.js.map +1 -1
  198. package/dist/agent-runtime/src/use-deep-agent-voice.cjs +30 -4
  199. package/dist/agent-runtime/src/use-deep-agent-voice.cjs.map +1 -1
  200. package/dist/agent-runtime/src/use-deep-agent-voice.d.ts +22 -4
  201. package/dist/agent-runtime/src/use-deep-agent-voice.js +30 -4
  202. package/dist/agent-runtime/src/use-deep-agent-voice.js.map +1 -1
  203. package/dist/agent-runtime/src/withdrawn-turns.d.ts +5 -4
  204. package/dist/agent-runtime/src/word-device-fit.d.ts +174 -0
  205. package/dist/agent-runtime/src/work-in.d.ts +127 -0
  206. package/dist/assets/AthenaAssetEmbed.cjs.map +1 -1
  207. package/dist/assets/AthenaAssetEmbed.d.ts +6 -1
  208. package/dist/assets/AthenaAssetEmbed.js.map +1 -1
  209. package/dist/assets/asset-panel-store.cjs +13 -5
  210. package/dist/assets/asset-panel-store.cjs.map +1 -1
  211. package/dist/assets/asset-panel-store.d.ts +33 -2
  212. package/dist/assets/asset-panel-store.js +13 -5
  213. package/dist/assets/asset-panel-store.js.map +1 -1
  214. package/dist/auth/AthenaCredentialSourceContext.cjs +11 -0
  215. package/dist/auth/AthenaCredentialSourceContext.cjs.map +1 -1
  216. package/dist/auth/AthenaCredentialSourceContext.d.ts +6 -0
  217. package/dist/auth/AthenaCredentialSourceContext.js +11 -0
  218. package/dist/auth/AthenaCredentialSourceContext.js.map +1 -1
  219. package/dist/auth/account-identity.cjs +13 -2
  220. package/dist/auth/account-identity.cjs.map +1 -1
  221. package/dist/auth/account-identity.d.ts +9 -0
  222. package/dist/auth/account-identity.js +13 -2
  223. package/dist/auth/account-identity.js.map +1 -1
  224. package/dist/auth/credential-source.cjs +20 -4
  225. package/dist/auth/credential-source.cjs.map +1 -1
  226. package/dist/auth/credential-source.d.ts +9 -0
  227. package/dist/auth/credential-source.js +20 -4
  228. package/dist/auth/credential-source.js.map +1 -1
  229. package/dist/catalog/chat-pickers.cjs +31 -0
  230. package/dist/catalog/chat-pickers.cjs.map +1 -1
  231. package/dist/catalog/chat-pickers.d.ts +17 -0
  232. package/dist/catalog/chat-pickers.js +33 -2
  233. package/dist/catalog/chat-pickers.js.map +1 -1
  234. package/dist/catalog/runtime-catalog.cjs +63 -3
  235. package/dist/catalog/runtime-catalog.cjs.map +1 -1
  236. package/dist/catalog/runtime-catalog.d.ts +63 -3
  237. package/dist/catalog/runtime-catalog.js +64 -4
  238. package/dist/catalog/runtime-catalog.js.map +1 -1
  239. package/dist/chat/AthenaChat.cjs +301 -98
  240. package/dist/chat/AthenaChat.cjs.map +1 -1
  241. package/dist/chat/AthenaChat.d.ts +80 -4
  242. package/dist/chat/AthenaChat.js +302 -99
  243. package/dist/chat/AthenaChat.js.map +1 -1
  244. package/dist/chat/StatewireApprovalCard.cjs +35 -5
  245. package/dist/chat/StatewireApprovalCard.cjs.map +1 -1
  246. package/dist/chat/StatewireApprovalCard.d.ts +55 -2
  247. package/dist/chat/StatewireApprovalCard.js +37 -7
  248. package/dist/chat/StatewireApprovalCard.js.map +1 -1
  249. package/dist/chat/StatewireQueuedMessages.cjs +17 -2
  250. package/dist/chat/StatewireQueuedMessages.cjs.map +1 -1
  251. package/dist/chat/StatewireQueuedMessages.d.ts +8 -45
  252. package/dist/chat/StatewireQueuedMessages.js +18 -3
  253. package/dist/chat/StatewireQueuedMessages.js.map +1 -1
  254. package/dist/chat/chat-agent-mentions.cjs +70 -0
  255. package/dist/chat/chat-agent-mentions.cjs.map +1 -0
  256. package/dist/chat/chat-agent-mentions.d.ts +13 -0
  257. package/dist/chat/chat-agent-mentions.js +70 -0
  258. package/dist/chat/chat-agent-mentions.js.map +1 -0
  259. package/dist/chat/composer-actions.cjs +12 -0
  260. package/dist/chat/composer-actions.cjs.map +1 -0
  261. package/dist/chat/composer-actions.d.ts +22 -0
  262. package/dist/chat/composer-actions.js +12 -0
  263. package/dist/chat/composer-actions.js.map +1 -0
  264. package/dist/chat/follow-up-suggestions.cjs +185 -0
  265. package/dist/chat/follow-up-suggestions.cjs.map +1 -0
  266. package/dist/chat/follow-up-suggestions.d.ts +64 -0
  267. package/dist/chat/follow-up-suggestions.js +185 -0
  268. package/dist/chat/follow-up-suggestions.js.map +1 -0
  269. package/dist/chat/super-grouping/ToolTimeline.cjs +4 -3
  270. package/dist/chat/super-grouping/ToolTimeline.cjs.map +1 -1
  271. package/dist/chat/super-grouping/ToolTimeline.d.ts +7 -3
  272. package/dist/chat/super-grouping/ToolTimeline.js +4 -3
  273. package/dist/chat/super-grouping/ToolTimeline.js.map +1 -1
  274. package/dist/chat/turn-changes.cjs +284 -0
  275. package/dist/chat/turn-changes.cjs.map +1 -0
  276. package/dist/chat/turn-changes.d.ts +130 -0
  277. package/dist/chat/turn-changes.js +284 -0
  278. package/dist/chat/turn-changes.js.map +1 -0
  279. package/dist/chat/typed-interrupts/StatewireTypedInterruptCard.cjs +31 -0
  280. package/dist/chat/typed-interrupts/StatewireTypedInterruptCard.cjs.map +1 -0
  281. package/dist/chat/typed-interrupts/StatewireTypedInterruptCard.d.ts +31 -0
  282. package/dist/chat/typed-interrupts/StatewireTypedInterruptCard.js +31 -0
  283. package/dist/chat/typed-interrupts/StatewireTypedInterruptCard.js.map +1 -0
  284. package/dist/chat/typed-interrupts/approval-cards.cjs +250 -0
  285. package/dist/chat/typed-interrupts/approval-cards.cjs.map +1 -0
  286. package/dist/chat/typed-interrupts/approval-cards.d.ts +22 -0
  287. package/dist/chat/typed-interrupts/approval-cards.js +250 -0
  288. package/dist/chat/typed-interrupts/approval-cards.js.map +1 -0
  289. package/dist/chat/typed-interrupts/form-cards.cjs +289 -0
  290. package/dist/chat/typed-interrupts/form-cards.cjs.map +1 -0
  291. package/dist/chat/typed-interrupts/form-cards.d.ts +6 -0
  292. package/dist/chat/typed-interrupts/form-cards.js +289 -0
  293. package/dist/chat/typed-interrupts/form-cards.js.map +1 -0
  294. package/dist/chat/typed-interrupts/interrupt-card-shell.cjs +182 -0
  295. package/dist/chat/typed-interrupts/interrupt-card-shell.cjs.map +1 -0
  296. package/dist/chat/typed-interrupts/interrupt-card-shell.d.ts +47 -0
  297. package/dist/chat/typed-interrupts/interrupt-card-shell.js +182 -0
  298. package/dist/chat/typed-interrupts/interrupt-card-shell.js.map +1 -0
  299. package/dist/chat/typed-interrupts/json-schema-form.cjs +388 -0
  300. package/dist/chat/typed-interrupts/json-schema-form.cjs.map +1 -0
  301. package/dist/chat/typed-interrupts/json-schema-form.d.ts +33 -0
  302. package/dist/chat/typed-interrupts/json-schema-form.js +388 -0
  303. package/dist/chat/typed-interrupts/json-schema-form.js.map +1 -0
  304. package/dist/chat/typed-interrupts/questionnaire-card.cjs +449 -0
  305. package/dist/chat/typed-interrupts/questionnaire-card.cjs.map +1 -0
  306. package/dist/chat/typed-interrupts/questionnaire-card.d.ts +20 -0
  307. package/dist/chat/typed-interrupts/questionnaire-card.js +449 -0
  308. package/dist/chat/typed-interrupts/questionnaire-card.js.map +1 -0
  309. package/dist/chat/typed-interrupts/request-file-card.cjs +159 -0
  310. package/dist/chat/typed-interrupts/request-file-card.cjs.map +1 -0
  311. package/dist/chat/typed-interrupts/request-file-card.d.ts +2 -0
  312. package/dist/chat/typed-interrupts/request-file-card.js +159 -0
  313. package/dist/chat/typed-interrupts/request-file-card.js.map +1 -0
  314. package/dist/chat/typed-interrupts/toolkit-selection-card.cjs +189 -0
  315. package/dist/chat/typed-interrupts/toolkit-selection-card.cjs.map +1 -0
  316. package/dist/chat/typed-interrupts/toolkit-selection-card.d.ts +23 -0
  317. package/dist/chat/typed-interrupts/toolkit-selection-card.js +189 -0
  318. package/dist/chat/typed-interrupts/toolkit-selection-card.js.map +1 -0
  319. package/dist/chat/typed-interrupts/typed-interrupt-body.cjs +26 -0
  320. package/dist/chat/typed-interrupts/typed-interrupt-body.cjs.map +1 -0
  321. package/dist/chat/typed-interrupts/typed-interrupt-body.d.ts +3 -0
  322. package/dist/chat/typed-interrupts/typed-interrupt-body.js +26 -0
  323. package/dist/chat/typed-interrupts/typed-interrupt-body.js.map +1 -0
  324. package/dist/chat/typed-interrupts/typed-interrupt-graphql.cjs +105 -0
  325. package/dist/chat/typed-interrupts/typed-interrupt-graphql.cjs.map +1 -0
  326. package/dist/chat/typed-interrupts/typed-interrupt-graphql.d.ts +29 -0
  327. package/dist/chat/typed-interrupts/typed-interrupt-graphql.js +105 -0
  328. package/dist/chat/typed-interrupts/typed-interrupt-graphql.js.map +1 -0
  329. package/dist/chat/typed-interrupts/typed-interrupt-notice.cjs +70 -0
  330. package/dist/chat/typed-interrupts/typed-interrupt-notice.cjs.map +1 -0
  331. package/dist/chat/typed-interrupts/typed-interrupt-notice.d.ts +45 -0
  332. package/dist/chat/typed-interrupts/typed-interrupt-notice.js +70 -0
  333. package/dist/chat/typed-interrupts/typed-interrupt-notice.js.map +1 -0
  334. package/dist/chat/typed-interrupts/typed-interrupt-panel.cjs +76 -0
  335. package/dist/chat/typed-interrupts/typed-interrupt-panel.cjs.map +1 -0
  336. package/dist/chat/typed-interrupts/typed-interrupt-panel.d.ts +11 -0
  337. package/dist/chat/typed-interrupts/typed-interrupt-panel.js +76 -0
  338. package/dist/chat/typed-interrupts/typed-interrupt-panel.js.map +1 -0
  339. package/dist/chat/typed-interrupts/typed-interrupt-types.d.ts +46 -0
  340. package/dist/chat/typed-interrupts/use-interrupt-draft.cjs +106 -0
  341. package/dist/chat/typed-interrupts/use-interrupt-draft.cjs.map +1 -0
  342. package/dist/chat/typed-interrupts/use-interrupt-draft.d.ts +29 -0
  343. package/dist/chat/typed-interrupts/use-interrupt-draft.js +106 -0
  344. package/dist/chat/typed-interrupts/use-interrupt-draft.js.map +1 -0
  345. package/dist/chat/typed-interrupts/use-statewire-typed-interrupt.cjs +231 -0
  346. package/dist/chat/typed-interrupts/use-statewire-typed-interrupt.cjs.map +1 -0
  347. package/dist/chat/typed-interrupts/use-statewire-typed-interrupt.d.ts +66 -0
  348. package/dist/chat/typed-interrupts/use-statewire-typed-interrupt.js +231 -0
  349. package/dist/chat/typed-interrupts/use-statewire-typed-interrupt.js.map +1 -0
  350. package/dist/chat-ui/composer/composer-named-agents.cjs +13 -0
  351. package/dist/chat-ui/composer/composer-named-agents.cjs.map +1 -0
  352. package/dist/chat-ui/composer/composer-named-agents.d.ts +20 -0
  353. package/dist/chat-ui/composer/composer-named-agents.js +13 -0
  354. package/dist/chat-ui/composer/composer-named-agents.js.map +1 -0
  355. package/dist/chat-ui/composer/slash-command-menu.cjs +143 -0
  356. package/dist/chat-ui/composer/slash-command-menu.cjs.map +1 -0
  357. package/dist/chat-ui/composer/slash-command-menu.d.ts +19 -0
  358. package/dist/chat-ui/composer/slash-command-menu.js +143 -0
  359. package/dist/chat-ui/composer/slash-command-menu.js.map +1 -0
  360. package/dist/chat-ui/composer/slash-commands-extension.cjs +51 -0
  361. package/dist/chat-ui/composer/slash-commands-extension.cjs.map +1 -0
  362. package/dist/chat-ui/composer/slash-commands-extension.d.ts +39 -0
  363. package/dist/chat-ui/composer/slash-commands-extension.js +51 -0
  364. package/dist/chat-ui/composer/slash-commands-extension.js.map +1 -0
  365. package/dist/chat-ui/composer/slash-commands.cjs +74 -0
  366. package/dist/chat-ui/composer/slash-commands.cjs.map +1 -0
  367. package/dist/chat-ui/composer/slash-commands.d.ts +82 -0
  368. package/dist/chat-ui/composer/slash-commands.js +74 -0
  369. package/dist/chat-ui/composer/slash-commands.js.map +1 -0
  370. package/dist/chat-ui/composer/tiptap-composer.cjs +135 -9
  371. package/dist/chat-ui/composer/tiptap-composer.cjs.map +1 -1
  372. package/dist/chat-ui/composer/tiptap-composer.d.ts +61 -2
  373. package/dist/chat-ui/composer/tiptap-composer.js +135 -9
  374. package/dist/chat-ui/composer/tiptap-composer.js.map +1 -1
  375. package/dist/chat-ui/index.cjs +5 -0
  376. package/dist/chat-ui/index.cjs.map +1 -1
  377. package/dist/chat-ui/index.d.ts +4 -2
  378. package/dist/chat-ui/index.js +5 -0
  379. package/dist/chat-ui/index.js.map +1 -1
  380. package/dist/chat-ui/mentions/mention-chip.cjs +10 -4
  381. package/dist/chat-ui/mentions/mention-chip.cjs.map +1 -1
  382. package/dist/chat-ui/mentions/mention-chip.js +11 -5
  383. package/dist/chat-ui/mentions/mention-chip.js.map +1 -1
  384. package/dist/chat-ui/mentions/mention-extension.cjs +8 -1
  385. package/dist/chat-ui/mentions/mention-extension.cjs.map +1 -1
  386. package/dist/chat-ui/mentions/mention-extension.js +8 -1
  387. package/dist/chat-ui/mentions/mention-extension.js.map +1 -1
  388. package/dist/chat-ui/mentions/suggestions/components/get-scope-name.cjs +1 -0
  389. package/dist/chat-ui/mentions/suggestions/components/get-scope-name.cjs.map +1 -1
  390. package/dist/chat-ui/mentions/suggestions/components/get-scope-name.js +1 -0
  391. package/dist/chat-ui/mentions/suggestions/components/get-scope-name.js.map +1 -1
  392. package/dist/chat-ui/mentions/suggestions/components/mention-icon.cjs +20 -2
  393. package/dist/chat-ui/mentions/suggestions/components/mention-icon.cjs.map +1 -1
  394. package/dist/chat-ui/mentions/suggestions/components/mention-icon.d.ts +10 -1
  395. package/dist/chat-ui/mentions/suggestions/components/mention-icon.js +22 -4
  396. package/dist/chat-ui/mentions/suggestions/components/mention-icon.js.map +1 -1
  397. package/dist/chat-ui/mentions/suggestions/components/menu-item.cjs +1 -1
  398. package/dist/chat-ui/mentions/suggestions/components/menu-item.cjs.map +1 -1
  399. package/dist/chat-ui/mentions/suggestions/components/menu-item.js +1 -1
  400. package/dist/chat-ui/mentions/suggestions/components/menu-item.js.map +1 -1
  401. package/dist/chat-ui/mentions/suggestions/data/api-client.cjs +45 -0
  402. package/dist/chat-ui/mentions/suggestions/data/api-client.cjs.map +1 -1
  403. package/dist/chat-ui/mentions/suggestions/data/api-client.d.ts +48 -0
  404. package/dist/chat-ui/mentions/suggestions/data/api-client.js +45 -0
  405. package/dist/chat-ui/mentions/suggestions/data/api-client.js.map +1 -1
  406. package/dist/chat-ui/mentions/suggestions/data/sources/asset-type-icon-names.generated.cjs +89 -0
  407. package/dist/chat-ui/mentions/suggestions/data/sources/asset-type-icon-names.generated.cjs.map +1 -0
  408. package/dist/chat-ui/mentions/suggestions/data/sources/asset-type-icon-names.generated.d.ts +8 -0
  409. package/dist/chat-ui/mentions/suggestions/data/sources/asset-type-icon-names.generated.js +89 -0
  410. package/dist/chat-ui/mentions/suggestions/data/sources/asset-type-icon-names.generated.js.map +1 -0
  411. package/dist/chat-ui/mentions/suggestions/data/sources/asset-type-icons.cjs +140 -116
  412. package/dist/chat-ui/mentions/suggestions/data/sources/asset-type-icons.cjs.map +1 -1
  413. package/dist/chat-ui/mentions/suggestions/data/sources/asset-type-icons.d.ts +46 -12
  414. package/dist/chat-ui/mentions/suggestions/data/sources/asset-type-icons.js +141 -117
  415. package/dist/chat-ui/mentions/suggestions/data/sources/asset-type-icons.js.map +1 -1
  416. package/dist/chat-ui/mentions/suggestions/data/sources/index.cjs +272 -25
  417. package/dist/chat-ui/mentions/suggestions/data/sources/index.cjs.map +1 -1
  418. package/dist/chat-ui/mentions/suggestions/data/sources/index.d.ts +88 -10
  419. package/dist/chat-ui/mentions/suggestions/data/sources/index.js +274 -27
  420. package/dist/chat-ui/mentions/suggestions/data/sources/index.js.map +1 -1
  421. package/dist/chat-ui/mentions/suggestions/data/types.cjs.map +1 -1
  422. package/dist/chat-ui/mentions/suggestions/data/types.d.ts +27 -1
  423. package/dist/chat-ui/mentions/suggestions/data/types.js.map +1 -1
  424. package/dist/chat-ui/mentions/suggestions/data/use-mention-suggestions.cjs +56 -5
  425. package/dist/chat-ui/mentions/suggestions/data/use-mention-suggestions.cjs.map +1 -1
  426. package/dist/chat-ui/mentions/suggestions/data/use-mention-suggestions.d.ts +26 -6
  427. package/dist/chat-ui/mentions/suggestions/data/use-mention-suggestions.js +57 -6
  428. package/dist/chat-ui/mentions/suggestions/data/use-mention-suggestions.js.map +1 -1
  429. package/dist/chat-ui/mentions/suggestions/mention-suggestions.extension.cjs +34 -17
  430. package/dist/chat-ui/mentions/suggestions/mention-suggestions.extension.cjs.map +1 -1
  431. package/dist/chat-ui/mentions/suggestions/mention-suggestions.extension.d.ts +19 -1
  432. package/dist/chat-ui/mentions/suggestions/mention-suggestions.extension.js +35 -18
  433. package/dist/chat-ui/mentions/suggestions/mention-suggestions.extension.js.map +1 -1
  434. package/dist/chat-ui/mentions/use-asset-icon-app-url.cjs +12 -0
  435. package/dist/chat-ui/mentions/use-asset-icon-app-url.cjs.map +1 -0
  436. package/dist/chat-ui/mentions/use-asset-icon-app-url.d.ts +8 -0
  437. package/dist/chat-ui/mentions/use-asset-icon-app-url.js +12 -0
  438. package/dist/chat-ui/mentions/use-asset-icon-app-url.js.map +1 -0
  439. package/dist/chat-ui/statewire.d.ts +1 -1
  440. package/dist/chat-ui/thread/statewire-history-edge.cjs +15 -0
  441. package/dist/chat-ui/thread/statewire-history-edge.cjs.map +1 -1
  442. package/dist/chat-ui/thread/statewire-history-edge.d.ts +4 -1
  443. package/dist/chat-ui/thread/statewire-history-edge.js +15 -0
  444. package/dist/chat-ui/thread/statewire-history-edge.js.map +1 -1
  445. package/dist/collab/client.cjs +41 -6
  446. package/dist/collab/client.cjs.map +1 -1
  447. package/dist/collab/client.d.ts +38 -7
  448. package/dist/collab/client.js +41 -6
  449. package/dist/collab/client.js.map +1 -1
  450. package/dist/composer/ComposerAttachedReferences.cjs +119 -0
  451. package/dist/composer/ComposerAttachedReferences.cjs.map +1 -0
  452. package/dist/composer/ComposerAttachedReferences.d.ts +26 -0
  453. package/dist/composer/ComposerAttachedReferences.js +119 -0
  454. package/dist/composer/ComposerAttachedReferences.js.map +1 -0
  455. package/dist/composer/ComposerNamedAgents.cjs +63 -0
  456. package/dist/composer/ComposerNamedAgents.cjs.map +1 -0
  457. package/dist/composer/ComposerNamedAgents.d.ts +16 -0
  458. package/dist/composer/ComposerNamedAgents.js +63 -0
  459. package/dist/composer/ComposerNamedAgents.js.map +1 -0
  460. package/dist/composer/attached-references.cjs +159 -0
  461. package/dist/composer/attached-references.cjs.map +1 -0
  462. package/dist/composer/attached-references.d.ts +86 -0
  463. package/dist/composer/attached-references.js +159 -0
  464. package/dist/composer/attached-references.js.map +1 -0
  465. package/dist/composer/build-composed-message.cjs +14 -7
  466. package/dist/composer/build-composed-message.cjs.map +1 -1
  467. package/dist/composer/build-composed-message.d.ts +6 -1
  468. package/dist/composer/build-composed-message.js +14 -7
  469. package/dist/composer/build-composed-message.js.map +1 -1
  470. package/dist/composer/composer-handoff.cjs +6 -2
  471. package/dist/composer/composer-handoff.cjs.map +1 -1
  472. package/dist/composer/composer-handoff.d.ts +7 -1
  473. package/dist/composer/composer-handoff.js +6 -2
  474. package/dist/composer/composer-handoff.js.map +1 -1
  475. package/dist/composer/folder-upload.cjs +149 -0
  476. package/dist/composer/folder-upload.cjs.map +1 -0
  477. package/dist/composer/folder-upload.d.ts +79 -0
  478. package/dist/composer/folder-upload.js +149 -0
  479. package/dist/composer/folder-upload.js.map +1 -0
  480. package/dist/composer/index.d.ts +1 -1
  481. package/dist/composer/staged-message-metadata.cjs +12 -0
  482. package/dist/composer/staged-message-metadata.cjs.map +1 -0
  483. package/dist/composer/staged-message-metadata.d.ts +15 -0
  484. package/dist/composer/staged-message-metadata.js +12 -0
  485. package/dist/composer/staged-message-metadata.js.map +1 -0
  486. package/dist/composer/useAttachToChat.cjs +35 -0
  487. package/dist/composer/useAttachToChat.cjs.map +1 -0
  488. package/dist/composer/useAttachToChat.d.ts +54 -0
  489. package/dist/composer/useAttachToChat.js +35 -0
  490. package/dist/composer/useAttachToChat.js.map +1 -0
  491. package/dist/composer/useAttachedReferencesComposerProps.cjs +19 -0
  492. package/dist/composer/useAttachedReferencesComposerProps.cjs.map +1 -0
  493. package/dist/composer/useAttachedReferencesComposerProps.d.ts +12 -0
  494. package/dist/composer/useAttachedReferencesComposerProps.js +19 -0
  495. package/dist/composer/useAttachedReferencesComposerProps.js.map +1 -0
  496. package/dist/composer/useFileUpload.cjs +95 -7
  497. package/dist/composer/useFileUpload.cjs.map +1 -1
  498. package/dist/composer/useFileUpload.d.ts +21 -2
  499. package/dist/composer/useFileUpload.js +95 -7
  500. package/dist/composer/useFileUpload.js.map +1 -1
  501. package/dist/data/athena-api-error.cjs +125 -0
  502. package/dist/data/athena-api-error.cjs.map +1 -0
  503. package/dist/data/athena-api-error.d.ts +96 -0
  504. package/dist/data/athena-api-error.js +125 -0
  505. package/dist/data/athena-api-error.js.map +1 -0
  506. package/dist/data/athena-data-client.cjs +106 -0
  507. package/dist/data/athena-data-client.cjs.map +1 -0
  508. package/dist/data/athena-data-client.d.ts +74 -0
  509. package/dist/data/athena-data-client.js +106 -0
  510. package/dist/data/athena-data-client.js.map +1 -0
  511. package/dist/data/athena-member.cjs +93 -0
  512. package/dist/data/athena-member.cjs.map +1 -0
  513. package/dist/data/athena-member.d.ts +125 -0
  514. package/dist/data/athena-member.js +93 -0
  515. package/dist/data/athena-member.js.map +1 -0
  516. package/dist/data/athena-request.cjs +460 -0
  517. package/dist/data/athena-request.cjs.map +1 -0
  518. package/dist/data/athena-request.d.ts +120 -0
  519. package/dist/data/athena-request.js +460 -0
  520. package/dist/data/athena-request.js.map +1 -0
  521. package/dist/data/use-athena-fetch.cjs +14 -0
  522. package/dist/data/use-athena-fetch.cjs.map +1 -0
  523. package/dist/data/use-athena-fetch.d.ts +19 -0
  524. package/dist/data/use-athena-fetch.js +14 -0
  525. package/dist/data/use-athena-fetch.js.map +1 -0
  526. package/dist/data/use-athena-graphql.cjs +66 -0
  527. package/dist/data/use-athena-graphql.cjs.map +1 -0
  528. package/dist/data/use-athena-graphql.d.ts +56 -0
  529. package/dist/data/use-athena-graphql.js +66 -0
  530. package/dist/data/use-athena-graphql.js.map +1 -0
  531. package/dist/data/use-athena-rest.cjs +33 -0
  532. package/dist/data/use-athena-rest.cjs.map +1 -0
  533. package/dist/data/use-athena-rest.d.ts +21 -0
  534. package/dist/data/use-athena-rest.js +33 -0
  535. package/dist/data/use-athena-rest.js.map +1 -0
  536. package/dist/data/use-semantic-query.cjs +44 -0
  537. package/dist/data/use-semantic-query.cjs.map +1 -0
  538. package/dist/data/use-semantic-query.d.ts +92 -0
  539. package/dist/data/use-semantic-query.js +44 -0
  540. package/dist/data/use-semantic-query.js.map +1 -0
  541. package/dist/diagnostics/athena-diagnostics.cjs.map +1 -1
  542. package/dist/diagnostics/athena-diagnostics.d.ts +5 -1
  543. package/dist/diagnostics/athena-diagnostics.js.map +1 -1
  544. package/dist/diagnostics/errors.cjs +7 -0
  545. package/dist/diagnostics/errors.cjs.map +1 -1
  546. package/dist/diagnostics/errors.d.ts +7 -0
  547. package/dist/diagnostics/errors.js +7 -0
  548. package/dist/diagnostics/errors.js.map +1 -1
  549. package/dist/index.cjs +155 -11
  550. package/dist/index.cjs.map +1 -1
  551. package/dist/index.d.ts +72 -13
  552. package/dist/index.js +148 -4
  553. package/dist/index.js.map +1 -1
  554. package/dist/keryx-http/src/initial-sync.cjs +64 -16
  555. package/dist/keryx-http/src/initial-sync.cjs.map +1 -1
  556. package/dist/keryx-http/src/initial-sync.d.ts +31 -1
  557. package/dist/keryx-http/src/initial-sync.js +64 -16
  558. package/dist/keryx-http/src/initial-sync.js.map +1 -1
  559. package/dist/keryx-http/src/own-awareness.cjs +20 -0
  560. package/dist/keryx-http/src/own-awareness.cjs.map +1 -0
  561. package/dist/keryx-http/src/own-awareness.d.ts +50 -0
  562. package/dist/keryx-http/src/own-awareness.js +20 -0
  563. package/dist/keryx-http/src/own-awareness.js.map +1 -0
  564. package/dist/keryx-http/src/update-attributions.cjs +26 -1
  565. package/dist/keryx-http/src/update-attributions.cjs.map +1 -1
  566. package/dist/keryx-http/src/update-attributions.d.ts +10 -1
  567. package/dist/keryx-http/src/update-attributions.js +26 -1
  568. package/dist/keryx-http/src/update-attributions.js.map +1 -1
  569. package/dist/offline/chat-outbox.cjs +262 -26
  570. package/dist/offline/chat-outbox.cjs.map +1 -1
  571. package/dist/offline/chat-outbox.d.ts +90 -12
  572. package/dist/offline/chat-outbox.js +263 -27
  573. package/dist/offline/chat-outbox.js.map +1 -1
  574. package/dist/provider/AthenaProvider.cjs +60 -22
  575. package/dist/provider/AthenaProvider.cjs.map +1 -1
  576. package/dist/provider/AthenaProvider.d.ts +24 -8
  577. package/dist/provider/AthenaProvider.js +61 -23
  578. package/dist/provider/AthenaProvider.js.map +1 -1
  579. package/dist/react/package.json.cjs +1 -1
  580. package/dist/react/package.json.js +1 -1
  581. package/dist/references/src/anchors/parse.cjs +11 -1
  582. package/dist/references/src/anchors/parse.cjs.map +1 -1
  583. package/dist/references/src/anchors/parse.js +11 -1
  584. package/dist/references/src/anchors/parse.js.map +1 -1
  585. package/dist/references/src/anchors/schemas.d.ts +1 -0
  586. package/dist/references/src/anchors/serialize.cjs +1 -0
  587. package/dist/references/src/anchors/serialize.cjs.map +1 -1
  588. package/dist/references/src/anchors/serialize.js +1 -0
  589. package/dist/references/src/anchors/serialize.js.map +1 -1
  590. package/dist/references/src/anchors/types.cjs +5 -0
  591. package/dist/references/src/anchors/types.cjs.map +1 -1
  592. package/dist/references/src/anchors/types.d.ts +9 -0
  593. package/dist/references/src/anchors/types.js +5 -0
  594. package/dist/references/src/anchors/types.js.map +1 -1
  595. package/dist/references/src/attachable.cjs +149 -0
  596. package/dist/references/src/attachable.cjs.map +1 -0
  597. package/dist/references/src/attachable.d.ts +87 -0
  598. package/dist/references/src/attachable.js +149 -0
  599. package/dist/references/src/attachable.js.map +1 -0
  600. package/dist/references/src/schemas.d.ts +2 -0
  601. package/dist/runtime/StatewirePlanModeLaneSync.cjs +93 -0
  602. package/dist/runtime/StatewirePlanModeLaneSync.cjs.map +1 -0
  603. package/dist/runtime/StatewirePlanModeLaneSync.d.ts +34 -0
  604. package/dist/runtime/StatewirePlanModeLaneSync.js +93 -0
  605. package/dist/runtime/StatewirePlanModeLaneSync.js.map +1 -0
  606. package/dist/runtime/StatewireThreadConfigLaneSync.cjs +2 -0
  607. package/dist/runtime/StatewireThreadConfigLaneSync.cjs.map +1 -1
  608. package/dist/runtime/StatewireThreadConfigLaneSync.d.ts +4 -0
  609. package/dist/runtime/StatewireThreadConfigLaneSync.js +2 -0
  610. package/dist/runtime/StatewireThreadConfigLaneSync.js.map +1 -1
  611. package/dist/runtime/statewire-plan-mode.cjs +71 -0
  612. package/dist/runtime/statewire-plan-mode.cjs.map +1 -0
  613. package/dist/runtime/statewire-plan-mode.d.ts +88 -0
  614. package/dist/runtime/statewire-plan-mode.js +71 -0
  615. package/dist/runtime/statewire-plan-mode.js.map +1 -0
  616. package/dist/runtime/statewire-run-config.cjs +3 -1
  617. package/dist/runtime/statewire-run-config.cjs.map +1 -1
  618. package/dist/runtime/statewire-run-config.d.ts +7 -0
  619. package/dist/runtime/statewire-run-config.js +3 -1
  620. package/dist/runtime/statewire-run-config.js.map +1 -1
  621. package/dist/runtime/statewire-session-key.cjs +11 -5
  622. package/dist/runtime/statewire-session-key.cjs.map +1 -1
  623. package/dist/runtime/statewire-session-key.d.ts +22 -10
  624. package/dist/runtime/statewire-session-key.js +11 -5
  625. package/dist/runtime/statewire-session-key.js.map +1 -1
  626. package/dist/runtime/useAthenaStatewireRuntime.cjs +64 -9
  627. package/dist/runtime/useAthenaStatewireRuntime.cjs.map +1 -1
  628. package/dist/runtime/useAthenaStatewireRuntime.d.ts +26 -10
  629. package/dist/runtime/useAthenaStatewireRuntime.js +66 -11
  630. package/dist/runtime/useAthenaStatewireRuntime.js.map +1 -1
  631. package/dist/search/useAthenaAssets.cjs +394 -0
  632. package/dist/search/useAthenaAssets.cjs.map +1 -0
  633. package/dist/search/useAthenaAssets.d.ts +186 -0
  634. package/dist/search/useAthenaAssets.js +394 -0
  635. package/dist/search/useAthenaAssets.js.map +1 -0
  636. package/dist/sheet-range/index.cjs +4 -0
  637. package/dist/sheet-range/index.cjs.map +1 -1
  638. package/dist/sheet-range/index.d.ts +4 -2
  639. package/dist/sheet-range/index.js +4 -0
  640. package/dist/sheet-range/index.js.map +1 -1
  641. package/dist/sheet-range/query-range.cjs +102 -0
  642. package/dist/sheet-range/query-range.cjs.map +1 -0
  643. package/dist/sheet-range/query-range.d.ts +46 -0
  644. package/dist/sheet-range/query-range.js +102 -0
  645. package/dist/sheet-range/query-range.js.map +1 -0
  646. package/dist/styles.css +1 -1
  647. package/dist/subagents/index.cjs +49 -0
  648. package/dist/subagents/index.cjs.map +1 -0
  649. package/dist/subagents/index.d.ts +16 -0
  650. package/dist/subagents/index.js +49 -0
  651. package/dist/subagents/index.js.map +1 -0
  652. package/dist/subagents/lane-follow.cjs +19 -0
  653. package/dist/subagents/lane-follow.cjs.map +1 -0
  654. package/dist/subagents/lane-follow.d.ts +9 -0
  655. package/dist/subagents/lane-follow.js +19 -0
  656. package/dist/subagents/lane-follow.js.map +1 -0
  657. package/dist/subagents/lane-model.cjs +178 -0
  658. package/dist/subagents/lane-model.cjs.map +1 -0
  659. package/dist/subagents/lane-model.d.ts +140 -0
  660. package/dist/subagents/lane-model.js +178 -0
  661. package/dist/subagents/lane-model.js.map +1 -0
  662. package/dist/subagents/lane-parts.cjs +517 -0
  663. package/dist/subagents/lane-parts.cjs.map +1 -0
  664. package/dist/subagents/lane-parts.d.ts +130 -0
  665. package/dist/subagents/lane-parts.js +517 -0
  666. package/dist/subagents/lane-parts.js.map +1 -0
  667. package/dist/subagents/subagent-lane-group.cjs +215 -0
  668. package/dist/subagents/subagent-lane-group.cjs.map +1 -0
  669. package/dist/subagents/subagent-lane-group.d.ts +67 -0
  670. package/dist/subagents/subagent-lane-group.js +215 -0
  671. package/dist/subagents/subagent-lane-group.js.map +1 -0
  672. package/dist/subagents/subagent-transcript-drawer.cjs +431 -0
  673. package/dist/subagents/subagent-transcript-drawer.cjs.map +1 -0
  674. package/dist/subagents/subagent-transcript-drawer.d.ts +78 -0
  675. package/dist/subagents/subagent-transcript-drawer.js +431 -0
  676. package/dist/subagents/subagent-transcript-drawer.js.map +1 -0
  677. package/dist/subagents/task-subagent-group.cjs +115 -0
  678. package/dist/subagents/task-subagent-group.cjs.map +1 -0
  679. package/dist/subagents/task-subagent-group.d.ts +36 -0
  680. package/dist/subagents/task-subagent-group.js +115 -0
  681. package/dist/subagents/task-subagent-group.js.map +1 -0
  682. package/dist/subagents/use-omitted-images-in-view.cjs +68 -0
  683. package/dist/subagents/use-omitted-images-in-view.cjs.map +1 -0
  684. package/dist/subagents/use-omitted-images-in-view.d.ts +21 -0
  685. package/dist/subagents/use-omitted-images-in-view.js +68 -0
  686. package/dist/subagents/use-omitted-images-in-view.js.map +1 -0
  687. package/dist/threads/Inbox.cjs +2 -2
  688. package/dist/threads/Inbox.cjs.map +1 -1
  689. package/dist/threads/SessionList.cjs +6 -6
  690. package/dist/threads/SessionList.cjs.map +1 -1
  691. package/dist/threads/SessionsPage.cjs +13 -7
  692. package/dist/threads/SessionsPage.cjs.map +1 -1
  693. package/dist/threads/SessionsPage.d.ts +10 -1
  694. package/dist/threads/SessionsPage.js +9 -3
  695. package/dist/threads/SessionsPage.js.map +1 -1
  696. package/dist/threads/session-list-model.cjs.map +1 -1
  697. package/dist/threads/session-list-model.d.ts +2 -1
  698. package/dist/threads/session-list-model.js.map +1 -1
  699. package/dist/threads/session-row-parts.cjs +3 -3
  700. package/dist/threads/session-row-parts.cjs.map +1 -1
  701. package/dist/threads/sessions-page-model.cjs +13 -5
  702. package/dist/threads/sessions-page-model.cjs.map +1 -1
  703. package/dist/threads/sessions-page-model.d.ts +7 -0
  704. package/dist/threads/sessions-page-model.js +11 -3
  705. package/dist/threads/sessions-page-model.js.map +1 -1
  706. package/dist/threads/sessions-page-storage.cjs +8 -8
  707. package/dist/threads/sessions-page-storage.cjs.map +1 -1
  708. package/dist/threads/sessions-page-storage.d.ts +5 -1
  709. package/dist/threads/sessions-page-storage.js +8 -8
  710. package/dist/threads/sessions-page-storage.js.map +1 -1
  711. package/dist/threads/statewire-thread-list.cjs +14 -2
  712. package/dist/threads/statewire-thread-list.cjs.map +1 -1
  713. package/dist/threads/statewire-thread-list.d.ts +11 -2
  714. package/dist/threads/statewire-thread-list.js +14 -2
  715. package/dist/threads/statewire-thread-list.js.map +1 -1
  716. package/dist/threads/use-athena-sessions.cjs +1 -0
  717. package/dist/threads/use-athena-sessions.cjs.map +1 -1
  718. package/dist/threads/use-athena-sessions.d.ts +7 -0
  719. package/dist/threads/use-athena-sessions.js +1 -0
  720. package/dist/threads/use-athena-sessions.js.map +1 -1
  721. package/dist/threads/use-athena-thread-agent.cjs +31 -0
  722. package/dist/threads/use-athena-thread-agent.cjs.map +1 -0
  723. package/dist/threads/use-athena-thread-agent.d.ts +38 -0
  724. package/dist/threads/use-athena-thread-agent.js +31 -0
  725. package/dist/threads/use-athena-thread-agent.js.map +1 -0
  726. package/dist/threads/use-athena-thread-plan-mode.cjs +18 -0
  727. package/dist/threads/use-athena-thread-plan-mode.cjs.map +1 -0
  728. package/dist/threads/use-athena-thread-plan-mode.d.ts +18 -0
  729. package/dist/threads/use-athena-thread-plan-mode.js +18 -0
  730. package/dist/threads/use-athena-thread-plan-mode.js.map +1 -0
  731. package/dist/threads/use-rest-conversation-history.d.ts +1 -0
  732. package/dist/tools/agent-creations.cjs +97 -0
  733. package/dist/tools/agent-creations.cjs.map +1 -0
  734. package/dist/tools/agent-creations.d.ts +38 -0
  735. package/dist/tools/agent-creations.js +97 -0
  736. package/dist/tools/agent-creations.js.map +1 -0
  737. package/dist/tools/agent-highlights.cjs +100 -0
  738. package/dist/tools/agent-highlights.cjs.map +1 -0
  739. package/dist/tools/agent-highlights.d.ts +57 -0
  740. package/dist/tools/agent-highlights.js +100 -0
  741. package/dist/tools/agent-highlights.js.map +1 -0
  742. package/dist/tools/append-document-tool-ui.cjs +1 -0
  743. package/dist/tools/append-document-tool-ui.cjs.map +1 -1
  744. package/dist/tools/append-document-tool-ui.d.ts +7 -0
  745. package/dist/tools/append-document-tool-ui.js +2 -1
  746. package/dist/tools/append-document-tool-ui.js.map +1 -1
  747. package/dist/tools/auto-open-tools.cjs +144 -71
  748. package/dist/tools/auto-open-tools.cjs.map +1 -1
  749. package/dist/tools/auto-open-tools.d.ts +131 -1
  750. package/dist/tools/auto-open-tools.js +145 -72
  751. package/dist/tools/auto-open-tools.js.map +1 -1
  752. package/dist/tools/browser-tool-uis.cjs +594 -0
  753. package/dist/tools/browser-tool-uis.cjs.map +1 -0
  754. package/dist/tools/browser-tool-uis.d.ts +8 -0
  755. package/dist/tools/browser-tool-uis.js +594 -0
  756. package/dist/tools/browser-tool-uis.js.map +1 -0
  757. package/dist/tools/computer-asset-tool-uis.cjs +313 -0
  758. package/dist/tools/computer-asset-tool-uis.cjs.map +1 -0
  759. package/dist/tools/computer-asset-tool-uis.d.ts +5 -0
  760. package/dist/tools/computer-asset-tool-uis.js +313 -0
  761. package/dist/tools/computer-asset-tool-uis.js.map +1 -0
  762. package/dist/tools/document-edit-tool-uis.cjs +218 -0
  763. package/dist/tools/document-edit-tool-uis.cjs.map +1 -0
  764. package/dist/tools/document-edit-tool-uis.d.ts +40 -0
  765. package/dist/tools/document-edit-tool-uis.js +218 -0
  766. package/dist/tools/document-edit-tool-uis.js.map +1 -0
  767. package/dist/tools/drive-tool-uis.cjs +429 -0
  768. package/dist/tools/drive-tool-uis.cjs.map +1 -0
  769. package/dist/tools/drive-tool-uis.d.ts +121 -0
  770. package/dist/tools/drive-tool-uis.js +429 -0
  771. package/dist/tools/drive-tool-uis.js.map +1 -0
  772. package/dist/tools/email-calendar-tool-uis.cjs +789 -0
  773. package/dist/tools/email-calendar-tool-uis.cjs.map +1 -0
  774. package/dist/tools/email-calendar-tool-uis.d.ts +129 -0
  775. package/dist/tools/email-calendar-tool-uis.js +789 -0
  776. package/dist/tools/email-calendar-tool-uis.js.map +1 -0
  777. package/dist/tools/ontology-tool-uis.cjs +83 -0
  778. package/dist/tools/ontology-tool-uis.cjs.map +1 -0
  779. package/dist/tools/ontology-tool-uis.d.ts +9 -0
  780. package/dist/tools/ontology-tool-uis.js +83 -0
  781. package/dist/tools/ontology-tool-uis.js.map +1 -0
  782. package/dist/tools/orchestration-tool-uis.cjs +586 -0
  783. package/dist/tools/orchestration-tool-uis.cjs.map +1 -0
  784. package/dist/tools/orchestration-tool-uis.d.ts +141 -0
  785. package/dist/tools/orchestration-tool-uis.js +586 -0
  786. package/dist/tools/orchestration-tool-uis.js.map +1 -0
  787. package/dist/tools/presentation-edit-tool-uis.cjs +516 -0
  788. package/dist/tools/presentation-edit-tool-uis.cjs.map +1 -0
  789. package/dist/tools/presentation-edit-tool-uis.d.ts +73 -0
  790. package/dist/tools/presentation-edit-tool-uis.js +516 -0
  791. package/dist/tools/presentation-edit-tool-uis.js.map +1 -0
  792. package/dist/tools/project-tool-uis.cjs +213 -0
  793. package/dist/tools/project-tool-uis.cjs.map +1 -0
  794. package/dist/tools/project-tool-uis.d.ts +14 -0
  795. package/dist/tools/project-tool-uis.js +213 -0
  796. package/dist/tools/project-tool-uis.js.map +1 -0
  797. package/dist/tools/sandbox-tool-uis.cjs +491 -0
  798. package/dist/tools/sandbox-tool-uis.cjs.map +1 -0
  799. package/dist/tools/sandbox-tool-uis.d.ts +116 -0
  800. package/dist/tools/sandbox-tool-uis.js +491 -0
  801. package/dist/tools/sandbox-tool-uis.js.map +1 -0
  802. package/dist/tools/sheet-query-tool-ui.cjs +138 -0
  803. package/dist/tools/sheet-query-tool-ui.cjs.map +1 -0
  804. package/dist/tools/sheet-query-tool-ui.d.ts +15 -0
  805. package/dist/tools/sheet-query-tool-ui.js +138 -0
  806. package/dist/tools/sheet-query-tool-ui.js.map +1 -0
  807. package/dist/tools/studio-screenshot-tool-uis.cjs +262 -0
  808. package/dist/tools/studio-screenshot-tool-uis.cjs.map +1 -0
  809. package/dist/tools/studio-screenshot-tool-uis.d.ts +52 -0
  810. package/dist/tools/studio-screenshot-tool-uis.js +262 -0
  811. package/dist/tools/studio-screenshot-tool-uis.js.map +1 -0
  812. package/dist/tools/subagent-task-tool-ui.cjs +24 -475
  813. package/dist/tools/subagent-task-tool-ui.cjs.map +1 -1
  814. package/dist/tools/subagent-task-tool-ui.d.ts +19 -103
  815. package/dist/tools/subagent-task-tool-ui.js +28 -479
  816. package/dist/tools/subagent-task-tool-ui.js.map +1 -1
  817. package/dist/tools/tool-summary.cjs +36 -0
  818. package/dist/tools/tool-summary.cjs.map +1 -1
  819. package/dist/tools/tool-summary.js +36 -0
  820. package/dist/tools/tool-summary.js.map +1 -1
  821. package/dist/tools/tool-uis.cjs +181 -53
  822. package/dist/tools/tool-uis.cjs.map +1 -1
  823. package/dist/tools/tool-uis.d.ts +40 -0
  824. package/dist/tools/tool-uis.js +183 -55
  825. package/dist/tools/tool-uis.js.map +1 -1
  826. package/dist/typed-interrupts/index.cjs +15 -0
  827. package/dist/typed-interrupts/index.cjs.map +1 -0
  828. package/dist/typed-interrupts/index.d.ts +20 -0
  829. package/dist/typed-interrupts/index.js +15 -0
  830. package/dist/typed-interrupts/index.js.map +1 -0
  831. package/dist/version.cjs +4 -0
  832. package/dist/version.cjs.map +1 -1
  833. package/dist/version.d.ts +9 -0
  834. package/dist/version.js +4 -0
  835. package/dist/version.js.map +1 -1
  836. package/dist/workbench/live-desktop-api.cjs +2 -1
  837. package/dist/workbench/live-desktop-api.cjs.map +1 -1
  838. package/dist/workbench/live-desktop-api.js +2 -1
  839. package/dist/workbench/live-desktop-api.js.map +1 -1
  840. package/dist/workbench/session-workbench-panes.cjs +6 -6
  841. package/dist/workbench/session-workbench-panes.cjs.map +1 -1
  842. package/dist/workbench/session-workspace-api.cjs +7 -2
  843. package/dist/workbench/session-workspace-api.cjs.map +1 -1
  844. package/dist/workbench/session-workspace-api.d.ts +10 -0
  845. package/dist/workbench/session-workspace-api.js +7 -2
  846. package/dist/workbench/session-workspace-api.js.map +1 -1
  847. package/package.json +28 -6
  848. package/dist/agent-runtime/src/chat-outbox-store.cjs +0 -510
  849. package/dist/agent-runtime/src/chat-outbox-store.cjs.map +0 -1
  850. package/dist/agent-runtime/src/chat-outbox-store.d.ts +0 -210
  851. package/dist/agent-runtime/src/chat-outbox-store.js +0 -510
  852. package/dist/agent-runtime/src/chat-outbox-store.js.map +0 -1
@@ -19,6 +19,20 @@ interface ThreadAssetState {
19
19
  * or the SDK's auto-open after a tool created or touched the asset.
20
20
  */
21
21
  export type AssetOpenOrigin = 'user' | 'auto';
22
+ /**
23
+ * What the tool behind an auto-open did with the asset: made it (`created`, a create tool or a
24
+ * studio SDK's `Create*`), opened it for the person to see (`shown`, `open_asset_in_workspace`), or
25
+ * only read or changed one that was there (`touched`).
26
+ */
27
+ export type AssetAutoOpenKind = 'created' | 'shown' | 'touched';
28
+ /**
29
+ * Why the SDK opened an asset by itself (`origin: 'auto'`): the tool whose result named it, and
30
+ * what that tool did with it. A host that follows only what the agent makes opens `created`.
31
+ */
32
+ export interface AssetAutoOpen {
33
+ tool: string;
34
+ kind: AssetAutoOpenKind;
35
+ }
22
36
  /** A request to open an asset, as a host's own opener receives it (`AthenaProvider onOpenAsset`). */
23
37
  export interface AssetOpenRequest {
24
38
  assetId: string;
@@ -30,6 +44,8 @@ export interface AssetOpenRequest {
30
44
  reference?: AthenaAssetCitationReference;
31
45
  /** The link's own address, when a link asked: a host that opens it on the web keeps every parameter it carried. */
32
46
  href?: string;
47
+ /** An auto-open's cause: the tool, and whether it made, showed or only touched the asset. */
48
+ autoOpen?: AssetAutoOpen;
33
49
  }
34
50
  /**
35
51
  * A host's own way to open an asset (a desktop app's tabs, a route of its own). Return `false` to
@@ -58,6 +74,12 @@ export interface AssetPanelState {
58
74
  autoOpenGeneration: number;
59
75
  /** Tracks which assets have been auto-opened in the current generation */
60
76
  autoOpenedAssets: Map<string, number>;
77
+ /**
78
+ * The assets a tool that made them or showed them to the person auto-opened in the current
79
+ * generation: such an open happens once per asset, and a touch earlier in the generation never
80
+ * holds it.
81
+ */
82
+ autoOpenedMadeOrShown: Map<string, number>;
61
83
  /**
62
84
  * Advances on every `openAsset` call — a repeat open of the asset already
63
85
  * showing included — so a host that hides the panel (a workbench tab) can
@@ -91,6 +113,8 @@ export interface AssetPanelState {
91
113
  origin?: AssetOpenOrigin;
92
114
  /** The link's own address, when a link asked (handed to a host's opener). */
93
115
  href?: string;
116
+ /** An auto-open's cause (handed to a host's opener). */
117
+ autoOpen?: AssetAutoOpen;
94
118
  }) => boolean;
95
119
  closeTab: (assetId: string) => void;
96
120
  setActiveTab: (assetId: string) => void;
@@ -104,8 +128,15 @@ export interface AssetPanelState {
104
128
  setCurrentThread: (threadId: string | null) => void;
105
129
  /** Reset auto-open tracking (increments generation so new assets can auto-open) */
106
130
  resetAutoOpen: () => void;
107
- /** Check if an asset should auto-open, and mark it as opened if so */
108
- markAutoOpened: (assetId: string) => boolean;
131
+ /**
132
+ * Check if an asset should auto-open, and mark it as opened if so: once per generation, except
133
+ * that a tool that made or showed the asset (`kind`, default `'touched'`) still opens it after a
134
+ * tool that only touched it did (where a runtime nests a script's sub-calls as tool calls, the
135
+ * script's own call can name the deck its `CreatePresentation` made before that sub-call's
136
+ * auto-open runs). An asset made or shown opens once: a later make or show of it in the same
137
+ * generation never takes the person back to it from what they opened since.
138
+ */
139
+ markAutoOpened: (assetId: string, kind?: AssetAutoOpenKind) => boolean;
109
140
  }
110
141
  export declare const useAssetPanelStore: import("zustand").UseBoundStore<Omit<import("zustand").StoreApi<AssetPanelState>, "persist" | "setState"> & {
111
142
  setState(partial: AssetPanelState | Partial<AssetPanelState> | ((state: AssetPanelState) => AssetPanelState | Partial<AssetPanelState>), replace?: false | undefined): unknown;
@@ -11,7 +11,8 @@ function assetOpenRequest({
11
11
  ...(meta == null ? void 0 : meta.type) !== void 0 ? { type: meta.type } : {},
12
12
  ...(meta == null ? void 0 : meta.slideNumber) !== void 0 ? { slideNumber: meta.slideNumber } : {},
13
13
  ...(meta == null ? void 0 : meta.reference) !== void 0 ? { reference: meta.reference } : {},
14
- ...(meta == null ? void 0 : meta.href) !== void 0 ? { href: meta.href } : {}
14
+ ...(meta == null ? void 0 : meta.href) !== void 0 ? { href: meta.href } : {},
15
+ ...(meta == null ? void 0 : meta.autoOpen) !== void 0 ? { autoOpen: meta.autoOpen } : {}
15
16
  };
16
17
  }
17
18
  const useAssetPanelStore = create()(
@@ -28,6 +29,7 @@ const useAssetPanelStore = create()(
28
29
  assetOpeners: [],
29
30
  autoOpenGeneration: 0,
30
31
  autoOpenedAssets: /* @__PURE__ */ new Map(),
32
+ autoOpenedMadeOrShown: /* @__PURE__ */ new Map(),
31
33
  openRequestSeq: 0,
32
34
  registerAssetPanelHost: () => set((state) => ({ assetPanelHostCount: state.assetPanelHostCount + 1 })),
33
35
  unregisterAssetPanelHost: () => set((state) => ({ assetPanelHostCount: Math.max(0, state.assetPanelHostCount - 1) })),
@@ -122,12 +124,18 @@ const useAssetPanelStore = create()(
122
124
  };
123
125
  }),
124
126
  resetAutoOpen: () => set((s) => ({ autoOpenGeneration: s.autoOpenGeneration + 1 })),
125
- markAutoOpened: (assetId) => {
127
+ markAutoOpened: (assetId, kind = "touched") => {
126
128
  const state = get();
127
- if (state.autoOpenedAssets.get(assetId) === state.autoOpenGeneration) {
128
- return false;
129
+ const generation = state.autoOpenGeneration;
130
+ if (kind === "touched") {
131
+ if (state.autoOpenedAssets.get(assetId) === generation) {
132
+ return false;
133
+ }
134
+ } else {
135
+ if (state.autoOpenedMadeOrShown.get(assetId) === generation) return false;
136
+ state.autoOpenedMadeOrShown.set(assetId, generation);
129
137
  }
130
- state.autoOpenedAssets.set(assetId, state.autoOpenGeneration);
138
+ state.autoOpenedAssets.set(assetId, generation);
131
139
  return true;
132
140
  }
133
141
  }),
@@ -1 +1 @@
1
- {"version":3,"file":"asset-panel-store.js","sources":["../../src/assets/asset-panel-store.ts"],"sourcesContent":["import { create } from 'zustand';\nimport { createJSONStorage, persist } from 'zustand/middleware';\nimport type { AthenaAssetCitationReference } from './asset-embed-messages';\n\nexport type AssetType = 'presentation' | 'spreadsheet' | 'document' | 'notebook' | 'unknown';\n\nexport type ViewMode = 'tabs' | 'tiled';\n\nexport interface AssetTab {\n id: string;\n name: string | null;\n type: AssetType;\n slideNumber?: number;\n /** The citation target (anchor + excerpt) the tab was last opened at. */\n reference?: AthenaAssetCitationReference;\n}\n\ninterface ThreadAssetState {\n tabs: AssetTab[];\n activeTabId: string | null;\n isOpen: boolean;\n}\n\n/**\n * Who asked for an asset: the person (a tool card's Open, a citation or asset link in a message)\n * or the SDK's auto-open after a tool created or touched the asset.\n */\nexport type AssetOpenOrigin = 'user' | 'auto';\n\n/** A request to open an asset, as a host's own opener receives it (`AthenaProvider onOpenAsset`). */\nexport interface AssetOpenRequest {\n assetId: string;\n origin: AssetOpenOrigin;\n name?: string;\n type?: AssetType;\n slideNumber?: number;\n /** The citation target (anchor + excerpt) the open should navigate to. */\n reference?: AthenaAssetCitationReference;\n /** The link's own address, when a link asked: a host that opens it on the web keeps every parameter it carried. */\n href?: string;\n}\n\n/**\n * A host's own way to open an asset (a desktop app's tabs, a route of its own). Return `false` to\n * leave the request to the SDK's asset panel.\n */\nexport type AssetOpener = (request: AssetOpenRequest) => boolean | void;\n\nfunction assetOpenRequest({\n assetId,\n meta,\n}: {\n assetId: string;\n meta: Parameters<AssetPanelState['openAsset']>[1];\n}): AssetOpenRequest {\n return {\n assetId,\n origin: meta?.origin ?? 'user',\n ...(meta?.name !== undefined ? { name: meta.name } : {}),\n ...(meta?.type !== undefined ? { type: meta.type } : {}),\n ...(meta?.slideNumber !== undefined ? { slideNumber: meta.slideNumber } : {}),\n ...(meta?.reference !== undefined ? { reference: meta.reference } : {}),\n ...(meta?.href !== undefined ? { href: meta.href } : {}),\n };\n}\n\nexport interface AssetPanelState {\n isOpen: boolean;\n tabs: AssetTab[];\n activeTabId: string | null;\n viewMode: ViewMode;\n isFullscreen: boolean;\n /** The current thread ID. Asset panel state is scoped per thread. */\n currentThreadId: string | null;\n /** Per-thread asset panel state — tabs and active tab persist per thread. */\n threadStates: Record<string, ThreadAssetState>;\n /** Number of registered hosts that can reveal the asset panel. */\n assetPanelHostCount: number;\n /**\n * The hosts' own openers (`AthenaProvider onOpenAsset`), newest last. While one is registered,\n * `openAsset` hands it the request first, and the panel opens the asset only when it returns\n * `false`.\n */\n assetOpeners: AssetOpener[];\n /** Generation counter for auto-open tracking — incremented on reset */\n autoOpenGeneration: number;\n /** Tracks which assets have been auto-opened in the current generation */\n autoOpenedAssets: Map<string, number>;\n /**\n * Advances on every `openAsset` call — a repeat open of the asset already\n * showing included — so a host that hides the panel (a workbench tab) can\n * reveal it for each request. A thread switch restoring that thread's open\n * assets does not advance it. Not persisted.\n */\n openRequestSeq: number;\n registerAssetPanelHost: () => void;\n unregisterAssetPanelHost: () => void;\n /** Registers a host's own opener; returns what unregisters it. */\n registerAssetOpener: (opener: AssetOpener) => () => void;\n /**\n * Opens an asset: a host's opener first, else the asset panel. Returns whether anything shows it:\n * an opener took it, or a mounted asset panel will. `false` (the host declined and no panel is\n * mounted) leaves the asset to whatever asked, such as a link that can still open as a link.\n */\n openAsset: (\n assetId: string,\n meta?: {\n name?: string;\n type?: AssetType;\n slideNumber?: number;\n /** Citation target (anchor + excerpt) the open should navigate to. */\n reference?: AthenaAssetCitationReference;\n /**\n * Swap the active tab for this asset instead of appending another tab.\n * Citation clicks use this: reading references shouldn't accumulate a\n * tab per cited document — the panel behaves as one preview surface.\n * A tab that already exists for the asset is re-targeted either way.\n */\n replaceActiveTab?: boolean;\n /** Who asked (default `'user'`); the SDK's auto-open passes `'auto'`. */\n origin?: AssetOpenOrigin;\n /** The link's own address, when a link asked (handed to a host's opener). */\n href?: string;\n },\n ) => boolean;\n closeTab: (assetId: string) => void;\n setActiveTab: (assetId: string) => void;\n setViewMode: (mode: ViewMode) => void;\n closePanel: () => void;\n toggleFullscreen: () => void;\n /**\n * Switch the active thread. Saves the current thread's asset panel state\n * and restores the new thread's state (if any). Pass null to clear.\n */\n setCurrentThread: (threadId: string | null) => void;\n /** Reset auto-open tracking (increments generation so new assets can auto-open) */\n resetAutoOpen: () => void;\n /** Check if an asset should auto-open, and mark it as opened if so */\n markAutoOpened: (assetId: string) => boolean;\n}\n\nexport const useAssetPanelStore = create<AssetPanelState>()(\n persist(\n (set, get) => ({\n isOpen: false,\n tabs: [],\n activeTabId: null,\n viewMode: 'tabs',\n isFullscreen: false,\n currentThreadId: null,\n threadStates: {},\n assetPanelHostCount: 0,\n assetOpeners: [],\n autoOpenGeneration: 0,\n autoOpenedAssets: new Map(),\n openRequestSeq: 0,\n\n registerAssetPanelHost: () =>\n set((state) => ({ assetPanelHostCount: state.assetPanelHostCount + 1 })),\n\n unregisterAssetPanelHost: () =>\n set((state) => ({ assetPanelHostCount: Math.max(0, state.assetPanelHostCount - 1) })),\n\n registerAssetOpener: (opener) => {\n set((state) => ({ assetOpeners: [...state.assetOpeners, opener] }));\n return () =>\n set((state) => {\n const index = state.assetOpeners.lastIndexOf(opener);\n if (index === -1) return state;\n const assetOpeners = state.assetOpeners.slice();\n assetOpeners.splice(index, 1);\n return { assetOpeners };\n });\n },\n\n openAsset: (assetId, meta) => {\n // A host that opens assets its own way takes the request first; `false` leaves it here.\n const opener = get().assetOpeners.at(-1);\n if (opener && opener(assetOpenRequest({ assetId, meta })) !== false) return true;\n set((s) => {\n const existing = s.tabs.find((t) => t.id === assetId);\n if (existing) {\n const tabs = meta\n ? s.tabs.map((t) =>\n t.id === assetId\n ? {\n ...t,\n name: meta.name ?? t.name,\n type: meta.type ?? t.type,\n slideNumber:\n 'slideNumber' in meta ? meta.slideNumber : t.slideNumber,\n // A repeat citation click re-targets the open tab: the new\n // reference reaches the iframe (src change -> navigation).\n reference:\n 'reference' in meta ? meta.reference : t.reference,\n }\n : t,\n )\n : s.tabs;\n return { isOpen: true, tabs, activeTabId: assetId, openRequestSeq: s.openRequestSeq + 1 };\n }\n const newTab: AssetTab = {\n id: assetId,\n name: meta?.name ?? null,\n type: meta?.type ?? 'unknown',\n slideNumber: meta?.slideNumber,\n reference: meta?.reference,\n };\n if (meta?.replaceActiveTab && s.activeTabId) {\n const activeIndex = s.tabs.findIndex((t) => t.id === s.activeTabId);\n if (activeIndex >= 0) {\n const tabs = s.tabs.slice();\n tabs[activeIndex] = newTab;\n return { isOpen: true, tabs, activeTabId: assetId, openRequestSeq: s.openRequestSeq + 1 };\n }\n }\n return {\n isOpen: true,\n tabs: [...s.tabs, newTab],\n activeTabId: assetId,\n openRequestSeq: s.openRequestSeq + 1,\n };\n });\n return get().assetPanelHostCount > 0;\n },\n\n closeTab: (assetId) =>\n set((s) => {\n const tabs = s.tabs.filter((t) => t.id !== assetId);\n if (tabs.length === 0) {\n return { isOpen: false, tabs: [], activeTabId: null, isFullscreen: false };\n }\n const activeTabId =\n s.activeTabId === assetId\n ? tabs[Math.min(s.tabs.findIndex((t) => t.id === assetId), tabs.length - 1)]?.id ?? null\n : s.activeTabId;\n return { tabs, activeTabId };\n }),\n\n setActiveTab: (assetId) => set({ activeTabId: assetId, viewMode: 'tabs' }),\n\n setViewMode: (mode) => set({ viewMode: mode }),\n\n closePanel: () =>\n set({ isOpen: false, tabs: [], activeTabId: null, viewMode: 'tabs', isFullscreen: false }),\n\n toggleFullscreen: () => set((s) => ({ isFullscreen: !s.isFullscreen })),\n\n setCurrentThread: (threadId) =>\n set((s) => {\n // No-op if same thread\n if (s.currentThreadId === threadId) {\n return s;\n }\n\n // Save current thread's asset state to the map (if we had one)\n const threadStates = { ...s.threadStates };\n if (s.currentThreadId !== null) {\n threadStates[s.currentThreadId] = {\n tabs: s.tabs,\n activeTabId: s.activeTabId,\n isOpen: s.isOpen,\n };\n }\n\n // Restore the new thread's state (or start fresh)\n const restored = threadId !== null ? threadStates[threadId] : undefined;\n\n return {\n currentThreadId: threadId,\n threadStates,\n tabs: restored?.tabs ?? [],\n activeTabId: restored?.activeTabId ?? null,\n isOpen: restored?.isOpen ?? false,\n // Reset transient UI state on thread switch\n isFullscreen: false,\n viewMode: 'tabs',\n };\n }),\n\n resetAutoOpen: () =>\n set((s) => ({ autoOpenGeneration: s.autoOpenGeneration + 1 })),\n\n markAutoOpened: (assetId: string) => {\n const state = get();\n if (state.autoOpenedAssets.get(assetId) === state.autoOpenGeneration) {\n return false; // already auto-opened in this generation\n }\n state.autoOpenedAssets.set(assetId, state.autoOpenGeneration);\n return true;\n },\n }),\n {\n name: 'athena-react-asset-panel',\n partialize: ({\n isOpen,\n tabs,\n activeTabId,\n viewMode,\n isFullscreen,\n currentThreadId,\n threadStates,\n }) => ({\n isOpen,\n tabs,\n activeTabId,\n viewMode,\n isFullscreen,\n currentThreadId,\n threadStates,\n }),\n storage: createJSONStorage(() => sessionStorage),\n },\n ),\n);\n"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"asset-panel-store.js","sources":["../../src/assets/asset-panel-store.ts"],"sourcesContent":["import { create } from 'zustand';\nimport { createJSONStorage, persist } from 'zustand/middleware';\nimport type { AthenaAssetCitationReference } from './asset-embed-messages';\n\nexport type AssetType = 'presentation' | 'spreadsheet' | 'document' | 'notebook' | 'unknown';\n\nexport type ViewMode = 'tabs' | 'tiled';\n\nexport interface AssetTab {\n id: string;\n name: string | null;\n type: AssetType;\n slideNumber?: number;\n /** The citation target (anchor + excerpt) the tab was last opened at. */\n reference?: AthenaAssetCitationReference;\n}\n\ninterface ThreadAssetState {\n tabs: AssetTab[];\n activeTabId: string | null;\n isOpen: boolean;\n}\n\n/**\n * Who asked for an asset: the person (a tool card's Open, a citation or asset link in a message)\n * or the SDK's auto-open after a tool created or touched the asset.\n */\nexport type AssetOpenOrigin = 'user' | 'auto';\n\n/**\n * What the tool behind an auto-open did with the asset: made it (`created`, a create tool or a\n * studio SDK's `Create*`), opened it for the person to see (`shown`, `open_asset_in_workspace`), or\n * only read or changed one that was there (`touched`).\n */\nexport type AssetAutoOpenKind = 'created' | 'shown' | 'touched';\n\n/**\n * Why the SDK opened an asset by itself (`origin: 'auto'`): the tool whose result named it, and\n * what that tool did with it. A host that follows only what the agent makes opens `created`.\n */\nexport interface AssetAutoOpen {\n tool: string;\n kind: AssetAutoOpenKind;\n}\n\n/** A request to open an asset, as a host's own opener receives it (`AthenaProvider onOpenAsset`). */\nexport interface AssetOpenRequest {\n assetId: string;\n origin: AssetOpenOrigin;\n name?: string;\n type?: AssetType;\n slideNumber?: number;\n /** The citation target (anchor + excerpt) the open should navigate to. */\n reference?: AthenaAssetCitationReference;\n /** The link's own address, when a link asked: a host that opens it on the web keeps every parameter it carried. */\n href?: string;\n /** An auto-open's cause: the tool, and whether it made, showed or only touched the asset. */\n autoOpen?: AssetAutoOpen;\n}\n\n/**\n * A host's own way to open an asset (a desktop app's tabs, a route of its own). Return `false` to\n * leave the request to the SDK's asset panel.\n */\nexport type AssetOpener = (request: AssetOpenRequest) => boolean | void;\n\nfunction assetOpenRequest({\n assetId,\n meta,\n}: {\n assetId: string;\n meta: Parameters<AssetPanelState['openAsset']>[1];\n}): AssetOpenRequest {\n return {\n assetId,\n origin: meta?.origin ?? 'user',\n ...(meta?.name !== undefined ? { name: meta.name } : {}),\n ...(meta?.type !== undefined ? { type: meta.type } : {}),\n ...(meta?.slideNumber !== undefined ? { slideNumber: meta.slideNumber } : {}),\n ...(meta?.reference !== undefined ? { reference: meta.reference } : {}),\n ...(meta?.href !== undefined ? { href: meta.href } : {}),\n ...(meta?.autoOpen !== undefined ? { autoOpen: meta.autoOpen } : {}),\n };\n}\n\nexport interface AssetPanelState {\n isOpen: boolean;\n tabs: AssetTab[];\n activeTabId: string | null;\n viewMode: ViewMode;\n isFullscreen: boolean;\n /** The current thread ID. Asset panel state is scoped per thread. */\n currentThreadId: string | null;\n /** Per-thread asset panel state — tabs and active tab persist per thread. */\n threadStates: Record<string, ThreadAssetState>;\n /** Number of registered hosts that can reveal the asset panel. */\n assetPanelHostCount: number;\n /**\n * The hosts' own openers (`AthenaProvider onOpenAsset`), newest last. While one is registered,\n * `openAsset` hands it the request first, and the panel opens the asset only when it returns\n * `false`.\n */\n assetOpeners: AssetOpener[];\n /** Generation counter for auto-open tracking — incremented on reset */\n autoOpenGeneration: number;\n /** Tracks which assets have been auto-opened in the current generation */\n autoOpenedAssets: Map<string, number>;\n /**\n * The assets a tool that made them or showed them to the person auto-opened in the current\n * generation: such an open happens once per asset, and a touch earlier in the generation never\n * holds it.\n */\n autoOpenedMadeOrShown: Map<string, number>;\n /**\n * Advances on every `openAsset` call — a repeat open of the asset already\n * showing included — so a host that hides the panel (a workbench tab) can\n * reveal it for each request. A thread switch restoring that thread's open\n * assets does not advance it. Not persisted.\n */\n openRequestSeq: number;\n registerAssetPanelHost: () => void;\n unregisterAssetPanelHost: () => void;\n /** Registers a host's own opener; returns what unregisters it. */\n registerAssetOpener: (opener: AssetOpener) => () => void;\n /**\n * Opens an asset: a host's opener first, else the asset panel. Returns whether anything shows it:\n * an opener took it, or a mounted asset panel will. `false` (the host declined and no panel is\n * mounted) leaves the asset to whatever asked, such as a link that can still open as a link.\n */\n openAsset: (\n assetId: string,\n meta?: {\n name?: string;\n type?: AssetType;\n slideNumber?: number;\n /** Citation target (anchor + excerpt) the open should navigate to. */\n reference?: AthenaAssetCitationReference;\n /**\n * Swap the active tab for this asset instead of appending another tab.\n * Citation clicks use this: reading references shouldn't accumulate a\n * tab per cited document — the panel behaves as one preview surface.\n * A tab that already exists for the asset is re-targeted either way.\n */\n replaceActiveTab?: boolean;\n /** Who asked (default `'user'`); the SDK's auto-open passes `'auto'`. */\n origin?: AssetOpenOrigin;\n /** The link's own address, when a link asked (handed to a host's opener). */\n href?: string;\n /** An auto-open's cause (handed to a host's opener). */\n autoOpen?: AssetAutoOpen;\n },\n ) => boolean;\n closeTab: (assetId: string) => void;\n setActiveTab: (assetId: string) => void;\n setViewMode: (mode: ViewMode) => void;\n closePanel: () => void;\n toggleFullscreen: () => void;\n /**\n * Switch the active thread. Saves the current thread's asset panel state\n * and restores the new thread's state (if any). Pass null to clear.\n */\n setCurrentThread: (threadId: string | null) => void;\n /** Reset auto-open tracking (increments generation so new assets can auto-open) */\n resetAutoOpen: () => void;\n /**\n * Check if an asset should auto-open, and mark it as opened if so: once per generation, except\n * that a tool that made or showed the asset (`kind`, default `'touched'`) still opens it after a\n * tool that only touched it did (where a runtime nests a script's sub-calls as tool calls, the\n * script's own call can name the deck its `CreatePresentation` made before that sub-call's\n * auto-open runs). An asset made or shown opens once: a later make or show of it in the same\n * generation never takes the person back to it from what they opened since.\n */\n markAutoOpened: (assetId: string, kind?: AssetAutoOpenKind) => boolean;\n}\n\nexport const useAssetPanelStore = create<AssetPanelState>()(\n persist(\n (set, get) => ({\n isOpen: false,\n tabs: [],\n activeTabId: null,\n viewMode: 'tabs',\n isFullscreen: false,\n currentThreadId: null,\n threadStates: {},\n assetPanelHostCount: 0,\n assetOpeners: [],\n autoOpenGeneration: 0,\n autoOpenedAssets: new Map(),\n autoOpenedMadeOrShown: new Map(),\n openRequestSeq: 0,\n\n registerAssetPanelHost: () =>\n set((state) => ({ assetPanelHostCount: state.assetPanelHostCount + 1 })),\n\n unregisterAssetPanelHost: () =>\n set((state) => ({ assetPanelHostCount: Math.max(0, state.assetPanelHostCount - 1) })),\n\n registerAssetOpener: (opener) => {\n set((state) => ({ assetOpeners: [...state.assetOpeners, opener] }));\n return () =>\n set((state) => {\n const index = state.assetOpeners.lastIndexOf(opener);\n if (index === -1) return state;\n const assetOpeners = state.assetOpeners.slice();\n assetOpeners.splice(index, 1);\n return { assetOpeners };\n });\n },\n\n openAsset: (assetId, meta) => {\n // A host that opens assets its own way takes the request first; `false` leaves it here.\n const opener = get().assetOpeners.at(-1);\n if (opener && opener(assetOpenRequest({ assetId, meta })) !== false) return true;\n set((s) => {\n const existing = s.tabs.find((t) => t.id === assetId);\n if (existing) {\n const tabs = meta\n ? s.tabs.map((t) =>\n t.id === assetId\n ? {\n ...t,\n name: meta.name ?? t.name,\n type: meta.type ?? t.type,\n slideNumber:\n 'slideNumber' in meta ? meta.slideNumber : t.slideNumber,\n // A repeat citation click re-targets the open tab: the new\n // reference reaches the iframe (src change -> navigation).\n reference:\n 'reference' in meta ? meta.reference : t.reference,\n }\n : t,\n )\n : s.tabs;\n return { isOpen: true, tabs, activeTabId: assetId, openRequestSeq: s.openRequestSeq + 1 };\n }\n const newTab: AssetTab = {\n id: assetId,\n name: meta?.name ?? null,\n type: meta?.type ?? 'unknown',\n slideNumber: meta?.slideNumber,\n reference: meta?.reference,\n };\n if (meta?.replaceActiveTab && s.activeTabId) {\n const activeIndex = s.tabs.findIndex((t) => t.id === s.activeTabId);\n if (activeIndex >= 0) {\n const tabs = s.tabs.slice();\n tabs[activeIndex] = newTab;\n return { isOpen: true, tabs, activeTabId: assetId, openRequestSeq: s.openRequestSeq + 1 };\n }\n }\n return {\n isOpen: true,\n tabs: [...s.tabs, newTab],\n activeTabId: assetId,\n openRequestSeq: s.openRequestSeq + 1,\n };\n });\n return get().assetPanelHostCount > 0;\n },\n\n closeTab: (assetId) =>\n set((s) => {\n const tabs = s.tabs.filter((t) => t.id !== assetId);\n if (tabs.length === 0) {\n return { isOpen: false, tabs: [], activeTabId: null, isFullscreen: false };\n }\n const activeTabId =\n s.activeTabId === assetId\n ? tabs[Math.min(s.tabs.findIndex((t) => t.id === assetId), tabs.length - 1)]?.id ?? null\n : s.activeTabId;\n return { tabs, activeTabId };\n }),\n\n setActiveTab: (assetId) => set({ activeTabId: assetId, viewMode: 'tabs' }),\n\n setViewMode: (mode) => set({ viewMode: mode }),\n\n closePanel: () =>\n set({ isOpen: false, tabs: [], activeTabId: null, viewMode: 'tabs', isFullscreen: false }),\n\n toggleFullscreen: () => set((s) => ({ isFullscreen: !s.isFullscreen })),\n\n setCurrentThread: (threadId) =>\n set((s) => {\n // No-op if same thread\n if (s.currentThreadId === threadId) {\n return s;\n }\n\n // Save current thread's asset state to the map (if we had one)\n const threadStates = { ...s.threadStates };\n if (s.currentThreadId !== null) {\n threadStates[s.currentThreadId] = {\n tabs: s.tabs,\n activeTabId: s.activeTabId,\n isOpen: s.isOpen,\n };\n }\n\n // Restore the new thread's state (or start fresh)\n const restored = threadId !== null ? threadStates[threadId] : undefined;\n\n return {\n currentThreadId: threadId,\n threadStates,\n tabs: restored?.tabs ?? [],\n activeTabId: restored?.activeTabId ?? null,\n isOpen: restored?.isOpen ?? false,\n // Reset transient UI state on thread switch\n isFullscreen: false,\n viewMode: 'tabs',\n };\n }),\n\n resetAutoOpen: () =>\n set((s) => ({ autoOpenGeneration: s.autoOpenGeneration + 1 })),\n\n markAutoOpened: (assetId: string, kind: AssetAutoOpenKind = 'touched') => {\n const state = get();\n const generation = state.autoOpenGeneration;\n if (kind === 'touched') {\n if (state.autoOpenedAssets.get(assetId) === generation) {\n return false; // already auto-opened in this generation\n }\n } else {\n if (state.autoOpenedMadeOrShown.get(assetId) === generation) return false;\n state.autoOpenedMadeOrShown.set(assetId, generation);\n }\n state.autoOpenedAssets.set(assetId, generation);\n return true;\n },\n }),\n {\n name: 'athena-react-asset-panel',\n partialize: ({\n isOpen,\n tabs,\n activeTabId,\n viewMode,\n isFullscreen,\n currentThreadId,\n threadStates,\n }) => ({\n isOpen,\n tabs,\n activeTabId,\n viewMode,\n isFullscreen,\n currentThreadId,\n threadStates,\n }),\n storage: createJSONStorage(() => sessionStorage),\n },\n ),\n);\n"],"names":[],"mappings":"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"}
@@ -15,7 +15,18 @@ function useAthenaCredentialIdentityEpoch() {
15
15
  const read = () => (credentials == null ? void 0 : credentials.identityEpoch()) ?? 0;
16
16
  return require$$0.useSyncExternalStore(subscribe, read, read);
17
17
  }
18
+ function useAthenaCredentialScopeEpoch() {
19
+ const credentials = useAthenaCredentialSource();
20
+ const subscribe = require$$0.useCallback(
21
+ (onChange) => credentials ? credentials.subscribe(onChange) : () => {
22
+ },
23
+ [credentials]
24
+ );
25
+ const read = () => (credentials == null ? void 0 : credentials.scopeEpoch()) ?? 0;
26
+ return require$$0.useSyncExternalStore(subscribe, read, read);
27
+ }
18
28
  exports.AthenaCredentialSourceContext = AthenaCredentialSourceContext;
19
29
  exports.useAthenaCredentialIdentityEpoch = useAthenaCredentialIdentityEpoch;
30
+ exports.useAthenaCredentialScopeEpoch = useAthenaCredentialScopeEpoch;
20
31
  exports.useAthenaCredentialSource = useAthenaCredentialSource;
21
32
  //# sourceMappingURL=AthenaCredentialSourceContext.cjs.map
@@ -1 +1 @@
1
- {"version":3,"file":"AthenaCredentialSourceContext.cjs","sources":["../../src/auth/AthenaCredentialSourceContext.ts"],"sourcesContent":["import { createContext, useCallback, useContext, useSyncExternalStore } from 'react';\nimport type { AthenaCredentialSource } from './credential-source';\n\n/**\n * The provider's credential source (see `createAthenaCredentialSource`), for\n * the SDK's own connections that must restart when a new token arrives.\n * Internal: hosts read tokens through `useAthenaConfig().getToken`.\n */\nexport const AthenaCredentialSourceContext = createContext<AthenaCredentialSource | null>(null);\n\nexport function useAthenaCredentialSource(): AthenaCredentialSource | null {\n return useContext(AthenaCredentialSourceContext);\n}\n\n/**\n * The credential source's identity epoch (see `identityEpoch`): a number that\n * changes when someone else signs in, not when a token is renewed. `0`\n * outside a provider.\n */\nexport function useAthenaCredentialIdentityEpoch(): number {\n const credentials = useAthenaCredentialSource();\n const subscribe = useCallback(\n (onChange: () => void) => (credentials ? credentials.subscribe(onChange) : () => {}),\n [credentials],\n );\n const read = () => credentials?.identityEpoch() ?? 0;\n return useSyncExternalStore(subscribe, read, read);\n}\n"],"names":["createContext","useContext","useCallback","useSyncExternalStore"],"mappings":";;;AAQO,MAAM,gCAAgCA,WAAAA,cAA6C,IAAI;AAEvF,SAAS,4BAA2D;AACzE,SAAOC,WAAAA,WAAW,6BAA6B;AACjD;AAOO,SAAS,mCAA2C;AACzD,QAAM,cAAc,0BAAA;AACpB,QAAM,YAAYC,WAAAA;AAAAA,IAChB,CAAC,aAA0B,cAAc,YAAY,UAAU,QAAQ,IAAI,MAAM;AAAA,IAAC;AAAA,IAClF,CAAC,WAAW;AAAA,EAAA;AAEd,QAAM,OAAO,OAAM,2CAAa,oBAAmB;AACnD,SAAOC,gCAAqB,WAAW,MAAM,IAAI;AACnD;;;;"}
1
+ {"version":3,"file":"AthenaCredentialSourceContext.cjs","sources":["../../src/auth/AthenaCredentialSourceContext.ts"],"sourcesContent":["import { createContext, useCallback, useContext, useSyncExternalStore } from 'react';\nimport type { AthenaCredentialSource } from './credential-source';\n\n/**\n * The provider's credential source (see `createAthenaCredentialSource`), for\n * the SDK's own connections that must restart when a new token arrives.\n * Internal: hosts read tokens through `useAthenaConfig().getToken`.\n */\nexport const AthenaCredentialSourceContext = createContext<AthenaCredentialSource | null>(null);\n\nexport function useAthenaCredentialSource(): AthenaCredentialSource | null {\n return useContext(AthenaCredentialSourceContext);\n}\n\n/**\n * The credential source's identity epoch (see `identityEpoch`): a number that\n * changes when someone else signs in, not when a token is renewed. `0`\n * outside a provider.\n */\nexport function useAthenaCredentialIdentityEpoch(): number {\n const credentials = useAthenaCredentialSource();\n const subscribe = useCallback(\n (onChange: () => void) => (credentials ? credentials.subscribe(onChange) : () => {}),\n [credentials],\n );\n const read = () => credentials?.identityEpoch() ?? 0;\n return useSyncExternalStore(subscribe, read, read);\n}\n\n/**\n * The credential source's scope epoch (see `scopeEpoch`): a number that\n * changes when someone else signs in or the token is scoped to another\n * workspace or org, not when a token is renewed. `0` outside a provider.\n */\nexport function useAthenaCredentialScopeEpoch(): number {\n const credentials = useAthenaCredentialSource();\n const subscribe = useCallback(\n (onChange: () => void) => (credentials ? credentials.subscribe(onChange) : () => {}),\n [credentials],\n );\n const read = () => credentials?.scopeEpoch() ?? 0;\n return useSyncExternalStore(subscribe, read, read);\n}\n"],"names":["createContext","useContext","useCallback","useSyncExternalStore"],"mappings":";;;AAQO,MAAM,gCAAgCA,WAAAA,cAA6C,IAAI;AAEvF,SAAS,4BAA2D;AACzE,SAAOC,WAAAA,WAAW,6BAA6B;AACjD;AAOO,SAAS,mCAA2C;AACzD,QAAM,cAAc,0BAAA;AACpB,QAAM,YAAYC,WAAAA;AAAAA,IAChB,CAAC,aAA0B,cAAc,YAAY,UAAU,QAAQ,IAAI,MAAM;AAAA,IAAC;AAAA,IAClF,CAAC,WAAW;AAAA,EAAA;AAEd,QAAM,OAAO,OAAM,2CAAa,oBAAmB;AACnD,SAAOC,gCAAqB,WAAW,MAAM,IAAI;AACnD;AAOO,SAAS,gCAAwC;AACtD,QAAM,cAAc,0BAAA;AACpB,QAAM,YAAYD,WAAAA;AAAAA,IAChB,CAAC,aAA0B,cAAc,YAAY,UAAU,QAAQ,IAAI,MAAM;AAAA,IAAC;AAAA,IAClF,CAAC,WAAW;AAAA,EAAA;AAEd,QAAM,OAAO,OAAM,2CAAa,iBAAgB;AAChD,SAAOC,gCAAqB,WAAW,MAAM,IAAI;AACnD;;;;;"}
@@ -12,3 +12,9 @@ export declare function useAthenaCredentialSource(): AthenaCredentialSource | nu
12
12
  * outside a provider.
13
13
  */
14
14
  export declare function useAthenaCredentialIdentityEpoch(): number;
15
+ /**
16
+ * The credential source's scope epoch (see `scopeEpoch`): a number that
17
+ * changes when someone else signs in or the token is scoped to another
18
+ * workspace or org, not when a token is renewed. `0` outside a provider.
19
+ */
20
+ export declare function useAthenaCredentialScopeEpoch(): number;
@@ -13,9 +13,20 @@ function useAthenaCredentialIdentityEpoch() {
13
13
  const read = () => (credentials == null ? void 0 : credentials.identityEpoch()) ?? 0;
14
14
  return useSyncExternalStore(subscribe, read, read);
15
15
  }
16
+ function useAthenaCredentialScopeEpoch() {
17
+ const credentials = useAthenaCredentialSource();
18
+ const subscribe = useCallback(
19
+ (onChange) => credentials ? credentials.subscribe(onChange) : () => {
20
+ },
21
+ [credentials]
22
+ );
23
+ const read = () => (credentials == null ? void 0 : credentials.scopeEpoch()) ?? 0;
24
+ return useSyncExternalStore(subscribe, read, read);
25
+ }
16
26
  export {
17
27
  AthenaCredentialSourceContext,
18
28
  useAthenaCredentialIdentityEpoch,
29
+ useAthenaCredentialScopeEpoch,
19
30
  useAthenaCredentialSource
20
31
  };
21
32
  //# sourceMappingURL=AthenaCredentialSourceContext.js.map
@@ -1 +1 @@
1
- {"version":3,"file":"AthenaCredentialSourceContext.js","sources":["../../src/auth/AthenaCredentialSourceContext.ts"],"sourcesContent":["import { createContext, useCallback, useContext, useSyncExternalStore } from 'react';\nimport type { AthenaCredentialSource } from './credential-source';\n\n/**\n * The provider's credential source (see `createAthenaCredentialSource`), for\n * the SDK's own connections that must restart when a new token arrives.\n * Internal: hosts read tokens through `useAthenaConfig().getToken`.\n */\nexport const AthenaCredentialSourceContext = createContext<AthenaCredentialSource | null>(null);\n\nexport function useAthenaCredentialSource(): AthenaCredentialSource | null {\n return useContext(AthenaCredentialSourceContext);\n}\n\n/**\n * The credential source's identity epoch (see `identityEpoch`): a number that\n * changes when someone else signs in, not when a token is renewed. `0`\n * outside a provider.\n */\nexport function useAthenaCredentialIdentityEpoch(): number {\n const credentials = useAthenaCredentialSource();\n const subscribe = useCallback(\n (onChange: () => void) => (credentials ? credentials.subscribe(onChange) : () => {}),\n [credentials],\n );\n const read = () => credentials?.identityEpoch() ?? 0;\n return useSyncExternalStore(subscribe, read, read);\n}\n"],"names":[],"mappings":";AAQO,MAAM,gCAAgC,cAA6C,IAAI;AAEvF,SAAS,4BAA2D;AACzE,SAAO,WAAW,6BAA6B;AACjD;AAOO,SAAS,mCAA2C;AACzD,QAAM,cAAc,0BAAA;AACpB,QAAM,YAAY;AAAA,IAChB,CAAC,aAA0B,cAAc,YAAY,UAAU,QAAQ,IAAI,MAAM;AAAA,IAAC;AAAA,IAClF,CAAC,WAAW;AAAA,EAAA;AAEd,QAAM,OAAO,OAAM,2CAAa,oBAAmB;AACnD,SAAO,qBAAqB,WAAW,MAAM,IAAI;AACnD;"}
1
+ {"version":3,"file":"AthenaCredentialSourceContext.js","sources":["../../src/auth/AthenaCredentialSourceContext.ts"],"sourcesContent":["import { createContext, useCallback, useContext, useSyncExternalStore } from 'react';\nimport type { AthenaCredentialSource } from './credential-source';\n\n/**\n * The provider's credential source (see `createAthenaCredentialSource`), for\n * the SDK's own connections that must restart when a new token arrives.\n * Internal: hosts read tokens through `useAthenaConfig().getToken`.\n */\nexport const AthenaCredentialSourceContext = createContext<AthenaCredentialSource | null>(null);\n\nexport function useAthenaCredentialSource(): AthenaCredentialSource | null {\n return useContext(AthenaCredentialSourceContext);\n}\n\n/**\n * The credential source's identity epoch (see `identityEpoch`): a number that\n * changes when someone else signs in, not when a token is renewed. `0`\n * outside a provider.\n */\nexport function useAthenaCredentialIdentityEpoch(): number {\n const credentials = useAthenaCredentialSource();\n const subscribe = useCallback(\n (onChange: () => void) => (credentials ? credentials.subscribe(onChange) : () => {}),\n [credentials],\n );\n const read = () => credentials?.identityEpoch() ?? 0;\n return useSyncExternalStore(subscribe, read, read);\n}\n\n/**\n * The credential source's scope epoch (see `scopeEpoch`): a number that\n * changes when someone else signs in or the token is scoped to another\n * workspace or org, not when a token is renewed. `0` outside a provider.\n */\nexport function useAthenaCredentialScopeEpoch(): number {\n const credentials = useAthenaCredentialSource();\n const subscribe = useCallback(\n (onChange: () => void) => (credentials ? credentials.subscribe(onChange) : () => {}),\n [credentials],\n );\n const read = () => credentials?.scopeEpoch() ?? 0;\n return useSyncExternalStore(subscribe, read, read);\n}\n"],"names":[],"mappings":";AAQO,MAAM,gCAAgC,cAA6C,IAAI;AAEvF,SAAS,4BAA2D;AACzE,SAAO,WAAW,6BAA6B;AACjD;AAOO,SAAS,mCAA2C;AACzD,QAAM,cAAc,0BAAA;AACpB,QAAM,YAAY;AAAA,IAChB,CAAC,aAA0B,cAAc,YAAY,UAAU,QAAQ,IAAI,MAAM;AAAA,IAAC;AAAA,IAClF,CAAC,WAAW;AAAA,EAAA;AAEd,QAAM,OAAO,OAAM,2CAAa,oBAAmB;AACnD,SAAO,qBAAqB,WAAW,MAAM,IAAI;AACnD;AAOO,SAAS,gCAAwC;AACtD,QAAM,cAAc,0BAAA;AACpB,QAAM,YAAY;AAAA,IAChB,CAAC,aAA0B,cAAc,YAAY,UAAU,QAAQ,IAAI,MAAM;AAAA,IAAC;AAAA,IAClF,CAAC,WAAW;AAAA,EAAA;AAEd,QAAM,OAAO,OAAM,2CAAa,iBAAgB;AAChD,SAAO,qBAAqB,WAAW,MAAM,IAAI;AACnD;"}
@@ -25,15 +25,25 @@ function heldTokenIdentity(token) {
25
25
  const scope = credentialSource.jwtScope(token);
26
26
  return scope === null ? `sub:${useAthenaRestQuery.keyPartFingerprint(subject)}` : `sub:${useAthenaRestQuery.keyPartFingerprint(subject)}|scope:${useAthenaRestQuery.keyPartFingerprint(scope)}`;
27
27
  }
28
+ function credentialKeyParts({
29
+ apiKey,
30
+ heldToken
31
+ }) {
32
+ return [apiKey ? useAthenaRestQuery.keyPartFingerprint(apiKey) : "", heldTokenIdentity(heldToken)];
33
+ }
28
34
  function accountIdentityQueryKey(credential, identityEpoch) {
35
+ const [apiKeyPart, heldTokenPart] = credentialKeyParts({
36
+ apiKey: credential.apiKey,
37
+ heldToken: credential.heldToken
38
+ });
29
39
  return [
30
40
  "athena-sdk",
31
41
  "account",
32
42
  credential.backendUrl,
33
43
  credential.principal ?? "",
34
- credential.apiKey ? useAthenaRestQuery.keyPartFingerprint(credential.apiKey) : "",
44
+ apiKeyPart,
35
45
  tokenGetterId(credential.tokenGetter),
36
- heldTokenIdentity(credential.heldToken),
46
+ heldTokenPart,
37
47
  identityEpoch
38
48
  ];
39
49
  }
@@ -65,5 +75,6 @@ function useAccountIdentityQuery({
65
75
  );
66
76
  }
67
77
  exports.accountIdentityQueryKey = accountIdentityQueryKey;
78
+ exports.credentialKeyParts = credentialKeyParts;
68
79
  exports.useAccountIdentityQuery = useAccountIdentityQuery;
69
80
  //# sourceMappingURL=account-identity.cjs.map
@@ -1 +1 @@
1
- {"version":3,"file":"account-identity.cjs","sources":["../../src/auth/account-identity.ts"],"sourcesContent":["import { type QueryClient, type UseQueryResult, useQuery } from '@tanstack/react-query';\nimport { keyPartFingerprint } from '../lib/use-athena-rest-query';\nimport { type CredentialResolver, withCredentialRenewal } from '../runtime/credential-renewal';\nimport type { AthenaStatewireTokenGetter } from '../runtime/statewire-auth-headers';\nimport { type AccountIdentity, fetchAccountIdentity } from '../threads/api';\nimport { useAthenaCredentialIdentityEpoch } from './AthenaCredentialSourceContext';\nimport { jwtScope, jwtSubject } from './credential-source';\n\n/**\n * The credential an identity read is sent with, as its key names it: never\n * the secret itself.\n */\nexport interface AccountIdentityCredential {\n /** Agora's API base the read goes to. */\n backendUrl: string;\n /** The signed-in person (`AthenaAuthContext`'s user id), when one is. */\n principal: string | undefined;\n apiKey: string | undefined;\n /** The token the host holds now. A renewal for the same person and scope keeps the key. */\n heldToken: string | null | undefined;\n /** The provider's token getter (`config.getToken`), by identity. */\n tokenGetter: AthenaStatewireTokenGetter | undefined;\n}\n\n/** What one read presents, resolved when it is sent; `force` renews a refused token. */\nexport interface AccountIdentityAuth {\n apiKey?: string;\n token?: string | null;\n}\n\n/** One id per token getter, so the key can name a getter without holding it. */\nconst tokenGetterIds = new WeakMap<AthenaStatewireTokenGetter, number>();\nlet lastTokenGetterId = 0;\n\nfunction tokenGetterId(getToken: AthenaStatewireTokenGetter | undefined): string {\n if (getToken === undefined) return '';\n let id = tokenGetterIds.get(getToken);\n if (id === undefined) {\n lastTokenGetterId += 1;\n id = lastTokenGetterId;\n tokenGetterIds.set(getToken, id);\n }\n return `getter:${id}`;\n}\n\n/**\n * Who a held token acts as, and where, without the token: its JWT subject and\n * the claims scoping it to a workspace or org (`jwtScope`), or the token\n * itself when it is opaque, fingerprinted. A renewal for the same person and\n * scope keeps it, so a rotation is not a new identity; the same person's token\n * scoped to another workspace is.\n */\nfunction heldTokenIdentity(token: string | null | undefined): string {\n if (!token) return '';\n const subject = jwtSubject(token);\n if (subject === null) return `token:${keyPartFingerprint(token)}`;\n const scope = jwtScope(token);\n return scope === null\n ? `sub:${keyPartFingerprint(subject)}`\n : `sub:${keyPartFingerprint(subject)}|scope:${keyPartFingerprint(scope)}`;\n}\n\n/**\n * The one key a credential's identity is read under, whoever reads it: the\n * backend, the signed-in person, the API key's fingerprint, the provider's\n * token getter, who the held token acts as and which workspace it is scoped\n * to, and the provider's credential identity epoch\n * (`useAthenaCredentialIdentityEpoch`), which moves once the getter has handed\n * out a token that acts as someone else.\n */\nexport function accountIdentityQueryKey(\n credential: AccountIdentityCredential,\n identityEpoch: number,\n): readonly unknown[] {\n return [\n 'athena-sdk',\n 'account',\n credential.backendUrl,\n credential.principal ?? '',\n credential.apiKey ? keyPartFingerprint(credential.apiKey) : '',\n tokenGetterId(credential.tokenGetter),\n heldTokenIdentity(credential.heldToken),\n identityEpoch,\n ];\n}\n\n/** A refusal, or a route an older agora lacks, answers the same way again. */\nconst NO_RETRY_STATUSES: ReadonlySet<number> = new Set([401, 403, 404, 405, 409]);\n\n/** Retry a transient failure twice; never a refused credential. */\nfunction retryTransient(failureCount: number, error: Error): boolean {\n const status: unknown = Reflect.get(error, 'status');\n if (typeof status === 'number' && NO_RETRY_STATUSES.has(status)) return false;\n return failureCount < 2;\n}\n\n/**\n * The credential's agora identity (`GET /api/v0/me`): one read per credential,\n * through the query cache, shared by every reader of it. `AthenaChat` (its\n * mentions workspace and the viewer behind its answer labels) and the session\n * list (the conversation index it attaches to) read it here under one key\n * (`accountIdentityQueryKey`), so a page with both sends one request. Never a\n * process-wide map: the key names the credential and never the secret. A\n * renewal for the same person and scope keeps the answer; an API-key switch, a\n * held token scoped to another workspace, or a getter now signing in someone\n * else, reads `/me` again under a new key, never a cached answer for the\n * previous credential. The epoch follows the person, not the scope: a getter\n * that alone hands out the same person's token for another workspace is read\n * again once the answer goes stale.\n *\n * `resolveAuth` presents the credential the key names, so whichever reader\n * sends the request, the answer is the same. `enabled` is the reader's own.\n * `queryClient` defaults to the one in context.\n */\nexport function useAccountIdentityQuery({\n credential,\n resolveAuth,\n enabled,\n queryClient,\n}: {\n credential: AccountIdentityCredential;\n resolveAuth: CredentialResolver<AccountIdentityAuth>;\n enabled: boolean;\n queryClient?: QueryClient;\n}): UseQueryResult<AccountIdentity> {\n const identityEpoch = useAthenaCredentialIdentityEpoch();\n return useQuery(\n {\n queryKey: accountIdentityQueryKey(credential, identityEpoch),\n queryFn: ({ signal }) =>\n withCredentialRenewal(resolveAuth, (auth) =>\n fetchAccountIdentity(credential.backendUrl, auth, { signal }),\n ),\n enabled,\n retry: retryTransient,\n staleTime: 60_000,\n },\n queryClient,\n );\n}\n"],"names":["jwtSubject","keyPartFingerprint","jwtScope","useAthenaCredentialIdentityEpoch","useQuery","withCredentialRenewal","fetchAccountIdentity"],"mappings":";;;;;;;;AA+BA,MAAM,qCAAqB,QAAA;AAC3B,IAAI,oBAAoB;AAExB,SAAS,cAAc,UAA0D;AAC/E,MAAI,aAAa,OAAW,QAAO;AACnC,MAAI,KAAK,eAAe,IAAI,QAAQ;AACpC,MAAI,OAAO,QAAW;AACpB,yBAAqB;AACrB,SAAK;AACL,mBAAe,IAAI,UAAU,EAAE;AAAA,EACjC;AACA,SAAO,UAAU,EAAE;AACrB;AASA,SAAS,kBAAkB,OAA0C;AACnE,MAAI,CAAC,MAAO,QAAO;AACnB,QAAM,UAAUA,iBAAAA,WAAW,KAAK;AAChC,MAAI,YAAY,KAAM,QAAO,SAASC,mBAAAA,mBAAmB,KAAK,CAAC;AAC/D,QAAM,QAAQC,iBAAAA,SAAS,KAAK;AAC5B,SAAO,UAAU,OACb,OAAOD,mBAAAA,mBAAmB,OAAO,CAAC,KAClC,OAAOA,mBAAAA,mBAAmB,OAAO,CAAC,UAAUA,mBAAAA,mBAAmB,KAAK,CAAC;AAC3E;AAUO,SAAS,wBACd,YACA,eACoB;AACpB,SAAO;AAAA,IACL;AAAA,IACA;AAAA,IACA,WAAW;AAAA,IACX,WAAW,aAAa;AAAA,IACxB,WAAW,SAASA,mBAAAA,mBAAmB,WAAW,MAAM,IAAI;AAAA,IAC5D,cAAc,WAAW,WAAW;AAAA,IACpC,kBAAkB,WAAW,SAAS;AAAA,IACtC;AAAA,EAAA;AAEJ;AAGA,MAAM,wCAA6C,IAAI,CAAC,KAAK,KAAK,KAAK,KAAK,GAAG,CAAC;AAGhF,SAAS,eAAe,cAAsB,OAAuB;AACnE,QAAM,SAAkB,QAAQ,IAAI,OAAO,QAAQ;AACnD,MAAI,OAAO,WAAW,YAAY,kBAAkB,IAAI,MAAM,EAAG,QAAO;AACxE,SAAO,eAAe;AACxB;AAoBO,SAAS,wBAAwB;AAAA,EACtC;AAAA,EACA;AAAA,EACA;AAAA,EACA;AACF,GAKoC;AAClC,QAAM,gBAAgBE,8BAAAA,iCAAA;AACtB,SAAOC,WAAAA;AAAAA,IACL;AAAA,MACE,UAAU,wBAAwB,YAAY,aAAa;AAAA,MAC3D,SAAS,CAAC,EAAE,OAAA,MACVC,kBAAAA;AAAAA,QAAsB;AAAA,QAAa,CAAC,SAClCC,IAAAA,qBAAqB,WAAW,YAAY,MAAM,EAAE,QAAQ;AAAA,MAAA;AAAA,MAEhE;AAAA,MACA,OAAO;AAAA,MACP,WAAW;AAAA,IAAA;AAAA,IAEb;AAAA,EAAA;AAEJ;;;"}
1
+ {"version":3,"file":"account-identity.cjs","sources":["../../src/auth/account-identity.ts"],"sourcesContent":["import { type QueryClient, type UseQueryResult, useQuery } from '@tanstack/react-query';\nimport { keyPartFingerprint } from '../lib/use-athena-rest-query';\nimport { type CredentialResolver, withCredentialRenewal } from '../runtime/credential-renewal';\nimport type { AthenaStatewireTokenGetter } from '../runtime/statewire-auth-headers';\nimport { type AccountIdentity, fetchAccountIdentity } from '../threads/api';\nimport { useAthenaCredentialIdentityEpoch } from './AthenaCredentialSourceContext';\nimport { jwtScope, jwtSubject } from './credential-source';\n\n/**\n * The credential an identity read is sent with, as its key names it: never\n * the secret itself.\n */\nexport interface AccountIdentityCredential {\n /** Agora's API base the read goes to. */\n backendUrl: string;\n /** The signed-in person (`AthenaAuthContext`'s user id), when one is. */\n principal: string | undefined;\n apiKey: string | undefined;\n /** The token the host holds now. A renewal for the same person and scope keeps the key. */\n heldToken: string | null | undefined;\n /** The provider's token getter (`config.getToken`), by identity. */\n tokenGetter: AthenaStatewireTokenGetter | undefined;\n}\n\n/** What one read presents, resolved when it is sent; `force` renews a refused token. */\nexport interface AccountIdentityAuth {\n apiKey?: string;\n token?: string | null;\n}\n\n/** One id per token getter, so the key can name a getter without holding it. */\nconst tokenGetterIds = new WeakMap<AthenaStatewireTokenGetter, number>();\nlet lastTokenGetterId = 0;\n\nfunction tokenGetterId(getToken: AthenaStatewireTokenGetter | undefined): string {\n if (getToken === undefined) return '';\n let id = tokenGetterIds.get(getToken);\n if (id === undefined) {\n lastTokenGetterId += 1;\n id = lastTokenGetterId;\n tokenGetterIds.set(getToken, id);\n }\n return `getter:${id}`;\n}\n\n/**\n * Who a held token acts as, and where, without the token: its JWT subject and\n * the claims scoping it to a workspace or org (`jwtScope`), or the token\n * itself when it is opaque, fingerprinted. A renewal for the same person and\n * scope keeps it, so a rotation is not a new identity; the same person's token\n * scoped to another workspace is.\n */\nfunction heldTokenIdentity(token: string | null | undefined): string {\n if (!token) return '';\n const subject = jwtSubject(token);\n if (subject === null) return `token:${keyPartFingerprint(token)}`;\n const scope = jwtScope(token);\n return scope === null\n ? `sub:${keyPartFingerprint(subject)}`\n : `sub:${keyPartFingerprint(subject)}|scope:${keyPartFingerprint(scope)}`;\n}\n\n/**\n * The parts of a query key that name a credential without holding it: the API\n * key's fingerprint, and who the held token acts as and where\n * (`heldTokenIdentity`). A renewal of the same person's token keeps them.\n */\nexport function credentialKeyParts({\n apiKey,\n heldToken,\n}: {\n apiKey: string | undefined;\n heldToken: string | null | undefined;\n}): readonly [string, string] {\n return [apiKey ? keyPartFingerprint(apiKey) : '', heldTokenIdentity(heldToken)];\n}\n\n/**\n * The one key a credential's identity is read under, whoever reads it: the\n * backend, the signed-in person, the API key's fingerprint, the provider's\n * token getter, who the held token acts as and which workspace it is scoped\n * to, and the provider's credential identity epoch\n * (`useAthenaCredentialIdentityEpoch`), which moves once the getter has handed\n * out a token that acts as someone else.\n */\nexport function accountIdentityQueryKey(\n credential: AccountIdentityCredential,\n identityEpoch: number,\n): readonly unknown[] {\n const [apiKeyPart, heldTokenPart] = credentialKeyParts({\n apiKey: credential.apiKey,\n heldToken: credential.heldToken,\n });\n return [\n 'athena-sdk',\n 'account',\n credential.backendUrl,\n credential.principal ?? '',\n apiKeyPart,\n tokenGetterId(credential.tokenGetter),\n heldTokenPart,\n identityEpoch,\n ];\n}\n\n/** A refusal, or a route an older agora lacks, answers the same way again. */\nconst NO_RETRY_STATUSES: ReadonlySet<number> = new Set([401, 403, 404, 405, 409]);\n\n/** Retry a transient failure twice; never a refused credential. */\nfunction retryTransient(failureCount: number, error: Error): boolean {\n const status: unknown = Reflect.get(error, 'status');\n if (typeof status === 'number' && NO_RETRY_STATUSES.has(status)) return false;\n return failureCount < 2;\n}\n\n/**\n * The credential's agora identity (`GET /api/v0/me`): one read per credential,\n * through the query cache, shared by every reader of it. `AthenaChat` (its\n * mentions workspace and the viewer behind its answer labels) and the session\n * list (the conversation index it attaches to) read it here under one key\n * (`accountIdentityQueryKey`), so a page with both sends one request. Never a\n * process-wide map: the key names the credential and never the secret. A\n * renewal for the same person and scope keeps the answer; an API-key switch, a\n * held token scoped to another workspace, or a getter now signing in someone\n * else, reads `/me` again under a new key, never a cached answer for the\n * previous credential. The epoch follows the person, not the scope: a getter\n * that alone hands out the same person's token for another workspace is read\n * again once the answer goes stale.\n *\n * `resolveAuth` presents the credential the key names, so whichever reader\n * sends the request, the answer is the same. `enabled` is the reader's own.\n * `queryClient` defaults to the one in context.\n */\nexport function useAccountIdentityQuery({\n credential,\n resolveAuth,\n enabled,\n queryClient,\n}: {\n credential: AccountIdentityCredential;\n resolveAuth: CredentialResolver<AccountIdentityAuth>;\n enabled: boolean;\n queryClient?: QueryClient;\n}): UseQueryResult<AccountIdentity> {\n const identityEpoch = useAthenaCredentialIdentityEpoch();\n return useQuery(\n {\n queryKey: accountIdentityQueryKey(credential, identityEpoch),\n queryFn: ({ signal }) =>\n withCredentialRenewal(resolveAuth, (auth) =>\n fetchAccountIdentity(credential.backendUrl, auth, { signal }),\n ),\n enabled,\n retry: retryTransient,\n staleTime: 60_000,\n },\n queryClient,\n );\n}\n"],"names":["jwtSubject","keyPartFingerprint","jwtScope","useAthenaCredentialIdentityEpoch","useQuery","withCredentialRenewal","fetchAccountIdentity"],"mappings":";;;;;;;;AA+BA,MAAM,qCAAqB,QAAA;AAC3B,IAAI,oBAAoB;AAExB,SAAS,cAAc,UAA0D;AAC/E,MAAI,aAAa,OAAW,QAAO;AACnC,MAAI,KAAK,eAAe,IAAI,QAAQ;AACpC,MAAI,OAAO,QAAW;AACpB,yBAAqB;AACrB,SAAK;AACL,mBAAe,IAAI,UAAU,EAAE;AAAA,EACjC;AACA,SAAO,UAAU,EAAE;AACrB;AASA,SAAS,kBAAkB,OAA0C;AACnE,MAAI,CAAC,MAAO,QAAO;AACnB,QAAM,UAAUA,iBAAAA,WAAW,KAAK;AAChC,MAAI,YAAY,KAAM,QAAO,SAASC,mBAAAA,mBAAmB,KAAK,CAAC;AAC/D,QAAM,QAAQC,iBAAAA,SAAS,KAAK;AAC5B,SAAO,UAAU,OACb,OAAOD,mBAAAA,mBAAmB,OAAO,CAAC,KAClC,OAAOA,mBAAAA,mBAAmB,OAAO,CAAC,UAAUA,mBAAAA,mBAAmB,KAAK,CAAC;AAC3E;AAOO,SAAS,mBAAmB;AAAA,EACjC;AAAA,EACA;AACF,GAG8B;AAC5B,SAAO,CAAC,SAASA,sCAAmB,MAAM,IAAI,IAAI,kBAAkB,SAAS,CAAC;AAChF;AAUO,SAAS,wBACd,YACA,eACoB;AACpB,QAAM,CAAC,YAAY,aAAa,IAAI,mBAAmB;AAAA,IACrD,QAAQ,WAAW;AAAA,IACnB,WAAW,WAAW;AAAA,EAAA,CACvB;AACD,SAAO;AAAA,IACL;AAAA,IACA;AAAA,IACA,WAAW;AAAA,IACX,WAAW,aAAa;AAAA,IACxB;AAAA,IACA,cAAc,WAAW,WAAW;AAAA,IACpC;AAAA,IACA;AAAA,EAAA;AAEJ;AAGA,MAAM,wCAA6C,IAAI,CAAC,KAAK,KAAK,KAAK,KAAK,GAAG,CAAC;AAGhF,SAAS,eAAe,cAAsB,OAAuB;AACnE,QAAM,SAAkB,QAAQ,IAAI,OAAO,QAAQ;AACnD,MAAI,OAAO,WAAW,YAAY,kBAAkB,IAAI,MAAM,EAAG,QAAO;AACxE,SAAO,eAAe;AACxB;AAoBO,SAAS,wBAAwB;AAAA,EACtC;AAAA,EACA;AAAA,EACA;AAAA,EACA;AACF,GAKoC;AAClC,QAAM,gBAAgBE,8BAAAA,iCAAA;AACtB,SAAOC,WAAAA;AAAAA,IACL;AAAA,MACE,UAAU,wBAAwB,YAAY,aAAa;AAAA,MAC3D,SAAS,CAAC,EAAE,OAAA,MACVC,kBAAAA;AAAAA,QAAsB;AAAA,QAAa,CAAC,SAClCC,IAAAA,qBAAqB,WAAW,YAAY,MAAM,EAAE,QAAQ;AAAA,MAAA;AAAA,MAEhE;AAAA,MACA,OAAO;AAAA,MACP,WAAW;AAAA,IAAA;AAAA,IAEb;AAAA,EAAA;AAEJ;;;;"}
@@ -22,6 +22,15 @@ export interface AccountIdentityAuth {
22
22
  apiKey?: string;
23
23
  token?: string | null;
24
24
  }
25
+ /**
26
+ * The parts of a query key that name a credential without holding it: the API
27
+ * key's fingerprint, and who the held token acts as and where
28
+ * (`heldTokenIdentity`). A renewal of the same person's token keeps them.
29
+ */
30
+ export declare function credentialKeyParts({ apiKey, heldToken, }: {
31
+ apiKey: string | undefined;
32
+ heldToken: string | null | undefined;
33
+ }): readonly [string, string];
25
34
  /**
26
35
  * The one key a credential's identity is read under, whoever reads it: the
27
36
  * backend, the signed-in person, the API key's fingerprint, the provider's
@@ -23,15 +23,25 @@ function heldTokenIdentity(token) {
23
23
  const scope = jwtScope(token);
24
24
  return scope === null ? `sub:${keyPartFingerprint(subject)}` : `sub:${keyPartFingerprint(subject)}|scope:${keyPartFingerprint(scope)}`;
25
25
  }
26
+ function credentialKeyParts({
27
+ apiKey,
28
+ heldToken
29
+ }) {
30
+ return [apiKey ? keyPartFingerprint(apiKey) : "", heldTokenIdentity(heldToken)];
31
+ }
26
32
  function accountIdentityQueryKey(credential, identityEpoch) {
33
+ const [apiKeyPart, heldTokenPart] = credentialKeyParts({
34
+ apiKey: credential.apiKey,
35
+ heldToken: credential.heldToken
36
+ });
27
37
  return [
28
38
  "athena-sdk",
29
39
  "account",
30
40
  credential.backendUrl,
31
41
  credential.principal ?? "",
32
- credential.apiKey ? keyPartFingerprint(credential.apiKey) : "",
42
+ apiKeyPart,
33
43
  tokenGetterId(credential.tokenGetter),
34
- heldTokenIdentity(credential.heldToken),
44
+ heldTokenPart,
35
45
  identityEpoch
36
46
  ];
37
47
  }
@@ -64,6 +74,7 @@ function useAccountIdentityQuery({
64
74
  }
65
75
  export {
66
76
  accountIdentityQueryKey,
77
+ credentialKeyParts,
67
78
  useAccountIdentityQuery
68
79
  };
69
80
  //# sourceMappingURL=account-identity.js.map
@@ -1 +1 @@
1
- {"version":3,"file":"account-identity.js","sources":["../../src/auth/account-identity.ts"],"sourcesContent":["import { type QueryClient, type UseQueryResult, useQuery } from '@tanstack/react-query';\nimport { keyPartFingerprint } from '../lib/use-athena-rest-query';\nimport { type CredentialResolver, withCredentialRenewal } from '../runtime/credential-renewal';\nimport type { AthenaStatewireTokenGetter } from '../runtime/statewire-auth-headers';\nimport { type AccountIdentity, fetchAccountIdentity } from '../threads/api';\nimport { useAthenaCredentialIdentityEpoch } from './AthenaCredentialSourceContext';\nimport { jwtScope, jwtSubject } from './credential-source';\n\n/**\n * The credential an identity read is sent with, as its key names it: never\n * the secret itself.\n */\nexport interface AccountIdentityCredential {\n /** Agora's API base the read goes to. */\n backendUrl: string;\n /** The signed-in person (`AthenaAuthContext`'s user id), when one is. */\n principal: string | undefined;\n apiKey: string | undefined;\n /** The token the host holds now. A renewal for the same person and scope keeps the key. */\n heldToken: string | null | undefined;\n /** The provider's token getter (`config.getToken`), by identity. */\n tokenGetter: AthenaStatewireTokenGetter | undefined;\n}\n\n/** What one read presents, resolved when it is sent; `force` renews a refused token. */\nexport interface AccountIdentityAuth {\n apiKey?: string;\n token?: string | null;\n}\n\n/** One id per token getter, so the key can name a getter without holding it. */\nconst tokenGetterIds = new WeakMap<AthenaStatewireTokenGetter, number>();\nlet lastTokenGetterId = 0;\n\nfunction tokenGetterId(getToken: AthenaStatewireTokenGetter | undefined): string {\n if (getToken === undefined) return '';\n let id = tokenGetterIds.get(getToken);\n if (id === undefined) {\n lastTokenGetterId += 1;\n id = lastTokenGetterId;\n tokenGetterIds.set(getToken, id);\n }\n return `getter:${id}`;\n}\n\n/**\n * Who a held token acts as, and where, without the token: its JWT subject and\n * the claims scoping it to a workspace or org (`jwtScope`), or the token\n * itself when it is opaque, fingerprinted. A renewal for the same person and\n * scope keeps it, so a rotation is not a new identity; the same person's token\n * scoped to another workspace is.\n */\nfunction heldTokenIdentity(token: string | null | undefined): string {\n if (!token) return '';\n const subject = jwtSubject(token);\n if (subject === null) return `token:${keyPartFingerprint(token)}`;\n const scope = jwtScope(token);\n return scope === null\n ? `sub:${keyPartFingerprint(subject)}`\n : `sub:${keyPartFingerprint(subject)}|scope:${keyPartFingerprint(scope)}`;\n}\n\n/**\n * The one key a credential's identity is read under, whoever reads it: the\n * backend, the signed-in person, the API key's fingerprint, the provider's\n * token getter, who the held token acts as and which workspace it is scoped\n * to, and the provider's credential identity epoch\n * (`useAthenaCredentialIdentityEpoch`), which moves once the getter has handed\n * out a token that acts as someone else.\n */\nexport function accountIdentityQueryKey(\n credential: AccountIdentityCredential,\n identityEpoch: number,\n): readonly unknown[] {\n return [\n 'athena-sdk',\n 'account',\n credential.backendUrl,\n credential.principal ?? '',\n credential.apiKey ? keyPartFingerprint(credential.apiKey) : '',\n tokenGetterId(credential.tokenGetter),\n heldTokenIdentity(credential.heldToken),\n identityEpoch,\n ];\n}\n\n/** A refusal, or a route an older agora lacks, answers the same way again. */\nconst NO_RETRY_STATUSES: ReadonlySet<number> = new Set([401, 403, 404, 405, 409]);\n\n/** Retry a transient failure twice; never a refused credential. */\nfunction retryTransient(failureCount: number, error: Error): boolean {\n const status: unknown = Reflect.get(error, 'status');\n if (typeof status === 'number' && NO_RETRY_STATUSES.has(status)) return false;\n return failureCount < 2;\n}\n\n/**\n * The credential's agora identity (`GET /api/v0/me`): one read per credential,\n * through the query cache, shared by every reader of it. `AthenaChat` (its\n * mentions workspace and the viewer behind its answer labels) and the session\n * list (the conversation index it attaches to) read it here under one key\n * (`accountIdentityQueryKey`), so a page with both sends one request. Never a\n * process-wide map: the key names the credential and never the secret. A\n * renewal for the same person and scope keeps the answer; an API-key switch, a\n * held token scoped to another workspace, or a getter now signing in someone\n * else, reads `/me` again under a new key, never a cached answer for the\n * previous credential. The epoch follows the person, not the scope: a getter\n * that alone hands out the same person's token for another workspace is read\n * again once the answer goes stale.\n *\n * `resolveAuth` presents the credential the key names, so whichever reader\n * sends the request, the answer is the same. `enabled` is the reader's own.\n * `queryClient` defaults to the one in context.\n */\nexport function useAccountIdentityQuery({\n credential,\n resolveAuth,\n enabled,\n queryClient,\n}: {\n credential: AccountIdentityCredential;\n resolveAuth: CredentialResolver<AccountIdentityAuth>;\n enabled: boolean;\n queryClient?: QueryClient;\n}): UseQueryResult<AccountIdentity> {\n const identityEpoch = useAthenaCredentialIdentityEpoch();\n return useQuery(\n {\n queryKey: accountIdentityQueryKey(credential, identityEpoch),\n queryFn: ({ signal }) =>\n withCredentialRenewal(resolveAuth, (auth) =>\n fetchAccountIdentity(credential.backendUrl, auth, { signal }),\n ),\n enabled,\n retry: retryTransient,\n staleTime: 60_000,\n },\n queryClient,\n );\n}\n"],"names":[],"mappings":";;;;;;AA+BA,MAAM,qCAAqB,QAAA;AAC3B,IAAI,oBAAoB;AAExB,SAAS,cAAc,UAA0D;AAC/E,MAAI,aAAa,OAAW,QAAO;AACnC,MAAI,KAAK,eAAe,IAAI,QAAQ;AACpC,MAAI,OAAO,QAAW;AACpB,yBAAqB;AACrB,SAAK;AACL,mBAAe,IAAI,UAAU,EAAE;AAAA,EACjC;AACA,SAAO,UAAU,EAAE;AACrB;AASA,SAAS,kBAAkB,OAA0C;AACnE,MAAI,CAAC,MAAO,QAAO;AACnB,QAAM,UAAU,WAAW,KAAK;AAChC,MAAI,YAAY,KAAM,QAAO,SAAS,mBAAmB,KAAK,CAAC;AAC/D,QAAM,QAAQ,SAAS,KAAK;AAC5B,SAAO,UAAU,OACb,OAAO,mBAAmB,OAAO,CAAC,KAClC,OAAO,mBAAmB,OAAO,CAAC,UAAU,mBAAmB,KAAK,CAAC;AAC3E;AAUO,SAAS,wBACd,YACA,eACoB;AACpB,SAAO;AAAA,IACL;AAAA,IACA;AAAA,IACA,WAAW;AAAA,IACX,WAAW,aAAa;AAAA,IACxB,WAAW,SAAS,mBAAmB,WAAW,MAAM,IAAI;AAAA,IAC5D,cAAc,WAAW,WAAW;AAAA,IACpC,kBAAkB,WAAW,SAAS;AAAA,IACtC;AAAA,EAAA;AAEJ;AAGA,MAAM,wCAA6C,IAAI,CAAC,KAAK,KAAK,KAAK,KAAK,GAAG,CAAC;AAGhF,SAAS,eAAe,cAAsB,OAAuB;AACnE,QAAM,SAAkB,QAAQ,IAAI,OAAO,QAAQ;AACnD,MAAI,OAAO,WAAW,YAAY,kBAAkB,IAAI,MAAM,EAAG,QAAO;AACxE,SAAO,eAAe;AACxB;AAoBO,SAAS,wBAAwB;AAAA,EACtC;AAAA,EACA;AAAA,EACA;AAAA,EACA;AACF,GAKoC;AAClC,QAAM,gBAAgB,iCAAA;AACtB,SAAO;AAAA,IACL;AAAA,MACE,UAAU,wBAAwB,YAAY,aAAa;AAAA,MAC3D,SAAS,CAAC,EAAE,OAAA,MACV;AAAA,QAAsB;AAAA,QAAa,CAAC,SAClC,qBAAqB,WAAW,YAAY,MAAM,EAAE,QAAQ;AAAA,MAAA;AAAA,MAEhE;AAAA,MACA,OAAO;AAAA,MACP,WAAW;AAAA,IAAA;AAAA,IAEb;AAAA,EAAA;AAEJ;"}
1
+ {"version":3,"file":"account-identity.js","sources":["../../src/auth/account-identity.ts"],"sourcesContent":["import { type QueryClient, type UseQueryResult, useQuery } from '@tanstack/react-query';\nimport { keyPartFingerprint } from '../lib/use-athena-rest-query';\nimport { type CredentialResolver, withCredentialRenewal } from '../runtime/credential-renewal';\nimport type { AthenaStatewireTokenGetter } from '../runtime/statewire-auth-headers';\nimport { type AccountIdentity, fetchAccountIdentity } from '../threads/api';\nimport { useAthenaCredentialIdentityEpoch } from './AthenaCredentialSourceContext';\nimport { jwtScope, jwtSubject } from './credential-source';\n\n/**\n * The credential an identity read is sent with, as its key names it: never\n * the secret itself.\n */\nexport interface AccountIdentityCredential {\n /** Agora's API base the read goes to. */\n backendUrl: string;\n /** The signed-in person (`AthenaAuthContext`'s user id), when one is. */\n principal: string | undefined;\n apiKey: string | undefined;\n /** The token the host holds now. A renewal for the same person and scope keeps the key. */\n heldToken: string | null | undefined;\n /** The provider's token getter (`config.getToken`), by identity. */\n tokenGetter: AthenaStatewireTokenGetter | undefined;\n}\n\n/** What one read presents, resolved when it is sent; `force` renews a refused token. */\nexport interface AccountIdentityAuth {\n apiKey?: string;\n token?: string | null;\n}\n\n/** One id per token getter, so the key can name a getter without holding it. */\nconst tokenGetterIds = new WeakMap<AthenaStatewireTokenGetter, number>();\nlet lastTokenGetterId = 0;\n\nfunction tokenGetterId(getToken: AthenaStatewireTokenGetter | undefined): string {\n if (getToken === undefined) return '';\n let id = tokenGetterIds.get(getToken);\n if (id === undefined) {\n lastTokenGetterId += 1;\n id = lastTokenGetterId;\n tokenGetterIds.set(getToken, id);\n }\n return `getter:${id}`;\n}\n\n/**\n * Who a held token acts as, and where, without the token: its JWT subject and\n * the claims scoping it to a workspace or org (`jwtScope`), or the token\n * itself when it is opaque, fingerprinted. A renewal for the same person and\n * scope keeps it, so a rotation is not a new identity; the same person's token\n * scoped to another workspace is.\n */\nfunction heldTokenIdentity(token: string | null | undefined): string {\n if (!token) return '';\n const subject = jwtSubject(token);\n if (subject === null) return `token:${keyPartFingerprint(token)}`;\n const scope = jwtScope(token);\n return scope === null\n ? `sub:${keyPartFingerprint(subject)}`\n : `sub:${keyPartFingerprint(subject)}|scope:${keyPartFingerprint(scope)}`;\n}\n\n/**\n * The parts of a query key that name a credential without holding it: the API\n * key's fingerprint, and who the held token acts as and where\n * (`heldTokenIdentity`). A renewal of the same person's token keeps them.\n */\nexport function credentialKeyParts({\n apiKey,\n heldToken,\n}: {\n apiKey: string | undefined;\n heldToken: string | null | undefined;\n}): readonly [string, string] {\n return [apiKey ? keyPartFingerprint(apiKey) : '', heldTokenIdentity(heldToken)];\n}\n\n/**\n * The one key a credential's identity is read under, whoever reads it: the\n * backend, the signed-in person, the API key's fingerprint, the provider's\n * token getter, who the held token acts as and which workspace it is scoped\n * to, and the provider's credential identity epoch\n * (`useAthenaCredentialIdentityEpoch`), which moves once the getter has handed\n * out a token that acts as someone else.\n */\nexport function accountIdentityQueryKey(\n credential: AccountIdentityCredential,\n identityEpoch: number,\n): readonly unknown[] {\n const [apiKeyPart, heldTokenPart] = credentialKeyParts({\n apiKey: credential.apiKey,\n heldToken: credential.heldToken,\n });\n return [\n 'athena-sdk',\n 'account',\n credential.backendUrl,\n credential.principal ?? '',\n apiKeyPart,\n tokenGetterId(credential.tokenGetter),\n heldTokenPart,\n identityEpoch,\n ];\n}\n\n/** A refusal, or a route an older agora lacks, answers the same way again. */\nconst NO_RETRY_STATUSES: ReadonlySet<number> = new Set([401, 403, 404, 405, 409]);\n\n/** Retry a transient failure twice; never a refused credential. */\nfunction retryTransient(failureCount: number, error: Error): boolean {\n const status: unknown = Reflect.get(error, 'status');\n if (typeof status === 'number' && NO_RETRY_STATUSES.has(status)) return false;\n return failureCount < 2;\n}\n\n/**\n * The credential's agora identity (`GET /api/v0/me`): one read per credential,\n * through the query cache, shared by every reader of it. `AthenaChat` (its\n * mentions workspace and the viewer behind its answer labels) and the session\n * list (the conversation index it attaches to) read it here under one key\n * (`accountIdentityQueryKey`), so a page with both sends one request. Never a\n * process-wide map: the key names the credential and never the secret. A\n * renewal for the same person and scope keeps the answer; an API-key switch, a\n * held token scoped to another workspace, or a getter now signing in someone\n * else, reads `/me` again under a new key, never a cached answer for the\n * previous credential. The epoch follows the person, not the scope: a getter\n * that alone hands out the same person's token for another workspace is read\n * again once the answer goes stale.\n *\n * `resolveAuth` presents the credential the key names, so whichever reader\n * sends the request, the answer is the same. `enabled` is the reader's own.\n * `queryClient` defaults to the one in context.\n */\nexport function useAccountIdentityQuery({\n credential,\n resolveAuth,\n enabled,\n queryClient,\n}: {\n credential: AccountIdentityCredential;\n resolveAuth: CredentialResolver<AccountIdentityAuth>;\n enabled: boolean;\n queryClient?: QueryClient;\n}): UseQueryResult<AccountIdentity> {\n const identityEpoch = useAthenaCredentialIdentityEpoch();\n return useQuery(\n {\n queryKey: accountIdentityQueryKey(credential, identityEpoch),\n queryFn: ({ signal }) =>\n withCredentialRenewal(resolveAuth, (auth) =>\n fetchAccountIdentity(credential.backendUrl, auth, { signal }),\n ),\n enabled,\n retry: retryTransient,\n staleTime: 60_000,\n },\n queryClient,\n );\n}\n"],"names":[],"mappings":";;;;;;AA+BA,MAAM,qCAAqB,QAAA;AAC3B,IAAI,oBAAoB;AAExB,SAAS,cAAc,UAA0D;AAC/E,MAAI,aAAa,OAAW,QAAO;AACnC,MAAI,KAAK,eAAe,IAAI,QAAQ;AACpC,MAAI,OAAO,QAAW;AACpB,yBAAqB;AACrB,SAAK;AACL,mBAAe,IAAI,UAAU,EAAE;AAAA,EACjC;AACA,SAAO,UAAU,EAAE;AACrB;AASA,SAAS,kBAAkB,OAA0C;AACnE,MAAI,CAAC,MAAO,QAAO;AACnB,QAAM,UAAU,WAAW,KAAK;AAChC,MAAI,YAAY,KAAM,QAAO,SAAS,mBAAmB,KAAK,CAAC;AAC/D,QAAM,QAAQ,SAAS,KAAK;AAC5B,SAAO,UAAU,OACb,OAAO,mBAAmB,OAAO,CAAC,KAClC,OAAO,mBAAmB,OAAO,CAAC,UAAU,mBAAmB,KAAK,CAAC;AAC3E;AAOO,SAAS,mBAAmB;AAAA,EACjC;AAAA,EACA;AACF,GAG8B;AAC5B,SAAO,CAAC,SAAS,mBAAmB,MAAM,IAAI,IAAI,kBAAkB,SAAS,CAAC;AAChF;AAUO,SAAS,wBACd,YACA,eACoB;AACpB,QAAM,CAAC,YAAY,aAAa,IAAI,mBAAmB;AAAA,IACrD,QAAQ,WAAW;AAAA,IACnB,WAAW,WAAW;AAAA,EAAA,CACvB;AACD,SAAO;AAAA,IACL;AAAA,IACA;AAAA,IACA,WAAW;AAAA,IACX,WAAW,aAAa;AAAA,IACxB;AAAA,IACA,cAAc,WAAW,WAAW;AAAA,IACpC;AAAA,IACA;AAAA,EAAA;AAEJ;AAGA,MAAM,wCAA6C,IAAI,CAAC,KAAK,KAAK,KAAK,KAAK,GAAG,CAAC;AAGhF,SAAS,eAAe,cAAsB,OAAuB;AACnE,QAAM,SAAkB,QAAQ,IAAI,OAAO,QAAQ;AACnD,MAAI,OAAO,WAAW,YAAY,kBAAkB,IAAI,MAAM,EAAG,QAAO;AACxE,SAAO,eAAe;AACxB;AAoBO,SAAS,wBAAwB;AAAA,EACtC;AAAA,EACA;AAAA,EACA;AAAA,EACA;AACF,GAKoC;AAClC,QAAM,gBAAgB,iCAAA;AACtB,SAAO;AAAA,IACL;AAAA,MACE,UAAU,wBAAwB,YAAY,aAAa;AAAA,MAC3D,SAAS,CAAC,EAAE,OAAA,MACV;AAAA,QAAsB;AAAA,QAAa,CAAC,SAClC,qBAAqB,WAAW,YAAY,MAAM,EAAE,QAAQ;AAAA,MAAA;AAAA,MAEhE;AAAA,MACA,OAAO;AAAA,MACP,WAAW;AAAA,IAAA;AAAA,IAEb;AAAA,EAAA;AAEJ;"}
@@ -47,6 +47,8 @@ function createAthenaCredentialSource(read) {
47
47
  let lastResolved = null;
48
48
  let identity = null;
49
49
  let identityEpoch = 0;
50
+ let scope = null;
51
+ let scopeEpoch = 0;
50
52
  const notifyListeners = () => {
51
53
  for (const listener of [...listeners]) listener();
52
54
  };
@@ -59,17 +61,30 @@ function createAthenaCredentialSource(read) {
59
61
  if (changed) identityEpoch += 1;
60
62
  return changed;
61
63
  };
64
+ const observeScope = (token) => {
65
+ if (!token) return false;
66
+ const subject = jwtSubject(token);
67
+ const next = subject === null ? token : `${subject}\0${jwtScope(token) ?? ""}`;
68
+ if (next === scope) return false;
69
+ const changed = scope !== null;
70
+ scope = next;
71
+ if (changed) scopeEpoch += 1;
72
+ return changed;
73
+ };
62
74
  const notifyTokenChanged = () => {
63
- observeIdentity(read().token);
75
+ const token = read().token;
76
+ observeIdentity(token);
77
+ observeScope(token);
64
78
  notifyListeners();
65
79
  };
66
80
  const settle = (token) => {
67
81
  const identityChanged = observeIdentity(token);
82
+ const scopeChanged = observeScope(token);
68
83
  if (token !== null && token !== lastResolved) {
69
84
  const replaced = lastResolved !== null;
70
85
  lastResolved = token;
71
- if (replaced || identityChanged) notifyListeners();
72
- } else if (identityChanged) {
86
+ if (replaced || identityChanged || scopeChanged) notifyListeners();
87
+ } else if (identityChanged || scopeChanged) {
73
88
  notifyListeners();
74
89
  }
75
90
  return token;
@@ -121,7 +136,8 @@ function createAthenaCredentialSource(read) {
121
136
  };
122
137
  },
123
138
  notifyTokenChanged,
124
- identityEpoch: () => identityEpoch
139
+ identityEpoch: () => identityEpoch,
140
+ scopeEpoch: () => scopeEpoch
125
141
  };
126
142
  }
127
143
  exports.TOKEN_EXPIRY_SKEW_MS = TOKEN_EXPIRY_SKEW_MS;
@@ -1 +1 @@
1
- {"version":3,"file":"credential-source.cjs","sources":["../../src/auth/credential-source.ts"],"sourcesContent":["import type { AthenaStatewireTokenGetter } from '../runtime/statewire-auth-headers';\n\n/**\n * Renews a token-backed sign-in. `force: true` means the token just presented\n * was refused, or has expired: the renewer must obtain a new one rather than\n * return the one it holds. Resolves `null` when it cannot produce a token.\n */\nexport type AthenaTokenRenewer = (options: { force: boolean }) => Promise<string | null>;\n\n/** What the credential source reads, fresh, on every resolve. */\nexport interface AthenaCredentialInputs {\n /**\n * The host's own getter (`config.getToken`). It owns renewal for its\n * sign-in, so it always wins; the held `token` is its fallback when it\n * resolves nothing.\n */\n hostGetToken?: AthenaStatewireTokenGetter;\n /** The token currently held: the host's, the sign-in provider's or the host bridge's. */\n token: string | null | undefined;\n /** How that token renews (the sign-in provider or the host bridge); absent for a static token. */\n renew?: AthenaTokenRenewer;\n}\n\n/**\n * The single place every SDK network path gets the token it presents — the\n * live thread connection, the session list's index and REST calls, uploads,\n * search, voice and the collaborative-document mint — read right before it is\n * presented.\n */\nexport interface AthenaCredentialSource {\n /**\n * The token to present now. `force` renews it first (the previous one was\n * refused). A token that has expired, or expires within\n * {@link TOKEN_EXPIRY_SKEW_MS}, is renewed before it is presented, so a tab\n * waking from sleep never presents a dead token. Concurrent renewals share\n * one in-flight request, and calls made while one is in flight wait for it\n * instead of presenting the token it is replacing. A renewal never hands one\n * account's token to a call made after the signed-in account changed.\n */\n getToken: (options?: { force?: boolean }) => Promise<string | null>;\n /** Called, with no arguments, whenever a different token becomes current. */\n subscribe: (listener: () => void) => () => void;\n /**\n * How many times the identity behind the token has changed: its JWT\n * subject, or the token itself when it is opaque. Renewals for the same\n * identity leave it alone. Long-lived connections key on it, so they keep\n * running across renewals and are rebuilt when someone else signs in,\n * including under a host `getToken`, whose identity is only known once a\n * token has been resolved. Subscribers hear when it moves.\n */\n identityEpoch: () => number;\n /** Tell subscribers the held token changed (the provider calls this when its inputs do). */\n notifyTokenChanged: () => void;\n}\n\n/** A token this close to its expiry is renewed before it is presented. */\nexport const TOKEN_EXPIRY_SKEW_MS = 30_000;\n\n/** The unverified claims of a JWT, or `null` for anything that is not one. */\nfunction jwtClaims(token: string): Record<string, unknown> | null {\n const payload = token.split('.')[1];\n if (!payload) return null;\n try {\n const base64 = payload.replace(/-/g, '+').replace(/_/g, '/');\n const padded = base64.padEnd(Math.ceil(base64.length / 4) * 4, '=');\n const claims: unknown = JSON.parse(atob(padded));\n return typeof claims === 'object' && claims !== null && !Array.isArray(claims)\n ? (claims as Record<string, unknown>)\n : null;\n } catch {\n return null;\n }\n}\n\n/**\n * The `exp` of a JWT, in milliseconds, or `null` for anything that is not a\n * JWT with a numeric `exp`. Read without verification: it only decides whether\n * to renew before presenting; the server still validates every token.\n */\nexport function jwtExpiresAtMs(token: string): number | null {\n const exp = jwtClaims(token)?.exp;\n return typeof exp === 'number' && Number.isFinite(exp) ? exp * 1000 : null;\n}\n\n/** The unverified `sub` of a JWT, or `null` for anything that is not a JWT with one. */\nexport function jwtSubject(token: string): string | null {\n const sub = jwtClaims(token)?.sub;\n return typeof sub === 'string' && sub.length > 0 ? sub : null;\n}\n\n/**\n * The unverified claims that scope a JWT to a workspace or org, as one stable\n * string, or `null` when it names none: Athena's `workspace_id` (an Office\n * session's token), `org_id` (an external sign-in's), and PropelAuth's\n * active-org `org_member_info.org_id`. Two of one person's tokens scoped to\n * different workspaces read differently; a renewal keeps it.\n */\nexport function jwtScope(token: string): string | null {\n const claims = jwtClaims(token);\n if (claims === null) return null;\n const orgMember = claims.org_member_info;\n const scope = [\n ['workspace_id', claims.workspace_id],\n ['org_id', claims.org_id],\n [\n 'org_member_info.org_id',\n typeof orgMember === 'object' && orgMember !== null\n ? (orgMember as Record<string, unknown>).org_id\n : undefined,\n ],\n ]\n .filter((entry): entry is [string, string] => typeof entry[1] === 'string' && entry[1].length > 0)\n .map(([claim, value]) => `${claim}=${value}`);\n return scope.length > 0 ? scope.join('\\u0000') : null;\n}\n\n/** True for a JWT that has expired or expires within {@link TOKEN_EXPIRY_SKEW_MS}. */\nexport function isTokenExpiring(token: string, now: number = Date.now()): boolean {\n const expiresAt = jwtExpiresAtMs(token);\n return expiresAt !== null && expiresAt - now <= TOKEN_EXPIRY_SKEW_MS;\n}\n\nexport function createAthenaCredentialSource(\n read: () => AthenaCredentialInputs,\n): AthenaCredentialSource {\n const listeners = new Set<() => void>();\n // The renewal in flight, and whether the host's getter runs it (the host\n // owns identity for its getter) or the sign-in provider's / bridge's renewer.\n let renewal: { token: Promise<string | null>; byHost: boolean } | null = null;\n let lastResolved: string | null = null;\n let identity: string | null = null;\n let identityEpoch = 0;\n\n const notifyListeners = () => {\n for (const listener of [...listeners]) listener();\n };\n\n /** Note who a token acts as; true when that is someone other than before. */\n const observeIdentity = (token: string | null | undefined): boolean => {\n if (!token) return false;\n const next = jwtSubject(token) ?? token;\n if (next === identity) return false;\n const changed = identity !== null;\n identity = next;\n if (changed) identityEpoch += 1;\n return changed;\n };\n\n const notifyTokenChanged = () => {\n observeIdentity(read().token);\n notifyListeners();\n };\n\n /** Record what a resolve produced; a different token than the last one is news. */\n const settle = (token: string | null): string | null => {\n const identityChanged = observeIdentity(token);\n if (token !== null && token !== lastResolved) {\n const replaced = lastResolved !== null;\n lastResolved = token;\n if (replaced || identityChanged) notifyListeners();\n } else if (identityChanged) {\n notifyListeners();\n }\n return token;\n };\n\n const shareRenewal = (\n start: () => Promise<string | null>,\n byHost: boolean,\n ): { token: Promise<string | null>; byHost: boolean } => {\n if (!renewal) {\n const entry = {\n token: start().finally(() => {\n if (renewal === entry) renewal = null;\n }),\n byHost,\n };\n renewal = entry;\n }\n return renewal;\n };\n\n /**\n * What a finished renewal hands one caller. A host getter's token is\n * presented as is: the host owns identity for its getter. A sign-in\n * provider's or bridge's renewed token is presented only while it acts as\n * the account the provider holds now. When the account changed while the\n * renewal was in flight (its JWT subject differs from the held token's, or\n * the provider holds no token any more), the held token, the current\n * account's, is presented instead. A renewal that produced nothing keeps\n * the held token: the caller presents it and the host's refusal ends the\n * attempt.\n */\n const presentable = (\n { byHost }: { byHost: boolean },\n renewed: string | null,\n ): string | null => {\n const held = read().token ?? null;\n if (byHost) return renewed ?? held;\n if (!renewed || !held) return held;\n const heldSubject = jwtSubject(held);\n const renewedSubject = jwtSubject(renewed);\n return heldSubject && renewedSubject && heldSubject !== renewedSubject ? held : renewed;\n };\n\n const awaitRenewal = async (shared: {\n token: Promise<string | null>;\n byHost: boolean;\n }): Promise<string | null> => settle(presentable(shared, await shared.token));\n\n const getToken = async ({ force = false }: { force?: boolean } = {}): Promise<string | null> => {\n if (renewal) return awaitRenewal(renewal);\n const inputs = read();\n const hostGetToken = inputs.hostGetToken;\n if (hostGetToken) {\n if (!force) return settle((await hostGetToken({ force: false })) ?? read().token ?? null);\n return awaitRenewal(\n shareRenewal(async () => (await hostGetToken({ force: true })) ?? null, true),\n );\n }\n const current = inputs.token ?? null;\n const renew = inputs.renew;\n if (!renew) return settle(current);\n const stale = force || (current !== null && isTokenExpiring(current));\n if (!stale) return settle(current);\n return awaitRenewal(shareRenewal(() => renew({ force: true }), false));\n };\n\n return {\n getToken,\n subscribe: (listener) => {\n listeners.add(listener);\n return () => {\n listeners.delete(listener);\n };\n },\n notifyTokenChanged,\n identityEpoch: () => identityEpoch,\n };\n}\n"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"credential-source.cjs","sources":["../../src/auth/credential-source.ts"],"sourcesContent":["import type { AthenaStatewireTokenGetter } from '../runtime/statewire-auth-headers';\n\n/**\n * Renews a token-backed sign-in. `force: true` means the token just presented\n * was refused, or has expired: the renewer must obtain a new one rather than\n * return the one it holds. Resolves `null` when it cannot produce a token.\n */\nexport type AthenaTokenRenewer = (options: { force: boolean }) => Promise<string | null>;\n\n/** What the credential source reads, fresh, on every resolve. */\nexport interface AthenaCredentialInputs {\n /**\n * The host's own getter (`config.getToken`). It owns renewal for its\n * sign-in, so it always wins; the held `token` is its fallback when it\n * resolves nothing.\n */\n hostGetToken?: AthenaStatewireTokenGetter;\n /** The token currently held: the host's, the sign-in provider's or the host bridge's. */\n token: string | null | undefined;\n /** How that token renews (the sign-in provider or the host bridge); absent for a static token. */\n renew?: AthenaTokenRenewer;\n}\n\n/**\n * The single place every SDK network path gets the token it presents — the\n * live thread connection, the session list's index and REST calls, uploads,\n * search, voice and the collaborative-document mint — read right before it is\n * presented.\n */\nexport interface AthenaCredentialSource {\n /**\n * The token to present now. `force` renews it first (the previous one was\n * refused). A token that has expired, or expires within\n * {@link TOKEN_EXPIRY_SKEW_MS}, is renewed before it is presented, so a tab\n * waking from sleep never presents a dead token. Concurrent renewals share\n * one in-flight request, and calls made while one is in flight wait for it\n * instead of presenting the token it is replacing. A renewal never hands one\n * account's token to a call made after the signed-in account changed.\n */\n getToken: (options?: { force?: boolean }) => Promise<string | null>;\n /** Called, with no arguments, whenever a different token becomes current. */\n subscribe: (listener: () => void) => () => void;\n /**\n * How many times the identity behind the token has changed: its JWT\n * subject, or the token itself when it is opaque. Renewals for the same\n * identity leave it alone. Long-lived connections key on it, so they keep\n * running across renewals and are rebuilt when someone else signs in,\n * including under a host `getToken`, whose identity is only known once a\n * token has been resolved. Subscribers hear when it moves.\n */\n identityEpoch: () => number;\n /**\n * How many times where the token acts has changed: its person (as\n * `identityEpoch` counts them) or the workspace or org its claims scope it\n * to (`jwtScope`). Renewals for the same person and scope leave it alone.\n * Caches of what the person may read key on it, so a host `getToken` that\n * hands out the same person's token for another workspace reads again under\n * new keys. Subscribers hear when it moves.\n */\n scopeEpoch: () => number;\n /** Tell subscribers the held token changed (the provider calls this when its inputs do). */\n notifyTokenChanged: () => void;\n}\n\n/** A token this close to its expiry is renewed before it is presented. */\nexport const TOKEN_EXPIRY_SKEW_MS = 30_000;\n\n/** The unverified claims of a JWT, or `null` for anything that is not one. */\nfunction jwtClaims(token: string): Record<string, unknown> | null {\n const payload = token.split('.')[1];\n if (!payload) return null;\n try {\n const base64 = payload.replace(/-/g, '+').replace(/_/g, '/');\n const padded = base64.padEnd(Math.ceil(base64.length / 4) * 4, '=');\n const claims: unknown = JSON.parse(atob(padded));\n return typeof claims === 'object' && claims !== null && !Array.isArray(claims)\n ? (claims as Record<string, unknown>)\n : null;\n } catch {\n return null;\n }\n}\n\n/**\n * The `exp` of a JWT, in milliseconds, or `null` for anything that is not a\n * JWT with a numeric `exp`. Read without verification: it only decides whether\n * to renew before presenting; the server still validates every token.\n */\nexport function jwtExpiresAtMs(token: string): number | null {\n const exp = jwtClaims(token)?.exp;\n return typeof exp === 'number' && Number.isFinite(exp) ? exp * 1000 : null;\n}\n\n/** The unverified `sub` of a JWT, or `null` for anything that is not a JWT with one. */\nexport function jwtSubject(token: string): string | null {\n const sub = jwtClaims(token)?.sub;\n return typeof sub === 'string' && sub.length > 0 ? sub : null;\n}\n\n/**\n * The unverified claims that scope a JWT to a workspace or org, as one stable\n * string, or `null` when it names none: Athena's `workspace_id` (an Office\n * session's token), `org_id` (an external sign-in's), and PropelAuth's\n * active-org `org_member_info.org_id`. Two of one person's tokens scoped to\n * different workspaces read differently; a renewal keeps it.\n */\nexport function jwtScope(token: string): string | null {\n const claims = jwtClaims(token);\n if (claims === null) return null;\n const orgMember = claims.org_member_info;\n const scope = [\n ['workspace_id', claims.workspace_id],\n ['org_id', claims.org_id],\n [\n 'org_member_info.org_id',\n typeof orgMember === 'object' && orgMember !== null\n ? (orgMember as Record<string, unknown>).org_id\n : undefined,\n ],\n ]\n .filter((entry): entry is [string, string] => typeof entry[1] === 'string' && entry[1].length > 0)\n .map(([claim, value]) => `${claim}=${value}`);\n return scope.length > 0 ? scope.join('\\u0000') : null;\n}\n\n/** True for a JWT that has expired or expires within {@link TOKEN_EXPIRY_SKEW_MS}. */\nexport function isTokenExpiring(token: string, now: number = Date.now()): boolean {\n const expiresAt = jwtExpiresAtMs(token);\n return expiresAt !== null && expiresAt - now <= TOKEN_EXPIRY_SKEW_MS;\n}\n\nexport function createAthenaCredentialSource(\n read: () => AthenaCredentialInputs,\n): AthenaCredentialSource {\n const listeners = new Set<() => void>();\n // The renewal in flight, and whether the host's getter runs it (the host\n // owns identity for its getter) or the sign-in provider's / bridge's renewer.\n let renewal: { token: Promise<string | null>; byHost: boolean } | null = null;\n let lastResolved: string | null = null;\n let identity: string | null = null;\n let identityEpoch = 0;\n let scope: string | null = null;\n let scopeEpoch = 0;\n\n const notifyListeners = () => {\n for (const listener of [...listeners]) listener();\n };\n\n /** Note who a token acts as; true when that is someone other than before. */\n const observeIdentity = (token: string | null | undefined): boolean => {\n if (!token) return false;\n const next = jwtSubject(token) ?? token;\n if (next === identity) return false;\n const changed = identity !== null;\n identity = next;\n if (changed) identityEpoch += 1;\n return changed;\n };\n\n /** Note who a token acts as and where (`jwtScope`); true when either differs from before. */\n const observeScope = (token: string | null | undefined): boolean => {\n if (!token) return false;\n const subject = jwtSubject(token);\n const next = subject === null ? token : `${subject}\\u0000${jwtScope(token) ?? ''}`;\n if (next === scope) return false;\n const changed = scope !== null;\n scope = next;\n if (changed) scopeEpoch += 1;\n return changed;\n };\n\n const notifyTokenChanged = () => {\n const token = read().token;\n observeIdentity(token);\n observeScope(token);\n notifyListeners();\n };\n\n /** Record what a resolve produced; a different token than the last one is news. */\n const settle = (token: string | null): string | null => {\n const identityChanged = observeIdentity(token);\n const scopeChanged = observeScope(token);\n if (token !== null && token !== lastResolved) {\n const replaced = lastResolved !== null;\n lastResolved = token;\n if (replaced || identityChanged || scopeChanged) notifyListeners();\n } else if (identityChanged || scopeChanged) {\n notifyListeners();\n }\n return token;\n };\n\n const shareRenewal = (\n start: () => Promise<string | null>,\n byHost: boolean,\n ): { token: Promise<string | null>; byHost: boolean } => {\n if (!renewal) {\n const entry = {\n token: start().finally(() => {\n if (renewal === entry) renewal = null;\n }),\n byHost,\n };\n renewal = entry;\n }\n return renewal;\n };\n\n /**\n * What a finished renewal hands one caller. A host getter's token is\n * presented as is: the host owns identity for its getter. A sign-in\n * provider's or bridge's renewed token is presented only while it acts as\n * the account the provider holds now. When the account changed while the\n * renewal was in flight (its JWT subject differs from the held token's, or\n * the provider holds no token any more), the held token, the current\n * account's, is presented instead. A renewal that produced nothing keeps\n * the held token: the caller presents it and the host's refusal ends the\n * attempt.\n */\n const presentable = (\n { byHost }: { byHost: boolean },\n renewed: string | null,\n ): string | null => {\n const held = read().token ?? null;\n if (byHost) return renewed ?? held;\n if (!renewed || !held) return held;\n const heldSubject = jwtSubject(held);\n const renewedSubject = jwtSubject(renewed);\n return heldSubject && renewedSubject && heldSubject !== renewedSubject ? held : renewed;\n };\n\n const awaitRenewal = async (shared: {\n token: Promise<string | null>;\n byHost: boolean;\n }): Promise<string | null> => settle(presentable(shared, await shared.token));\n\n const getToken = async ({ force = false }: { force?: boolean } = {}): Promise<string | null> => {\n if (renewal) return awaitRenewal(renewal);\n const inputs = read();\n const hostGetToken = inputs.hostGetToken;\n if (hostGetToken) {\n if (!force) return settle((await hostGetToken({ force: false })) ?? read().token ?? null);\n return awaitRenewal(\n shareRenewal(async () => (await hostGetToken({ force: true })) ?? null, true),\n );\n }\n const current = inputs.token ?? null;\n const renew = inputs.renew;\n if (!renew) return settle(current);\n const stale = force || (current !== null && isTokenExpiring(current));\n if (!stale) return settle(current);\n return awaitRenewal(shareRenewal(() => renew({ force: true }), false));\n };\n\n return {\n getToken,\n subscribe: (listener) => {\n listeners.add(listener);\n return () => {\n listeners.delete(listener);\n };\n },\n notifyTokenChanged,\n identityEpoch: () => identityEpoch,\n scopeEpoch: () => scopeEpoch,\n };\n}\n"],"names":[],"mappings":"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"}
@@ -50,6 +50,15 @@ export interface AthenaCredentialSource {
50
50
  * token has been resolved. Subscribers hear when it moves.
51
51
  */
52
52
  identityEpoch: () => number;
53
+ /**
54
+ * How many times where the token acts has changed: its person (as
55
+ * `identityEpoch` counts them) or the workspace or org its claims scope it
56
+ * to (`jwtScope`). Renewals for the same person and scope leave it alone.
57
+ * Caches of what the person may read key on it, so a host `getToken` that
58
+ * hands out the same person's token for another workspace reads again under
59
+ * new keys. Subscribers hear when it moves.
60
+ */
61
+ scopeEpoch: () => number;
53
62
  /** Tell subscribers the held token changed (the provider calls this when its inputs do). */
54
63
  notifyTokenChanged: () => void;
55
64
  }