@athenaintel/react 0.57.1 → 0.59.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 (811) hide show
  1. package/README.md +778 -9
  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.map +1 -1
  46. package/dist/agent-runtime/src/composer-markdown.d.ts +1 -1
  47. package/dist/agent-runtime/src/composer-markdown.js.map +1 -1
  48. package/dist/agent-runtime/src/deep-agent-transport-recipe.cjs +3 -1
  49. package/dist/agent-runtime/src/deep-agent-transport-recipe.cjs.map +1 -1
  50. package/dist/agent-runtime/src/deep-agent-transport-recipe.d.ts +8 -1
  51. package/dist/agent-runtime/src/deep-agent-transport-recipe.js +3 -1
  52. package/dist/agent-runtime/src/deep-agent-transport-recipe.js.map +1 -1
  53. package/dist/agent-runtime/src/dictation-preferences.d.ts +356 -0
  54. package/dist/agent-runtime/src/dictation-record.d.ts +279 -0
  55. package/dist/agent-runtime/src/dictation-session.d.ts +106 -7
  56. package/dist/agent-runtime/src/dictation-snippets.d.ts +9 -0
  57. package/dist/agent-runtime/src/dictation-transfer.d.ts +142 -0
  58. package/dist/agent-runtime/src/edit-command.cjs.map +1 -1
  59. package/dist/agent-runtime/src/edit-command.d.ts +1 -1
  60. package/dist/agent-runtime/src/edit-command.js.map +1 -1
  61. package/dist/agent-runtime/src/errors.cjs +1 -0
  62. package/dist/agent-runtime/src/errors.cjs.map +1 -1
  63. package/dist/agent-runtime/src/errors.js +1 -0
  64. package/dist/agent-runtime/src/errors.js.map +1 -1
  65. package/dist/agent-runtime/src/generated/runconfig-contract.cjs +24 -0
  66. package/dist/agent-runtime/src/generated/runconfig-contract.cjs.map +1 -1
  67. package/dist/agent-runtime/src/generated/runconfig-contract.d.ts +3 -3
  68. package/dist/agent-runtime/src/generated/runconfig-contract.js +24 -0
  69. package/dist/agent-runtime/src/generated/runconfig-contract.js.map +1 -1
  70. package/dist/agent-runtime/src/index.d.ts +14 -8
  71. package/dist/agent-runtime/src/lane-follow.cjs +289 -0
  72. package/dist/agent-runtime/src/lane-follow.cjs.map +1 -0
  73. package/dist/agent-runtime/src/lane-follow.js +289 -0
  74. package/dist/agent-runtime/src/lane-follow.js.map +1 -0
  75. package/dist/agent-runtime/src/lane-images.cjs +387 -0
  76. package/dist/agent-runtime/src/lane-images.cjs.map +1 -0
  77. package/dist/agent-runtime/src/lane-images.js +387 -0
  78. package/dist/agent-runtime/src/lane-images.js.map +1 -0
  79. package/dist/agent-runtime/src/message-window.js +1 -1
  80. package/dist/agent-runtime/src/messages.cjs +19 -1
  81. package/dist/agent-runtime/src/messages.cjs.map +1 -1
  82. package/dist/agent-runtime/src/messages.d.ts +8 -0
  83. package/dist/agent-runtime/src/messages.js +21 -3
  84. package/dist/agent-runtime/src/messages.js.map +1 -1
  85. package/dist/agent-runtime/src/named-agents.cjs +301 -0
  86. package/dist/agent-runtime/src/named-agents.cjs.map +1 -0
  87. package/dist/agent-runtime/src/named-agents.d.ts +246 -0
  88. package/dist/agent-runtime/src/named-agents.js +301 -0
  89. package/dist/agent-runtime/src/named-agents.js.map +1 -0
  90. package/dist/agent-runtime/src/offline-status.cjs.map +1 -1
  91. package/dist/agent-runtime/src/offline-status.d.ts +66 -2
  92. package/dist/agent-runtime/src/offline-status.js.map +1 -1
  93. package/dist/agent-runtime/src/ptc-subcalls.cjs +41 -0
  94. package/dist/agent-runtime/src/ptc-subcalls.cjs.map +1 -0
  95. package/dist/agent-runtime/src/ptc-subcalls.js +41 -0
  96. package/dist/agent-runtime/src/ptc-subcalls.js.map +1 -0
  97. package/dist/agent-runtime/src/queue.cjs +2 -2
  98. package/dist/agent-runtime/src/queue.cjs.map +1 -1
  99. package/dist/agent-runtime/src/queue.d.ts +20 -25
  100. package/dist/agent-runtime/src/queue.js +2 -2
  101. package/dist/agent-runtime/src/queue.js.map +1 -1
  102. package/dist/agent-runtime/src/quota-safe-local-storage-session.cjs +314 -84
  103. package/dist/agent-runtime/src/quota-safe-local-storage-session.cjs.map +1 -1
  104. package/dist/agent-runtime/src/quota-safe-local-storage-session.d.ts +137 -40
  105. package/dist/agent-runtime/src/quota-safe-local-storage-session.js +318 -88
  106. package/dist/agent-runtime/src/quota-safe-local-storage-session.js.map +1 -1
  107. package/dist/agent-runtime/src/run-send.cjs +54 -0
  108. package/dist/agent-runtime/src/run-send.cjs.map +1 -0
  109. package/dist/agent-runtime/src/run-send.d.ts +51 -0
  110. package/dist/agent-runtime/src/run-send.js +54 -0
  111. package/dist/agent-runtime/src/run-send.js.map +1 -0
  112. package/dist/agent-runtime/src/running-tool-placeholder.cjs +6 -0
  113. package/dist/agent-runtime/src/running-tool-placeholder.cjs.map +1 -1
  114. package/dist/agent-runtime/src/running-tool-placeholder.js +6 -0
  115. package/dist/agent-runtime/src/running-tool-placeholder.js.map +1 -1
  116. package/dist/agent-runtime/src/runtime.d.ts +9 -5
  117. package/dist/agent-runtime/src/sealed-idb.cjs +64 -0
  118. package/dist/agent-runtime/src/sealed-idb.cjs.map +1 -1
  119. package/dist/agent-runtime/src/sealed-idb.d.ts +16 -0
  120. package/dist/agent-runtime/src/sealed-idb.js +64 -0
  121. package/dist/agent-runtime/src/sealed-idb.js.map +1 -1
  122. package/dist/agent-runtime/src/send-recovery.cjs +90 -118
  123. package/dist/agent-runtime/src/send-recovery.cjs.map +1 -1
  124. package/dist/agent-runtime/src/send-recovery.d.ts +25 -29
  125. package/dist/agent-runtime/src/send-recovery.js +90 -118
  126. package/dist/agent-runtime/src/send-recovery.js.map +1 -1
  127. package/dist/agent-runtime/src/statewire-diagnostics.d.ts +4 -1
  128. package/dist/agent-runtime/src/statewire-held-sends.cjs +191 -0
  129. package/dist/agent-runtime/src/statewire-held-sends.cjs.map +1 -0
  130. package/dist/agent-runtime/src/statewire-held-sends.d.ts +119 -0
  131. package/dist/agent-runtime/src/statewire-held-sends.js +191 -0
  132. package/dist/agent-runtime/src/statewire-held-sends.js.map +1 -0
  133. package/dist/agent-runtime/src/statewire-state.cjs +4 -0
  134. package/dist/agent-runtime/src/statewire-state.cjs.map +1 -1
  135. package/dist/agent-runtime/src/statewire-state.js +4 -0
  136. package/dist/agent-runtime/src/statewire-state.js.map +1 -1
  137. package/dist/agent-runtime/src/statewire-transport.cjs +8 -2
  138. package/dist/agent-runtime/src/statewire-transport.cjs.map +1 -1
  139. package/dist/agent-runtime/src/statewire-transport.d.ts +14 -5
  140. package/dist/agent-runtime/src/statewire-transport.js +8 -2
  141. package/dist/agent-runtime/src/statewire-transport.js.map +1 -1
  142. package/dist/agent-runtime/src/subagent-transcripts.cjs +1 -23
  143. package/dist/agent-runtime/src/subagent-transcripts.cjs.map +1 -1
  144. package/dist/agent-runtime/src/subagent-transcripts.js +3 -25
  145. package/dist/agent-runtime/src/subagent-transcripts.js.map +1 -1
  146. package/dist/agent-runtime/src/subagents.cjs +22 -29
  147. package/dist/agent-runtime/src/subagents.cjs.map +1 -1
  148. package/dist/agent-runtime/src/subagents.js +23 -30
  149. package/dist/agent-runtime/src/subagents.js.map +1 -1
  150. package/dist/agent-runtime/src/thread-extras.cjs +27 -19
  151. package/dist/agent-runtime/src/thread-extras.cjs.map +1 -1
  152. package/dist/agent-runtime/src/thread-extras.d.ts +19 -6
  153. package/dist/agent-runtime/src/thread-extras.js +27 -19
  154. package/dist/agent-runtime/src/thread-extras.js.map +1 -1
  155. package/dist/agent-runtime/src/thread-handoff-flow-machine.d.ts +8 -8
  156. package/dist/agent-runtime/src/tool-metadata.cjs +12 -0
  157. package/dist/agent-runtime/src/tool-metadata.cjs.map +1 -1
  158. package/dist/agent-runtime/src/tool-metadata.js +12 -0
  159. package/dist/agent-runtime/src/tool-metadata.js.map +1 -1
  160. package/dist/agent-runtime/src/tool-names.cjs +21 -0
  161. package/dist/agent-runtime/src/tool-names.cjs.map +1 -1
  162. package/dist/agent-runtime/src/tool-names.d.ts +8 -0
  163. package/dist/agent-runtime/src/tool-names.js +21 -0
  164. package/dist/agent-runtime/src/tool-names.js.map +1 -1
  165. package/dist/agent-runtime/src/typed-interrupt-kinds.cjs +247 -0
  166. package/dist/agent-runtime/src/typed-interrupt-kinds.cjs.map +1 -0
  167. package/dist/agent-runtime/src/typed-interrupt-kinds.d.ts +173 -0
  168. package/dist/agent-runtime/src/typed-interrupt-kinds.js +247 -0
  169. package/dist/agent-runtime/src/typed-interrupt-kinds.js.map +1 -0
  170. package/dist/agent-runtime/src/typed-interrupts.cjs +48 -0
  171. package/dist/agent-runtime/src/typed-interrupts.cjs.map +1 -0
  172. package/dist/agent-runtime/src/typed-interrupts.d.ts +75 -0
  173. package/dist/agent-runtime/src/typed-interrupts.js +48 -0
  174. package/dist/agent-runtime/src/typed-interrupts.js.map +1 -0
  175. package/dist/agent-runtime/src/types.d.ts +1 -1
  176. package/dist/agent-runtime/src/use-conversation-list.cjs +1 -0
  177. package/dist/agent-runtime/src/use-conversation-list.cjs.map +1 -1
  178. package/dist/agent-runtime/src/use-conversation-list.d.ts +7 -0
  179. package/dist/agent-runtime/src/use-conversation-list.js +1 -0
  180. package/dist/agent-runtime/src/use-conversation-list.js.map +1 -1
  181. package/dist/agent-runtime/src/use-deep-agent-chat-outbox.cjs +46 -29
  182. package/dist/agent-runtime/src/use-deep-agent-chat-outbox.cjs.map +1 -1
  183. package/dist/agent-runtime/src/use-deep-agent-chat-outbox.d.ts +14 -22
  184. package/dist/agent-runtime/src/use-deep-agent-chat-outbox.js +46 -29
  185. package/dist/agent-runtime/src/use-deep-agent-chat-outbox.js.map +1 -1
  186. package/dist/agent-runtime/src/use-deep-agent-runtime.cjs +78 -14
  187. package/dist/agent-runtime/src/use-deep-agent-runtime.cjs.map +1 -1
  188. package/dist/agent-runtime/src/use-deep-agent-runtime.d.ts +34 -7
  189. package/dist/agent-runtime/src/use-deep-agent-runtime.js +79 -15
  190. package/dist/agent-runtime/src/use-deep-agent-runtime.js.map +1 -1
  191. package/dist/agent-runtime/src/use-deep-agent-thread.cjs +16 -1
  192. package/dist/agent-runtime/src/use-deep-agent-thread.cjs.map +1 -1
  193. package/dist/agent-runtime/src/use-deep-agent-thread.d.ts +7 -2
  194. package/dist/agent-runtime/src/use-deep-agent-thread.js +16 -1
  195. package/dist/agent-runtime/src/use-deep-agent-thread.js.map +1 -1
  196. package/dist/agent-runtime/src/use-deep-agent-voice.cjs +30 -4
  197. package/dist/agent-runtime/src/use-deep-agent-voice.cjs.map +1 -1
  198. package/dist/agent-runtime/src/use-deep-agent-voice.d.ts +22 -4
  199. package/dist/agent-runtime/src/use-deep-agent-voice.js +30 -4
  200. package/dist/agent-runtime/src/use-deep-agent-voice.js.map +1 -1
  201. package/dist/agent-runtime/src/withdrawn-turns.d.ts +5 -4
  202. package/dist/agent-runtime/src/word-device-fit.d.ts +174 -0
  203. package/dist/agent-runtime/src/work-in.d.ts +127 -0
  204. package/dist/assets/AthenaAssetEmbed.cjs.map +1 -1
  205. package/dist/assets/AthenaAssetEmbed.d.ts +6 -1
  206. package/dist/assets/AthenaAssetEmbed.js.map +1 -1
  207. package/dist/assets/asset-panel-store.cjs +13 -5
  208. package/dist/assets/asset-panel-store.cjs.map +1 -1
  209. package/dist/assets/asset-panel-store.d.ts +33 -2
  210. package/dist/assets/asset-panel-store.js +13 -5
  211. package/dist/assets/asset-panel-store.js.map +1 -1
  212. package/dist/auth/AthenaCredentialSourceContext.cjs +11 -0
  213. package/dist/auth/AthenaCredentialSourceContext.cjs.map +1 -1
  214. package/dist/auth/AthenaCredentialSourceContext.d.ts +6 -0
  215. package/dist/auth/AthenaCredentialSourceContext.js +11 -0
  216. package/dist/auth/AthenaCredentialSourceContext.js.map +1 -1
  217. package/dist/auth/account-identity.cjs +13 -2
  218. package/dist/auth/account-identity.cjs.map +1 -1
  219. package/dist/auth/account-identity.d.ts +9 -0
  220. package/dist/auth/account-identity.js +13 -2
  221. package/dist/auth/account-identity.js.map +1 -1
  222. package/dist/auth/credential-source.cjs +20 -4
  223. package/dist/auth/credential-source.cjs.map +1 -1
  224. package/dist/auth/credential-source.d.ts +9 -0
  225. package/dist/auth/credential-source.js +20 -4
  226. package/dist/auth/credential-source.js.map +1 -1
  227. package/dist/catalog/chat-pickers.cjs +31 -0
  228. package/dist/catalog/chat-pickers.cjs.map +1 -1
  229. package/dist/catalog/chat-pickers.d.ts +17 -0
  230. package/dist/catalog/chat-pickers.js +33 -2
  231. package/dist/catalog/chat-pickers.js.map +1 -1
  232. package/dist/catalog/runtime-catalog.cjs +63 -3
  233. package/dist/catalog/runtime-catalog.cjs.map +1 -1
  234. package/dist/catalog/runtime-catalog.d.ts +63 -3
  235. package/dist/catalog/runtime-catalog.js +64 -4
  236. package/dist/catalog/runtime-catalog.js.map +1 -1
  237. package/dist/chat/AthenaChat.cjs +337 -99
  238. package/dist/chat/AthenaChat.cjs.map +1 -1
  239. package/dist/chat/AthenaChat.d.ts +80 -4
  240. package/dist/chat/AthenaChat.js +337 -99
  241. package/dist/chat/AthenaChat.js.map +1 -1
  242. package/dist/chat/StatewireApprovalCard.cjs +35 -5
  243. package/dist/chat/StatewireApprovalCard.cjs.map +1 -1
  244. package/dist/chat/StatewireApprovalCard.d.ts +55 -2
  245. package/dist/chat/StatewireApprovalCard.js +37 -7
  246. package/dist/chat/StatewireApprovalCard.js.map +1 -1
  247. package/dist/chat/StatewireQueuedMessages.cjs +17 -2
  248. package/dist/chat/StatewireQueuedMessages.cjs.map +1 -1
  249. package/dist/chat/StatewireQueuedMessages.d.ts +8 -45
  250. package/dist/chat/StatewireQueuedMessages.js +18 -3
  251. package/dist/chat/StatewireQueuedMessages.js.map +1 -1
  252. package/dist/chat/chat-agent-mentions.cjs +70 -0
  253. package/dist/chat/chat-agent-mentions.cjs.map +1 -0
  254. package/dist/chat/chat-agent-mentions.d.ts +13 -0
  255. package/dist/chat/chat-agent-mentions.js +70 -0
  256. package/dist/chat/chat-agent-mentions.js.map +1 -0
  257. package/dist/chat/composer-actions.cjs +12 -0
  258. package/dist/chat/composer-actions.cjs.map +1 -0
  259. package/dist/chat/composer-actions.d.ts +22 -0
  260. package/dist/chat/composer-actions.js +12 -0
  261. package/dist/chat/composer-actions.js.map +1 -0
  262. package/dist/chat/follow-up-suggestions.cjs +185 -0
  263. package/dist/chat/follow-up-suggestions.cjs.map +1 -0
  264. package/dist/chat/follow-up-suggestions.d.ts +64 -0
  265. package/dist/chat/follow-up-suggestions.js +185 -0
  266. package/dist/chat/follow-up-suggestions.js.map +1 -0
  267. package/dist/chat/super-grouping/ToolTimeline.cjs +4 -3
  268. package/dist/chat/super-grouping/ToolTimeline.cjs.map +1 -1
  269. package/dist/chat/super-grouping/ToolTimeline.d.ts +7 -3
  270. package/dist/chat/super-grouping/ToolTimeline.js +4 -3
  271. package/dist/chat/super-grouping/ToolTimeline.js.map +1 -1
  272. package/dist/chat/turn-changes.cjs +284 -0
  273. package/dist/chat/turn-changes.cjs.map +1 -0
  274. package/dist/chat/turn-changes.d.ts +130 -0
  275. package/dist/chat/turn-changes.js +284 -0
  276. package/dist/chat/turn-changes.js.map +1 -0
  277. package/dist/chat/typed-interrupts/StatewireTypedInterruptCard.cjs +31 -0
  278. package/dist/chat/typed-interrupts/StatewireTypedInterruptCard.cjs.map +1 -0
  279. package/dist/chat/typed-interrupts/StatewireTypedInterruptCard.d.ts +31 -0
  280. package/dist/chat/typed-interrupts/StatewireTypedInterruptCard.js +31 -0
  281. package/dist/chat/typed-interrupts/StatewireTypedInterruptCard.js.map +1 -0
  282. package/dist/chat/typed-interrupts/approval-cards.cjs +250 -0
  283. package/dist/chat/typed-interrupts/approval-cards.cjs.map +1 -0
  284. package/dist/chat/typed-interrupts/approval-cards.d.ts +22 -0
  285. package/dist/chat/typed-interrupts/approval-cards.js +250 -0
  286. package/dist/chat/typed-interrupts/approval-cards.js.map +1 -0
  287. package/dist/chat/typed-interrupts/form-cards.cjs +289 -0
  288. package/dist/chat/typed-interrupts/form-cards.cjs.map +1 -0
  289. package/dist/chat/typed-interrupts/form-cards.d.ts +6 -0
  290. package/dist/chat/typed-interrupts/form-cards.js +289 -0
  291. package/dist/chat/typed-interrupts/form-cards.js.map +1 -0
  292. package/dist/chat/typed-interrupts/interrupt-card-shell.cjs +182 -0
  293. package/dist/chat/typed-interrupts/interrupt-card-shell.cjs.map +1 -0
  294. package/dist/chat/typed-interrupts/interrupt-card-shell.d.ts +47 -0
  295. package/dist/chat/typed-interrupts/interrupt-card-shell.js +182 -0
  296. package/dist/chat/typed-interrupts/interrupt-card-shell.js.map +1 -0
  297. package/dist/chat/typed-interrupts/json-schema-form.cjs +388 -0
  298. package/dist/chat/typed-interrupts/json-schema-form.cjs.map +1 -0
  299. package/dist/chat/typed-interrupts/json-schema-form.d.ts +33 -0
  300. package/dist/chat/typed-interrupts/json-schema-form.js +388 -0
  301. package/dist/chat/typed-interrupts/json-schema-form.js.map +1 -0
  302. package/dist/chat/typed-interrupts/questionnaire-card.cjs +449 -0
  303. package/dist/chat/typed-interrupts/questionnaire-card.cjs.map +1 -0
  304. package/dist/chat/typed-interrupts/questionnaire-card.d.ts +20 -0
  305. package/dist/chat/typed-interrupts/questionnaire-card.js +449 -0
  306. package/dist/chat/typed-interrupts/questionnaire-card.js.map +1 -0
  307. package/dist/chat/typed-interrupts/request-file-card.cjs +159 -0
  308. package/dist/chat/typed-interrupts/request-file-card.cjs.map +1 -0
  309. package/dist/chat/typed-interrupts/request-file-card.d.ts +2 -0
  310. package/dist/chat/typed-interrupts/request-file-card.js +159 -0
  311. package/dist/chat/typed-interrupts/request-file-card.js.map +1 -0
  312. package/dist/chat/typed-interrupts/toolkit-selection-card.cjs +189 -0
  313. package/dist/chat/typed-interrupts/toolkit-selection-card.cjs.map +1 -0
  314. package/dist/chat/typed-interrupts/toolkit-selection-card.d.ts +23 -0
  315. package/dist/chat/typed-interrupts/toolkit-selection-card.js +189 -0
  316. package/dist/chat/typed-interrupts/toolkit-selection-card.js.map +1 -0
  317. package/dist/chat/typed-interrupts/typed-interrupt-body.cjs +26 -0
  318. package/dist/chat/typed-interrupts/typed-interrupt-body.cjs.map +1 -0
  319. package/dist/chat/typed-interrupts/typed-interrupt-body.d.ts +3 -0
  320. package/dist/chat/typed-interrupts/typed-interrupt-body.js +26 -0
  321. package/dist/chat/typed-interrupts/typed-interrupt-body.js.map +1 -0
  322. package/dist/chat/typed-interrupts/typed-interrupt-graphql.cjs +105 -0
  323. package/dist/chat/typed-interrupts/typed-interrupt-graphql.cjs.map +1 -0
  324. package/dist/chat/typed-interrupts/typed-interrupt-graphql.d.ts +29 -0
  325. package/dist/chat/typed-interrupts/typed-interrupt-graphql.js +105 -0
  326. package/dist/chat/typed-interrupts/typed-interrupt-graphql.js.map +1 -0
  327. package/dist/chat/typed-interrupts/typed-interrupt-notice.cjs +70 -0
  328. package/dist/chat/typed-interrupts/typed-interrupt-notice.cjs.map +1 -0
  329. package/dist/chat/typed-interrupts/typed-interrupt-notice.d.ts +45 -0
  330. package/dist/chat/typed-interrupts/typed-interrupt-notice.js +70 -0
  331. package/dist/chat/typed-interrupts/typed-interrupt-notice.js.map +1 -0
  332. package/dist/chat/typed-interrupts/typed-interrupt-panel.cjs +76 -0
  333. package/dist/chat/typed-interrupts/typed-interrupt-panel.cjs.map +1 -0
  334. package/dist/chat/typed-interrupts/typed-interrupt-panel.d.ts +11 -0
  335. package/dist/chat/typed-interrupts/typed-interrupt-panel.js +76 -0
  336. package/dist/chat/typed-interrupts/typed-interrupt-panel.js.map +1 -0
  337. package/dist/chat/typed-interrupts/typed-interrupt-types.d.ts +46 -0
  338. package/dist/chat/typed-interrupts/use-interrupt-draft.cjs +106 -0
  339. package/dist/chat/typed-interrupts/use-interrupt-draft.cjs.map +1 -0
  340. package/dist/chat/typed-interrupts/use-interrupt-draft.d.ts +29 -0
  341. package/dist/chat/typed-interrupts/use-interrupt-draft.js +106 -0
  342. package/dist/chat/typed-interrupts/use-interrupt-draft.js.map +1 -0
  343. package/dist/chat/typed-interrupts/use-statewire-typed-interrupt.cjs +231 -0
  344. package/dist/chat/typed-interrupts/use-statewire-typed-interrupt.cjs.map +1 -0
  345. package/dist/chat/typed-interrupts/use-statewire-typed-interrupt.d.ts +66 -0
  346. package/dist/chat/typed-interrupts/use-statewire-typed-interrupt.js +231 -0
  347. package/dist/chat/typed-interrupts/use-statewire-typed-interrupt.js.map +1 -0
  348. package/dist/chat-ui/composer/composer-named-agents.cjs +13 -0
  349. package/dist/chat-ui/composer/composer-named-agents.cjs.map +1 -0
  350. package/dist/chat-ui/composer/composer-named-agents.d.ts +20 -0
  351. package/dist/chat-ui/composer/composer-named-agents.js +13 -0
  352. package/dist/chat-ui/composer/composer-named-agents.js.map +1 -0
  353. package/dist/chat-ui/composer/slash-command-menu.cjs +143 -0
  354. package/dist/chat-ui/composer/slash-command-menu.cjs.map +1 -0
  355. package/dist/chat-ui/composer/slash-command-menu.d.ts +19 -0
  356. package/dist/chat-ui/composer/slash-command-menu.js +143 -0
  357. package/dist/chat-ui/composer/slash-command-menu.js.map +1 -0
  358. package/dist/chat-ui/composer/slash-commands-extension.cjs +51 -0
  359. package/dist/chat-ui/composer/slash-commands-extension.cjs.map +1 -0
  360. package/dist/chat-ui/composer/slash-commands-extension.d.ts +39 -0
  361. package/dist/chat-ui/composer/slash-commands-extension.js +51 -0
  362. package/dist/chat-ui/composer/slash-commands-extension.js.map +1 -0
  363. package/dist/chat-ui/composer/slash-commands.cjs +74 -0
  364. package/dist/chat-ui/composer/slash-commands.cjs.map +1 -0
  365. package/dist/chat-ui/composer/slash-commands.d.ts +82 -0
  366. package/dist/chat-ui/composer/slash-commands.js +74 -0
  367. package/dist/chat-ui/composer/slash-commands.js.map +1 -0
  368. package/dist/chat-ui/composer/tiptap-composer.cjs +135 -9
  369. package/dist/chat-ui/composer/tiptap-composer.cjs.map +1 -1
  370. package/dist/chat-ui/composer/tiptap-composer.d.ts +61 -2
  371. package/dist/chat-ui/composer/tiptap-composer.js +135 -9
  372. package/dist/chat-ui/composer/tiptap-composer.js.map +1 -1
  373. package/dist/chat-ui/index.cjs +3 -0
  374. package/dist/chat-ui/index.cjs.map +1 -1
  375. package/dist/chat-ui/index.d.ts +3 -2
  376. package/dist/chat-ui/index.js +3 -0
  377. package/dist/chat-ui/index.js.map +1 -1
  378. package/dist/chat-ui/mentions/mention-chip.cjs +1 -1
  379. package/dist/chat-ui/mentions/mention-chip.cjs.map +1 -1
  380. package/dist/chat-ui/mentions/mention-chip.js +2 -2
  381. package/dist/chat-ui/mentions/mention-chip.js.map +1 -1
  382. package/dist/chat-ui/mentions/mention-extension.cjs +8 -1
  383. package/dist/chat-ui/mentions/mention-extension.cjs.map +1 -1
  384. package/dist/chat-ui/mentions/mention-extension.js +8 -1
  385. package/dist/chat-ui/mentions/mention-extension.js.map +1 -1
  386. package/dist/chat-ui/mentions/suggestions/components/get-scope-name.cjs +1 -0
  387. package/dist/chat-ui/mentions/suggestions/components/get-scope-name.cjs.map +1 -1
  388. package/dist/chat-ui/mentions/suggestions/components/get-scope-name.js +1 -0
  389. package/dist/chat-ui/mentions/suggestions/components/get-scope-name.js.map +1 -1
  390. package/dist/chat-ui/mentions/suggestions/components/mention-icon.cjs +2 -0
  391. package/dist/chat-ui/mentions/suggestions/components/mention-icon.cjs.map +1 -1
  392. package/dist/chat-ui/mentions/suggestions/components/mention-icon.js +3 -1
  393. package/dist/chat-ui/mentions/suggestions/components/mention-icon.js.map +1 -1
  394. package/dist/chat-ui/mentions/suggestions/components/menu-item.cjs +1 -1
  395. package/dist/chat-ui/mentions/suggestions/components/menu-item.cjs.map +1 -1
  396. package/dist/chat-ui/mentions/suggestions/components/menu-item.js +1 -1
  397. package/dist/chat-ui/mentions/suggestions/components/menu-item.js.map +1 -1
  398. package/dist/chat-ui/mentions/suggestions/data/api-client.cjs +36 -0
  399. package/dist/chat-ui/mentions/suggestions/data/api-client.cjs.map +1 -1
  400. package/dist/chat-ui/mentions/suggestions/data/api-client.d.ts +42 -0
  401. package/dist/chat-ui/mentions/suggestions/data/api-client.js +36 -0
  402. package/dist/chat-ui/mentions/suggestions/data/api-client.js.map +1 -1
  403. package/dist/chat-ui/mentions/suggestions/data/sources/index.cjs +235 -19
  404. package/dist/chat-ui/mentions/suggestions/data/sources/index.cjs.map +1 -1
  405. package/dist/chat-ui/mentions/suggestions/data/sources/index.d.ts +88 -10
  406. package/dist/chat-ui/mentions/suggestions/data/sources/index.js +236 -20
  407. package/dist/chat-ui/mentions/suggestions/data/sources/index.js.map +1 -1
  408. package/dist/chat-ui/mentions/suggestions/data/types.cjs.map +1 -1
  409. package/dist/chat-ui/mentions/suggestions/data/types.d.ts +27 -1
  410. package/dist/chat-ui/mentions/suggestions/data/types.js.map +1 -1
  411. package/dist/chat-ui/mentions/suggestions/data/use-mention-suggestions.cjs +56 -5
  412. package/dist/chat-ui/mentions/suggestions/data/use-mention-suggestions.cjs.map +1 -1
  413. package/dist/chat-ui/mentions/suggestions/data/use-mention-suggestions.d.ts +26 -6
  414. package/dist/chat-ui/mentions/suggestions/data/use-mention-suggestions.js +57 -6
  415. package/dist/chat-ui/mentions/suggestions/data/use-mention-suggestions.js.map +1 -1
  416. package/dist/chat-ui/mentions/suggestions/mention-suggestions.extension.cjs +34 -17
  417. package/dist/chat-ui/mentions/suggestions/mention-suggestions.extension.cjs.map +1 -1
  418. package/dist/chat-ui/mentions/suggestions/mention-suggestions.extension.d.ts +19 -1
  419. package/dist/chat-ui/mentions/suggestions/mention-suggestions.extension.js +35 -18
  420. package/dist/chat-ui/mentions/suggestions/mention-suggestions.extension.js.map +1 -1
  421. package/dist/chat-ui/statewire.d.ts +1 -1
  422. package/dist/chat-ui/thread/statewire-history-edge.cjs +15 -0
  423. package/dist/chat-ui/thread/statewire-history-edge.cjs.map +1 -1
  424. package/dist/chat-ui/thread/statewire-history-edge.d.ts +4 -1
  425. package/dist/chat-ui/thread/statewire-history-edge.js +15 -0
  426. package/dist/chat-ui/thread/statewire-history-edge.js.map +1 -1
  427. package/dist/collab/client.cjs +17 -5
  428. package/dist/collab/client.cjs.map +1 -1
  429. package/dist/collab/client.d.ts +22 -7
  430. package/dist/collab/client.js +17 -5
  431. package/dist/collab/client.js.map +1 -1
  432. package/dist/composer/ComposerAttachedReferences.cjs +119 -0
  433. package/dist/composer/ComposerAttachedReferences.cjs.map +1 -0
  434. package/dist/composer/ComposerAttachedReferences.d.ts +26 -0
  435. package/dist/composer/ComposerAttachedReferences.js +119 -0
  436. package/dist/composer/ComposerAttachedReferences.js.map +1 -0
  437. package/dist/composer/ComposerNamedAgents.cjs +63 -0
  438. package/dist/composer/ComposerNamedAgents.cjs.map +1 -0
  439. package/dist/composer/ComposerNamedAgents.d.ts +16 -0
  440. package/dist/composer/ComposerNamedAgents.js +63 -0
  441. package/dist/composer/ComposerNamedAgents.js.map +1 -0
  442. package/dist/composer/attached-references.cjs +159 -0
  443. package/dist/composer/attached-references.cjs.map +1 -0
  444. package/dist/composer/attached-references.d.ts +86 -0
  445. package/dist/composer/attached-references.js +159 -0
  446. package/dist/composer/attached-references.js.map +1 -0
  447. package/dist/composer/build-composed-message.cjs +14 -7
  448. package/dist/composer/build-composed-message.cjs.map +1 -1
  449. package/dist/composer/build-composed-message.d.ts +6 -1
  450. package/dist/composer/build-composed-message.js +14 -7
  451. package/dist/composer/build-composed-message.js.map +1 -1
  452. package/dist/composer/composer-handoff.cjs +6 -2
  453. package/dist/composer/composer-handoff.cjs.map +1 -1
  454. package/dist/composer/composer-handoff.d.ts +7 -1
  455. package/dist/composer/composer-handoff.js +6 -2
  456. package/dist/composer/composer-handoff.js.map +1 -1
  457. package/dist/composer/folder-upload.cjs +149 -0
  458. package/dist/composer/folder-upload.cjs.map +1 -0
  459. package/dist/composer/folder-upload.d.ts +79 -0
  460. package/dist/composer/folder-upload.js +149 -0
  461. package/dist/composer/folder-upload.js.map +1 -0
  462. package/dist/composer/index.d.ts +1 -1
  463. package/dist/composer/useAttachToChat.cjs +35 -0
  464. package/dist/composer/useAttachToChat.cjs.map +1 -0
  465. package/dist/composer/useAttachToChat.d.ts +54 -0
  466. package/dist/composer/useAttachToChat.js +35 -0
  467. package/dist/composer/useAttachToChat.js.map +1 -0
  468. package/dist/composer/useAttachedReferencesComposerProps.cjs +19 -0
  469. package/dist/composer/useAttachedReferencesComposerProps.cjs.map +1 -0
  470. package/dist/composer/useAttachedReferencesComposerProps.d.ts +12 -0
  471. package/dist/composer/useAttachedReferencesComposerProps.js +19 -0
  472. package/dist/composer/useAttachedReferencesComposerProps.js.map +1 -0
  473. package/dist/composer/useFileUpload.cjs +95 -7
  474. package/dist/composer/useFileUpload.cjs.map +1 -1
  475. package/dist/composer/useFileUpload.d.ts +21 -2
  476. package/dist/composer/useFileUpload.js +95 -7
  477. package/dist/composer/useFileUpload.js.map +1 -1
  478. package/dist/data/athena-api-error.cjs +125 -0
  479. package/dist/data/athena-api-error.cjs.map +1 -0
  480. package/dist/data/athena-api-error.d.ts +96 -0
  481. package/dist/data/athena-api-error.js +125 -0
  482. package/dist/data/athena-api-error.js.map +1 -0
  483. package/dist/data/athena-data-client.cjs +106 -0
  484. package/dist/data/athena-data-client.cjs.map +1 -0
  485. package/dist/data/athena-data-client.d.ts +74 -0
  486. package/dist/data/athena-data-client.js +106 -0
  487. package/dist/data/athena-data-client.js.map +1 -0
  488. package/dist/data/athena-member.cjs +93 -0
  489. package/dist/data/athena-member.cjs.map +1 -0
  490. package/dist/data/athena-member.d.ts +125 -0
  491. package/dist/data/athena-member.js +93 -0
  492. package/dist/data/athena-member.js.map +1 -0
  493. package/dist/data/athena-request.cjs +458 -0
  494. package/dist/data/athena-request.cjs.map +1 -0
  495. package/dist/data/athena-request.d.ts +120 -0
  496. package/dist/data/athena-request.js +458 -0
  497. package/dist/data/athena-request.js.map +1 -0
  498. package/dist/data/use-athena-fetch.cjs +14 -0
  499. package/dist/data/use-athena-fetch.cjs.map +1 -0
  500. package/dist/data/use-athena-fetch.d.ts +19 -0
  501. package/dist/data/use-athena-fetch.js +14 -0
  502. package/dist/data/use-athena-fetch.js.map +1 -0
  503. package/dist/data/use-athena-graphql.cjs +66 -0
  504. package/dist/data/use-athena-graphql.cjs.map +1 -0
  505. package/dist/data/use-athena-graphql.d.ts +56 -0
  506. package/dist/data/use-athena-graphql.js +66 -0
  507. package/dist/data/use-athena-graphql.js.map +1 -0
  508. package/dist/data/use-athena-rest.cjs +33 -0
  509. package/dist/data/use-athena-rest.cjs.map +1 -0
  510. package/dist/data/use-athena-rest.d.ts +21 -0
  511. package/dist/data/use-athena-rest.js +33 -0
  512. package/dist/data/use-athena-rest.js.map +1 -0
  513. package/dist/data/use-semantic-query.cjs +44 -0
  514. package/dist/data/use-semantic-query.cjs.map +1 -0
  515. package/dist/data/use-semantic-query.d.ts +92 -0
  516. package/dist/data/use-semantic-query.js +44 -0
  517. package/dist/data/use-semantic-query.js.map +1 -0
  518. package/dist/diagnostics/athena-diagnostics.cjs.map +1 -1
  519. package/dist/diagnostics/athena-diagnostics.d.ts +5 -1
  520. package/dist/diagnostics/athena-diagnostics.js.map +1 -1
  521. package/dist/diagnostics/errors.cjs +7 -0
  522. package/dist/diagnostics/errors.cjs.map +1 -1
  523. package/dist/diagnostics/errors.d.ts +7 -0
  524. package/dist/diagnostics/errors.js +7 -0
  525. package/dist/diagnostics/errors.js.map +1 -1
  526. package/dist/index.cjs +155 -11
  527. package/dist/index.cjs.map +1 -1
  528. package/dist/index.d.ts +72 -13
  529. package/dist/index.js +148 -4
  530. package/dist/index.js.map +1 -1
  531. package/dist/keryx-http/src/initial-sync.cjs +64 -16
  532. package/dist/keryx-http/src/initial-sync.cjs.map +1 -1
  533. package/dist/keryx-http/src/initial-sync.d.ts +31 -1
  534. package/dist/keryx-http/src/initial-sync.js +64 -16
  535. package/dist/keryx-http/src/initial-sync.js.map +1 -1
  536. package/dist/keryx-http/src/own-awareness.cjs +20 -0
  537. package/dist/keryx-http/src/own-awareness.cjs.map +1 -0
  538. package/dist/keryx-http/src/own-awareness.d.ts +50 -0
  539. package/dist/keryx-http/src/own-awareness.js +20 -0
  540. package/dist/keryx-http/src/own-awareness.js.map +1 -0
  541. package/dist/keryx-http/src/update-attributions.cjs +26 -1
  542. package/dist/keryx-http/src/update-attributions.cjs.map +1 -1
  543. package/dist/keryx-http/src/update-attributions.d.ts +10 -1
  544. package/dist/keryx-http/src/update-attributions.js +26 -1
  545. package/dist/keryx-http/src/update-attributions.js.map +1 -1
  546. package/dist/offline/chat-outbox.cjs +262 -26
  547. package/dist/offline/chat-outbox.cjs.map +1 -1
  548. package/dist/offline/chat-outbox.d.ts +90 -12
  549. package/dist/offline/chat-outbox.js +263 -27
  550. package/dist/offline/chat-outbox.js.map +1 -1
  551. package/dist/provider/AthenaProvider.cjs +63 -19
  552. package/dist/provider/AthenaProvider.cjs.map +1 -1
  553. package/dist/provider/AthenaProvider.d.ts +24 -8
  554. package/dist/provider/AthenaProvider.js +66 -22
  555. package/dist/provider/AthenaProvider.js.map +1 -1
  556. package/dist/react/package.json.cjs +1 -1
  557. package/dist/react/package.json.js +1 -1
  558. package/dist/references/src/anchors/types.cjs +5 -0
  559. package/dist/references/src/anchors/types.cjs.map +1 -1
  560. package/dist/references/src/anchors/types.js +5 -0
  561. package/dist/references/src/anchors/types.js.map +1 -1
  562. package/dist/references/src/attachable.cjs +149 -0
  563. package/dist/references/src/attachable.cjs.map +1 -0
  564. package/dist/references/src/attachable.d.ts +87 -0
  565. package/dist/references/src/attachable.js +149 -0
  566. package/dist/references/src/attachable.js.map +1 -0
  567. package/dist/runtime/StatewirePlanModeLaneSync.cjs +93 -0
  568. package/dist/runtime/StatewirePlanModeLaneSync.cjs.map +1 -0
  569. package/dist/runtime/StatewirePlanModeLaneSync.d.ts +34 -0
  570. package/dist/runtime/StatewirePlanModeLaneSync.js +93 -0
  571. package/dist/runtime/StatewirePlanModeLaneSync.js.map +1 -0
  572. package/dist/runtime/StatewireThreadConfigLaneSync.cjs +2 -0
  573. package/dist/runtime/StatewireThreadConfigLaneSync.cjs.map +1 -1
  574. package/dist/runtime/StatewireThreadConfigLaneSync.d.ts +4 -0
  575. package/dist/runtime/StatewireThreadConfigLaneSync.js +2 -0
  576. package/dist/runtime/StatewireThreadConfigLaneSync.js.map +1 -1
  577. package/dist/runtime/statewire-plan-mode.cjs +71 -0
  578. package/dist/runtime/statewire-plan-mode.cjs.map +1 -0
  579. package/dist/runtime/statewire-plan-mode.d.ts +88 -0
  580. package/dist/runtime/statewire-plan-mode.js +71 -0
  581. package/dist/runtime/statewire-plan-mode.js.map +1 -0
  582. package/dist/runtime/statewire-run-config.cjs +18 -1
  583. package/dist/runtime/statewire-run-config.cjs.map +1 -1
  584. package/dist/runtime/statewire-run-config.d.ts +20 -0
  585. package/dist/runtime/statewire-run-config.js +18 -1
  586. package/dist/runtime/statewire-run-config.js.map +1 -1
  587. package/dist/runtime/statewire-session-key.cjs +11 -5
  588. package/dist/runtime/statewire-session-key.cjs.map +1 -1
  589. package/dist/runtime/statewire-session-key.d.ts +22 -10
  590. package/dist/runtime/statewire-session-key.js +11 -5
  591. package/dist/runtime/statewire-session-key.js.map +1 -1
  592. package/dist/runtime/useAthenaStatewireRuntime.cjs +65 -8
  593. package/dist/runtime/useAthenaStatewireRuntime.cjs.map +1 -1
  594. package/dist/runtime/useAthenaStatewireRuntime.d.ts +26 -10
  595. package/dist/runtime/useAthenaStatewireRuntime.js +67 -10
  596. package/dist/runtime/useAthenaStatewireRuntime.js.map +1 -1
  597. package/dist/search/useAthenaAssets.cjs +394 -0
  598. package/dist/search/useAthenaAssets.cjs.map +1 -0
  599. package/dist/search/useAthenaAssets.d.ts +186 -0
  600. package/dist/search/useAthenaAssets.js +394 -0
  601. package/dist/search/useAthenaAssets.js.map +1 -0
  602. package/dist/sheet-range/index.cjs +4 -0
  603. package/dist/sheet-range/index.cjs.map +1 -1
  604. package/dist/sheet-range/index.d.ts +4 -2
  605. package/dist/sheet-range/index.js +4 -0
  606. package/dist/sheet-range/index.js.map +1 -1
  607. package/dist/sheet-range/query-range.cjs +102 -0
  608. package/dist/sheet-range/query-range.cjs.map +1 -0
  609. package/dist/sheet-range/query-range.d.ts +46 -0
  610. package/dist/sheet-range/query-range.js +102 -0
  611. package/dist/sheet-range/query-range.js.map +1 -0
  612. package/dist/styles.css +1 -1
  613. package/dist/subagents/index.cjs +49 -0
  614. package/dist/subagents/index.cjs.map +1 -0
  615. package/dist/subagents/index.d.ts +16 -0
  616. package/dist/subagents/index.js +49 -0
  617. package/dist/subagents/index.js.map +1 -0
  618. package/dist/subagents/lane-follow.cjs +19 -0
  619. package/dist/subagents/lane-follow.cjs.map +1 -0
  620. package/dist/subagents/lane-follow.d.ts +9 -0
  621. package/dist/subagents/lane-follow.js +19 -0
  622. package/dist/subagents/lane-follow.js.map +1 -0
  623. package/dist/subagents/lane-model.cjs +178 -0
  624. package/dist/subagents/lane-model.cjs.map +1 -0
  625. package/dist/subagents/lane-model.d.ts +140 -0
  626. package/dist/subagents/lane-model.js +178 -0
  627. package/dist/subagents/lane-model.js.map +1 -0
  628. package/dist/subagents/lane-parts.cjs +517 -0
  629. package/dist/subagents/lane-parts.cjs.map +1 -0
  630. package/dist/subagents/lane-parts.d.ts +130 -0
  631. package/dist/subagents/lane-parts.js +517 -0
  632. package/dist/subagents/lane-parts.js.map +1 -0
  633. package/dist/subagents/subagent-lane-group.cjs +215 -0
  634. package/dist/subagents/subagent-lane-group.cjs.map +1 -0
  635. package/dist/subagents/subagent-lane-group.d.ts +67 -0
  636. package/dist/subagents/subagent-lane-group.js +215 -0
  637. package/dist/subagents/subagent-lane-group.js.map +1 -0
  638. package/dist/subagents/subagent-transcript-drawer.cjs +431 -0
  639. package/dist/subagents/subagent-transcript-drawer.cjs.map +1 -0
  640. package/dist/subagents/subagent-transcript-drawer.d.ts +78 -0
  641. package/dist/subagents/subagent-transcript-drawer.js +431 -0
  642. package/dist/subagents/subagent-transcript-drawer.js.map +1 -0
  643. package/dist/subagents/task-subagent-group.cjs +115 -0
  644. package/dist/subagents/task-subagent-group.cjs.map +1 -0
  645. package/dist/subagents/task-subagent-group.d.ts +36 -0
  646. package/dist/subagents/task-subagent-group.js +115 -0
  647. package/dist/subagents/task-subagent-group.js.map +1 -0
  648. package/dist/subagents/use-omitted-images-in-view.cjs +68 -0
  649. package/dist/subagents/use-omitted-images-in-view.cjs.map +1 -0
  650. package/dist/subagents/use-omitted-images-in-view.d.ts +21 -0
  651. package/dist/subagents/use-omitted-images-in-view.js +68 -0
  652. package/dist/subagents/use-omitted-images-in-view.js.map +1 -0
  653. package/dist/threads/Inbox.cjs +2 -2
  654. package/dist/threads/Inbox.cjs.map +1 -1
  655. package/dist/threads/SessionList.cjs +27 -24
  656. package/dist/threads/SessionList.cjs.map +1 -1
  657. package/dist/threads/SessionList.js +22 -19
  658. package/dist/threads/SessionList.js.map +1 -1
  659. package/dist/threads/SessionsPage.cjs +13 -7
  660. package/dist/threads/SessionsPage.cjs.map +1 -1
  661. package/dist/threads/SessionsPage.d.ts +10 -1
  662. package/dist/threads/SessionsPage.js +9 -3
  663. package/dist/threads/SessionsPage.js.map +1 -1
  664. package/dist/threads/live-session-rows.cjs +207 -0
  665. package/dist/threads/live-session-rows.cjs.map +1 -0
  666. package/dist/threads/live-session-rows.d.ts +175 -0
  667. package/dist/threads/live-session-rows.js +207 -0
  668. package/dist/threads/live-session-rows.js.map +1 -0
  669. package/dist/threads/session-list-model.cjs.map +1 -1
  670. package/dist/threads/session-list-model.d.ts +2 -1
  671. package/dist/threads/session-list-model.js.map +1 -1
  672. package/dist/threads/session-row-parts.cjs +3 -3
  673. package/dist/threads/session-row-parts.cjs.map +1 -1
  674. package/dist/threads/sessions-page-model.cjs +13 -5
  675. package/dist/threads/sessions-page-model.cjs.map +1 -1
  676. package/dist/threads/sessions-page-model.d.ts +7 -0
  677. package/dist/threads/sessions-page-model.js +11 -3
  678. package/dist/threads/sessions-page-model.js.map +1 -1
  679. package/dist/threads/sessions-page-storage.cjs +8 -8
  680. package/dist/threads/sessions-page-storage.cjs.map +1 -1
  681. package/dist/threads/sessions-page-storage.d.ts +5 -1
  682. package/dist/threads/sessions-page-storage.js +8 -8
  683. package/dist/threads/sessions-page-storage.js.map +1 -1
  684. package/dist/threads/statewire-thread-list.cjs +173 -20
  685. package/dist/threads/statewire-thread-list.cjs.map +1 -1
  686. package/dist/threads/statewire-thread-list.d.ts +44 -1
  687. package/dist/threads/statewire-thread-list.js +174 -21
  688. package/dist/threads/statewire-thread-list.js.map +1 -1
  689. package/dist/threads/use-athena-sessions.cjs +1 -0
  690. package/dist/threads/use-athena-sessions.cjs.map +1 -1
  691. package/dist/threads/use-athena-sessions.d.ts +7 -0
  692. package/dist/threads/use-athena-sessions.js +1 -0
  693. package/dist/threads/use-athena-sessions.js.map +1 -1
  694. package/dist/threads/use-athena-thread-agent.cjs +31 -0
  695. package/dist/threads/use-athena-thread-agent.cjs.map +1 -0
  696. package/dist/threads/use-athena-thread-agent.d.ts +38 -0
  697. package/dist/threads/use-athena-thread-agent.js +31 -0
  698. package/dist/threads/use-athena-thread-agent.js.map +1 -0
  699. package/dist/threads/use-athena-thread-plan-mode.cjs +18 -0
  700. package/dist/threads/use-athena-thread-plan-mode.cjs.map +1 -0
  701. package/dist/threads/use-athena-thread-plan-mode.d.ts +18 -0
  702. package/dist/threads/use-athena-thread-plan-mode.js +18 -0
  703. package/dist/threads/use-athena-thread-plan-mode.js.map +1 -0
  704. package/dist/threads/use-rest-conversation-history.d.ts +1 -0
  705. package/dist/tools/agent-creations.cjs +97 -0
  706. package/dist/tools/agent-creations.cjs.map +1 -0
  707. package/dist/tools/agent-creations.d.ts +38 -0
  708. package/dist/tools/agent-creations.js +97 -0
  709. package/dist/tools/agent-creations.js.map +1 -0
  710. package/dist/tools/agent-highlights.cjs +100 -0
  711. package/dist/tools/agent-highlights.cjs.map +1 -0
  712. package/dist/tools/agent-highlights.d.ts +57 -0
  713. package/dist/tools/agent-highlights.js +100 -0
  714. package/dist/tools/agent-highlights.js.map +1 -0
  715. package/dist/tools/append-document-tool-ui.cjs +1 -0
  716. package/dist/tools/append-document-tool-ui.cjs.map +1 -1
  717. package/dist/tools/append-document-tool-ui.d.ts +7 -0
  718. package/dist/tools/append-document-tool-ui.js +2 -1
  719. package/dist/tools/append-document-tool-ui.js.map +1 -1
  720. package/dist/tools/auto-open-tools.cjs +144 -71
  721. package/dist/tools/auto-open-tools.cjs.map +1 -1
  722. package/dist/tools/auto-open-tools.d.ts +131 -1
  723. package/dist/tools/auto-open-tools.js +145 -72
  724. package/dist/tools/auto-open-tools.js.map +1 -1
  725. package/dist/tools/browser-tool-uis.cjs +594 -0
  726. package/dist/tools/browser-tool-uis.cjs.map +1 -0
  727. package/dist/tools/browser-tool-uis.d.ts +8 -0
  728. package/dist/tools/browser-tool-uis.js +594 -0
  729. package/dist/tools/browser-tool-uis.js.map +1 -0
  730. package/dist/tools/computer-asset-tool-uis.cjs +313 -0
  731. package/dist/tools/computer-asset-tool-uis.cjs.map +1 -0
  732. package/dist/tools/computer-asset-tool-uis.d.ts +5 -0
  733. package/dist/tools/computer-asset-tool-uis.js +313 -0
  734. package/dist/tools/computer-asset-tool-uis.js.map +1 -0
  735. package/dist/tools/document-edit-tool-uis.cjs +218 -0
  736. package/dist/tools/document-edit-tool-uis.cjs.map +1 -0
  737. package/dist/tools/document-edit-tool-uis.d.ts +40 -0
  738. package/dist/tools/document-edit-tool-uis.js +218 -0
  739. package/dist/tools/document-edit-tool-uis.js.map +1 -0
  740. package/dist/tools/drive-tool-uis.cjs +425 -0
  741. package/dist/tools/drive-tool-uis.cjs.map +1 -0
  742. package/dist/tools/drive-tool-uis.d.ts +120 -0
  743. package/dist/tools/drive-tool-uis.js +425 -0
  744. package/dist/tools/drive-tool-uis.js.map +1 -0
  745. package/dist/tools/email-calendar-tool-uis.cjs +789 -0
  746. package/dist/tools/email-calendar-tool-uis.cjs.map +1 -0
  747. package/dist/tools/email-calendar-tool-uis.d.ts +129 -0
  748. package/dist/tools/email-calendar-tool-uis.js +789 -0
  749. package/dist/tools/email-calendar-tool-uis.js.map +1 -0
  750. package/dist/tools/ontology-tool-uis.cjs +83 -0
  751. package/dist/tools/ontology-tool-uis.cjs.map +1 -0
  752. package/dist/tools/ontology-tool-uis.d.ts +9 -0
  753. package/dist/tools/ontology-tool-uis.js +83 -0
  754. package/dist/tools/ontology-tool-uis.js.map +1 -0
  755. package/dist/tools/orchestration-tool-uis.cjs +586 -0
  756. package/dist/tools/orchestration-tool-uis.cjs.map +1 -0
  757. package/dist/tools/orchestration-tool-uis.d.ts +141 -0
  758. package/dist/tools/orchestration-tool-uis.js +586 -0
  759. package/dist/tools/orchestration-tool-uis.js.map +1 -0
  760. package/dist/tools/presentation-edit-tool-uis.cjs +516 -0
  761. package/dist/tools/presentation-edit-tool-uis.cjs.map +1 -0
  762. package/dist/tools/presentation-edit-tool-uis.d.ts +73 -0
  763. package/dist/tools/presentation-edit-tool-uis.js +516 -0
  764. package/dist/tools/presentation-edit-tool-uis.js.map +1 -0
  765. package/dist/tools/project-tool-uis.cjs +213 -0
  766. package/dist/tools/project-tool-uis.cjs.map +1 -0
  767. package/dist/tools/project-tool-uis.d.ts +14 -0
  768. package/dist/tools/project-tool-uis.js +213 -0
  769. package/dist/tools/project-tool-uis.js.map +1 -0
  770. package/dist/tools/sandbox-tool-uis.cjs +491 -0
  771. package/dist/tools/sandbox-tool-uis.cjs.map +1 -0
  772. package/dist/tools/sandbox-tool-uis.d.ts +116 -0
  773. package/dist/tools/sandbox-tool-uis.js +491 -0
  774. package/dist/tools/sandbox-tool-uis.js.map +1 -0
  775. package/dist/tools/sheet-query-tool-ui.cjs +138 -0
  776. package/dist/tools/sheet-query-tool-ui.cjs.map +1 -0
  777. package/dist/tools/sheet-query-tool-ui.d.ts +15 -0
  778. package/dist/tools/sheet-query-tool-ui.js +138 -0
  779. package/dist/tools/sheet-query-tool-ui.js.map +1 -0
  780. package/dist/tools/studio-screenshot-tool-uis.cjs +262 -0
  781. package/dist/tools/studio-screenshot-tool-uis.cjs.map +1 -0
  782. package/dist/tools/studio-screenshot-tool-uis.d.ts +52 -0
  783. package/dist/tools/studio-screenshot-tool-uis.js +262 -0
  784. package/dist/tools/studio-screenshot-tool-uis.js.map +1 -0
  785. package/dist/tools/subagent-task-tool-ui.cjs +24 -475
  786. package/dist/tools/subagent-task-tool-ui.cjs.map +1 -1
  787. package/dist/tools/subagent-task-tool-ui.d.ts +19 -103
  788. package/dist/tools/subagent-task-tool-ui.js +28 -479
  789. package/dist/tools/subagent-task-tool-ui.js.map +1 -1
  790. package/dist/tools/tool-summary.cjs +36 -0
  791. package/dist/tools/tool-summary.cjs.map +1 -1
  792. package/dist/tools/tool-summary.js +36 -0
  793. package/dist/tools/tool-summary.js.map +1 -1
  794. package/dist/tools/tool-uis.cjs +181 -53
  795. package/dist/tools/tool-uis.cjs.map +1 -1
  796. package/dist/tools/tool-uis.d.ts +40 -0
  797. package/dist/tools/tool-uis.js +183 -55
  798. package/dist/tools/tool-uis.js.map +1 -1
  799. package/dist/typed-interrupts/index.cjs +15 -0
  800. package/dist/typed-interrupts/index.cjs.map +1 -0
  801. package/dist/typed-interrupts/index.d.ts +20 -0
  802. package/dist/typed-interrupts/index.js +15 -0
  803. package/dist/typed-interrupts/index.js.map +1 -0
  804. package/dist/workbench/session-workbench-panes.cjs +6 -6
  805. package/dist/workbench/session-workbench-panes.cjs.map +1 -1
  806. package/package.json +28 -6
  807. package/dist/agent-runtime/src/chat-outbox-store.cjs +0 -510
  808. package/dist/agent-runtime/src/chat-outbox-store.cjs.map +0 -1
  809. package/dist/agent-runtime/src/chat-outbox-store.d.ts +0 -210
  810. package/dist/agent-runtime/src/chat-outbox-store.js +0 -510
  811. package/dist/agent-runtime/src/chat-outbox-store.js.map +0 -1
@@ -1 +1 @@
1
- {"version":3,"file":"session-row-parts.cjs","sources":["../../src/threads/session-row-parts.tsx"],"sourcesContent":["/**\n * Row pieces every SDK session list shares (`SessionList`, `SessionsPage`,\n * `Inbox`): the focus ring, the pull-request chip and its list, the\n * attention-toned status chip, and a labelled icon action that never selects\n * its row.\n */\nimport type { ConversationPullRequest } from '@athenaintel/agent-runtime';\nimport type { FC, MouseEvent, ReactNode } from 'react';\nimport { cn } from '../lib/utils';\nimport { Popover, PopoverContent, PopoverTrigger } from '../ui/popover';\nimport { PR_CHECKS_LABEL, PR_STATE_CLASS, PR_STATE_ICON } from './pull-request-display';\nimport {\n orderedPullRequests,\n type PullRequestChip as PullRequestChipModel,\n pullRequestChipState,\n} from './session-list-model';\nimport type { SessionStatusTone } from './sessions-page-model';\n\n/** The focus treatment every row control and action shares. */\nexport const FOCUS_RING_CLASS =\n 'outline-none focus-visible:ring-2 focus-visible:ring-ring/60 focus-visible:ring-offset-0';\n\nexport const stopPropagation = (event: MouseEvent) => event.stopPropagation();\n\nconst PR_CHIP_CLASS =\n 'inline-flex h-4 shrink-0 items-center gap-1 rounded-full border border-border/60 px-1.5 font-medium text-[11px] leading-none transition-colors hover:bg-muted';\n\n/**\n * One row of the pull-request list: the state icon, the title, and the\n * number, state and checks beneath it (the repository too when the list\n * spans several), as a link to GitHub in a new tab.\n */\nconst PullRequestListRow: FC<{ pullRequest: ConversationPullRequest; showRepo: boolean }> = ({\n pullRequest,\n showRepo,\n}) => {\n const state = pullRequestChipState(pullRequest);\n const Icon = PR_STATE_ICON[state];\n const meta = [\n showRepo ? `${pullRequest.repoFullName} #${pullRequest.number}` : `#${pullRequest.number}`,\n state,\n PR_CHECKS_LABEL[pullRequest.checksState],\n ]\n .filter(Boolean)\n .join(' · ');\n return (\n <li>\n <a\n href={pullRequest.url}\n target=\"_blank\"\n rel=\"noopener noreferrer\"\n data-pr-state={state}\n className={cn(\n 'flex items-start gap-2 rounded-sm px-2 py-1.5 text-xs transition-colors hover:bg-muted',\n FOCUS_RING_CLASS,\n )}\n >\n <Icon className={cn('mt-0.5 size-3.5 shrink-0', PR_STATE_CLASS[state])} aria-hidden />\n <span className=\"min-w-0 flex-1\">\n <span className=\"block truncate text-foreground\">\n {pullRequest.title || `#${pullRequest.number}`}\n </span>\n <span className=\"block truncate text-muted-foreground\">{meta}</span>\n </span>\n </a>\n </li>\n );\n};\n\n/**\n * The session's pull-request chip; a sibling of the row button (never nested\n * inside it) so the markup stays valid and a click on it never selects the\n * row. One pull request: a link to it. Several: a button that opens all of\n * them — in flight first, then the most recently updated — each a link to\n * GitHub.\n */\nexport const PullRequestChip: FC<{\n chip: PullRequestChipModel;\n pullRequests: readonly ConversationPullRequest[];\n}> = ({ chip, pullRequests }) => {\n const Icon = PR_STATE_ICON[chip.state];\n if (chip.count === 1) {\n return (\n <a\n href={chip.url}\n target=\"_blank\"\n rel=\"noopener noreferrer\"\n onClick={stopPropagation}\n title={chip.title}\n aria-label={`Pull request ${chip.label}, ${chip.state}`}\n data-pr-state={chip.state}\n data-pr-count={chip.count}\n className={cn(PR_CHIP_CLASS, FOCUS_RING_CLASS, PR_STATE_CLASS[chip.state])}\n >\n <Icon className=\"size-3\" aria-hidden />\n {chip.label}\n </a>\n );\n }\n const listLabel = `${chip.count} pull requests`;\n const ordered = orderedPullRequests(pullRequests);\n // One repository (the usual case) is named once in the header, so each\n // row's meta line has room for its state and checks.\n const repositories = new Set(ordered.map((pullRequest) => pullRequest.repoFullName));\n const sharedRepository = repositories.size === 1 ? (ordered[0]?.repoFullName ?? null) : null;\n return (\n <Popover>\n <PopoverTrigger asChild>\n <button\n type=\"button\"\n onClick={stopPropagation}\n aria-label={`${chip.label}: show all ${listLabel}`}\n data-pr-state={chip.state}\n data-pr-count={chip.count}\n className={cn(PR_CHIP_CLASS, FOCUS_RING_CLASS, PR_STATE_CLASS[chip.state])}\n >\n <Icon className=\"size-3\" aria-hidden />\n {chip.label}\n </button>\n </PopoverTrigger>\n <PopoverContent align=\"end\" className=\"w-80 p-0\" aria-label={listLabel} data-pr-list=\"\">\n <p className=\"truncate border-b border-border px-3 py-2 font-medium text-muted-foreground text-xs\">\n {sharedRepository ? `${listLabel} in ${sharedRepository}` : listLabel}\n </p>\n <ul className=\"max-h-72 overflow-y-auto p-1\">\n {ordered.map((pullRequest) => (\n <PullRequestListRow\n key={`${pullRequest.repoFullName}#${pullRequest.number}`}\n pullRequest={pullRequest}\n showRepo={sharedRepository === null}\n />\n ))}\n </ul>\n </PopoverContent>\n </Popover>\n );\n};\n\n/** One colour per attention tone: the chip's dot and its text. */\nexport const STATUS_TONE_CLASS: Record<SessionStatusTone, { dot: string; text: string }> = {\n needs_you: { dot: 'bg-orange-500', text: 'text-orange-700' },\n working: { dot: 'bg-blue-500 animate-pulse', text: 'text-blue-700' },\n ready: { dot: 'bg-green-500', text: 'text-green-700' },\n watching: { dot: 'bg-violet-400', text: 'text-violet-700' },\n done: { dot: 'bg-muted-foreground/50', text: 'text-muted-foreground' },\n error: { dot: 'bg-red-500', text: 'text-red-700' },\n muted: { dot: 'bg-muted-foreground/30', text: 'text-muted-foreground' },\n};\n\n/** A coloured dot and a label (truncated, with the full text as its tooltip). */\nexport const StatusChip: FC<{\n label: string;\n tone: SessionStatusTone;\n detail?: string | null;\n className?: string;\n}> = ({ label, tone, detail, className }) => (\n <span\n data-status-tone={tone}\n title={detail ?? label}\n className={cn(\n 'inline-flex min-w-0 max-w-full items-center gap-1.5 font-medium text-xs',\n STATUS_TONE_CLASS[tone].text,\n className,\n )}\n >\n <span aria-hidden=\"true\" className={cn('size-2 shrink-0 rounded-full', STATUS_TONE_CLASS[tone].dot)} />\n <span className=\"truncate\">{label}</span>\n </span>\n);\n\n/**\n * A labelled icon action on a row: a sibling of the row control (a click\n * never selects the row), disabled while its write is in flight, revealed on\n * row hover or focus unless `alwaysVisible`.\n */\nexport const RowIconButton: FC<{\n label: string;\n action: string;\n onClick: () => void;\n pending?: boolean;\n pressed?: boolean;\n alwaysVisible?: boolean;\n children: ReactNode;\n}> = ({ label, action, onClick, pending = false, pressed, alwaysVisible = false, children }) => (\n <button\n type=\"button\"\n onClick={(event) => {\n event.stopPropagation();\n if (!pending) onClick();\n }}\n disabled={pending}\n aria-busy={pending || undefined}\n aria-pressed={pressed}\n aria-label={label}\n title={label}\n data-action={action}\n className={cn(\n 'rounded p-1 text-muted-foreground transition-colors hover:bg-muted hover:text-foreground disabled:cursor-wait disabled:opacity-60',\n FOCUS_RING_CLASS,\n !alwaysVisible &&\n !pending &&\n 'opacity-0 focus-visible:opacity-100 group-focus-within:opacity-100 group-hover:opacity-100',\n )}\n >\n {children}\n </button>\n);\n"],"names":["pullRequestChipState","PR_STATE_ICON","PR_CHECKS_LABEL","jsxs","cn","jsx","PR_STATE_CLASS","orderedPullRequests","Popover","PopoverTrigger","PopoverContent"],"mappings":"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"}
1
+ {"version":3,"file":"session-row-parts.cjs","sources":["../../src/threads/session-row-parts.tsx"],"sourcesContent":["/**\n * Row pieces every SDK session list shares (`SessionList`, `SessionsPage`,\n * `Inbox`): the focus ring, the pull-request chip and its list, the\n * attention-toned status chip, and a labelled icon action that never selects\n * its row.\n */\nimport type { ConversationPullRequest } from '@athenaintel/agent-runtime';\nimport type { FC, MouseEvent, ReactNode } from 'react';\nimport { cn } from '../lib/utils';\nimport { Popover, PopoverContent, PopoverTrigger } from '../ui/popover';\nimport { PR_CHECKS_LABEL, PR_STATE_CLASS, PR_STATE_ICON } from './pull-request-display';\nimport {\n orderedPullRequests,\n type PullRequestChip as PullRequestChipModel,\n pullRequestChipState,\n} from './session-list-model';\nimport type { SessionStatusTone } from './sessions-page-model';\n\n/** The focus treatment every row control and action shares. */\nexport const FOCUS_RING_CLASS =\n 'outline-none focus-visible:ring-2 focus-visible:ring-ring/60 focus-visible:ring-offset-0';\n\nexport const stopPropagation = (event: MouseEvent) => event.stopPropagation();\n\nconst PR_CHIP_CLASS =\n 'inline-flex h-4 shrink-0 items-center gap-1 rounded-full border border-border/60 px-1.5 font-medium text-[11px] leading-none transition-colors hover:bg-muted';\n\n/**\n * One row of the pull-request list: the state icon, the title, and the\n * number, state and checks beneath it (the repository too when the list\n * spans several), as a link to GitHub in a new tab.\n */\nconst PullRequestListRow: FC<{ pullRequest: ConversationPullRequest; showRepo: boolean }> = ({\n pullRequest,\n showRepo,\n}) => {\n const state = pullRequestChipState(pullRequest);\n const Icon = PR_STATE_ICON[state];\n const meta = [\n showRepo ? `${pullRequest.repoFullName} #${pullRequest.number}` : `#${pullRequest.number}`,\n state,\n PR_CHECKS_LABEL[pullRequest.checksState],\n ]\n .filter(Boolean)\n .join(' · ');\n return (\n <li>\n <a\n href={pullRequest.url}\n target=\"_blank\"\n rel=\"noopener noreferrer\"\n data-pr-state={state}\n className={cn(\n 'flex items-start gap-2 rounded-sm px-2 py-1.5 text-xs transition-colors hover:bg-muted',\n FOCUS_RING_CLASS,\n )}\n >\n <Icon className={cn('mt-0.5 size-3.5 shrink-0', PR_STATE_CLASS[state])} aria-hidden />\n <span className=\"min-w-0 flex-1\">\n <span className=\"block truncate text-foreground\">\n {pullRequest.title || `#${pullRequest.number}`}\n </span>\n <span className=\"block truncate text-muted-foreground\">{meta}</span>\n </span>\n </a>\n </li>\n );\n};\n\n/**\n * The session's pull-request chip; a sibling of the row button (never nested\n * inside it) so the markup stays valid and a click on it never selects the\n * row. One pull request: a link to it. Several: a button that opens all of\n * them — in flight first, then the most recently updated — each a link to\n * GitHub.\n */\nexport const PullRequestChip: FC<{\n chip: PullRequestChipModel;\n pullRequests: readonly ConversationPullRequest[];\n}> = ({ chip, pullRequests }) => {\n const Icon = PR_STATE_ICON[chip.state];\n if (chip.count === 1) {\n return (\n <a\n href={chip.url}\n target=\"_blank\"\n rel=\"noopener noreferrer\"\n onClick={stopPropagation}\n title={chip.title}\n aria-label={`Pull request ${chip.label}, ${chip.state}`}\n data-pr-state={chip.state}\n data-pr-count={chip.count}\n className={cn(PR_CHIP_CLASS, FOCUS_RING_CLASS, PR_STATE_CLASS[chip.state])}\n >\n <Icon className=\"size-3\" aria-hidden />\n {chip.label}\n </a>\n );\n }\n const listLabel = `${chip.count} pull requests`;\n const ordered = orderedPullRequests(pullRequests);\n // One repository (the usual case) is named once in the header, so each\n // row's meta line has room for its state and checks.\n const repositories = new Set(ordered.map((pullRequest) => pullRequest.repoFullName));\n const sharedRepository = repositories.size === 1 ? (ordered[0]?.repoFullName ?? null) : null;\n return (\n <Popover>\n <PopoverTrigger asChild>\n <button\n type=\"button\"\n onClick={stopPropagation}\n aria-label={`${chip.label}: show all ${listLabel}`}\n data-pr-state={chip.state}\n data-pr-count={chip.count}\n className={cn(PR_CHIP_CLASS, FOCUS_RING_CLASS, PR_STATE_CLASS[chip.state])}\n >\n <Icon className=\"size-3\" aria-hidden />\n {chip.label}\n </button>\n </PopoverTrigger>\n <PopoverContent align=\"end\" className=\"w-80 p-0\" aria-label={listLabel} data-pr-list=\"\">\n <p className=\"truncate border-b border-border px-3 py-2 font-medium text-muted-foreground text-xs\">\n {sharedRepository ? `${listLabel} in ${sharedRepository}` : listLabel}\n </p>\n <ul className=\"max-h-72 overflow-y-auto p-1\">\n {ordered.map((pullRequest) => (\n <PullRequestListRow\n key={`${pullRequest.repoFullName}#${pullRequest.number}`}\n pullRequest={pullRequest}\n showRepo={sharedRepository === null}\n />\n ))}\n </ul>\n </PopoverContent>\n </Popover>\n );\n};\n\n/** One colour per attention tone: the chip's dot and its text. */\nexport const STATUS_TONE_CLASS: Record<SessionStatusTone, { dot: string; text: string }> = {\n needs_you: { dot: 'bg-orange-500', text: 'text-orange-700' },\n working: { dot: 'bg-blue-500 animate-pulse', text: 'text-blue-700' },\n ready: { dot: 'bg-green-500', text: 'text-green-700' },\n watching: { dot: 'bg-violet-400', text: 'text-violet-700' },\n done: { dot: 'bg-muted-foreground/50', text: 'text-muted-foreground' },\n error: { dot: 'bg-red-500', text: 'text-red-700' },\n muted: { dot: 'bg-muted-foreground/30', text: 'text-muted-foreground' },\n};\n\n/** A coloured dot and a label (truncated, with the full text as its tooltip). */\nexport const StatusChip: FC<{\n label: string;\n tone: SessionStatusTone;\n detail?: string | null;\n className?: string;\n}> = ({ label, tone, detail, className }) => (\n <span\n data-status-tone={tone}\n title={detail ?? label}\n className={cn(\n 'inline-flex min-w-0 max-w-full items-center gap-1.5 font-medium text-xs',\n STATUS_TONE_CLASS[tone].text,\n className,\n )}\n >\n <span aria-hidden=\"true\" className={cn('size-2 shrink-0 rounded-full', STATUS_TONE_CLASS[tone].dot)} />\n <span className=\"truncate\">{label}</span>\n </span>\n);\n\n/**\n * A labelled icon action on a row: a sibling of the row control (a click\n * never selects the row), disabled while its write is in flight, revealed on\n * row hover or focus unless `alwaysVisible`.\n */\nexport const RowIconButton: FC<{\n label: string;\n action: string;\n onClick: () => void;\n pending?: boolean;\n pressed?: boolean;\n alwaysVisible?: boolean;\n children: ReactNode;\n}> = ({ label, action, onClick, pending = false, pressed, alwaysVisible = false, children }) => (\n <button\n type=\"button\"\n onClick={(event) => {\n event.stopPropagation();\n if (!pending) onClick();\n }}\n disabled={pending}\n aria-busy={pending || undefined}\n aria-pressed={pressed}\n aria-label={label}\n title={label}\n data-action={action}\n className={cn(\n 'rounded p-1 text-muted-foreground transition-colors hover:bg-muted hover:text-foreground disabled:cursor-wait disabled:opacity-60',\n FOCUS_RING_CLASS,\n !alwaysVisible &&\n !pending &&\n 'opacity-0 focus-visible:opacity-100 group-focus-within:opacity-100 group-hover:opacity-100',\n )}\n >\n {children}\n </button>\n);\n"],"names":["pullRequestChipState","PR_STATE_ICON","PR_CHECKS_LABEL","jsxs","cn","jsx","PR_STATE_CLASS","orderedPullRequests","Popover","PopoverTrigger","PopoverContent"],"mappings":"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"}
@@ -1,7 +1,7 @@
1
1
  "use strict";
2
2
  Object.defineProperty(exports, Symbol.toStringTag, { value: "Module" });
3
3
  const sessionsQuery = require("./sessions-query.cjs");
4
- const sessionListModel = require("./session-list-model.cjs");
4
+ const threads_sessionListModel = require("./session-list-model.cjs");
5
5
  function mergedPullRequestOf(row) {
6
6
  const pullRequests = row.pullRequests ?? [];
7
7
  if (pullRequests.length === 0 || pullRequests.some((pr) => pr.state === "OPEN")) return null;
@@ -134,9 +134,15 @@ const SESSIONS_COLUMNS = [
134
134
  { id: "created", label: "Created", defaultVisible: false },
135
135
  { id: "updated", label: "Updated", defaultVisible: true }
136
136
  ];
137
- const DEFAULT_VISIBLE_SESSIONS_COLUMNS = SESSIONS_COLUMNS.filter(
138
- (column) => column.defaultVisible
137
+ const DEFAULT_HIDDEN_SESSIONS_COLUMNS = SESSIONS_COLUMNS.filter(
138
+ (column) => !column.defaultVisible
139
139
  ).map((column) => column.id);
140
+ function visibleSessionsColumns(hidden) {
141
+ return SESSIONS_COLUMNS.map((column) => column.id).filter((id) => !hidden.includes(id));
142
+ }
143
+ const DEFAULT_VISIBLE_SESSIONS_COLUMNS = visibleSessionsColumns(
144
+ DEFAULT_HIDDEN_SESSIONS_COLUMNS
145
+ );
140
146
  function humanizeId(value) {
141
147
  const words = value.replace(/^asset_/, "").replace(/[-_]+/g, " ").trim();
142
148
  if (/^[0-9a-f]{8} ?[0-9a-f]{4}/i.test(words)) return `${words.slice(0, 8)}…`;
@@ -209,7 +215,7 @@ function sessionsFilterChips(query, labels) {
209
215
  field: "startChannels",
210
216
  label: `Origin: ${join(
211
217
  query.startChannels.map(
212
- (channel) => sessionListModel.sessionOriginLabel({ startChannel: channel, appId: null, triggerType: null }) ?? channel
218
+ (channel) => threads_sessionListModel.sessionOriginLabel({ startChannel: channel, appId: null, triggerType: null }) ?? channel
213
219
  )
214
220
  )}`
215
221
  });
@@ -273,7 +279,7 @@ function sessionsCsv(rows, labels) {
273
279
  row.attention ?? "",
274
280
  row.runStatus ?? "",
275
281
  row.sessionStatus ?? "",
276
- sessionListModel.sessionOriginLabel(row) ?? "",
282
+ threads_sessionListModel.sessionOriginLabel(row) ?? "",
277
283
  row.collabAgentId ? agentLabel(row.collabAgentId, labels) : "",
278
284
  row.collabAgentId ? channelLabel(row.collabChannelId, labels) : "",
279
285
  (row.pullRequests ?? []).map((pr) => `${pr.repoFullName}#${pr.number} (${pr.state})`).join("; "),
@@ -287,6 +293,7 @@ function sessionsCsv(rows, labels) {
287
293
  });
288
294
  return [header.map(csvCell).join(","), ...lines].join("\r\n");
289
295
  }
296
+ exports.DEFAULT_HIDDEN_SESSIONS_COLUMNS = DEFAULT_HIDDEN_SESSIONS_COLUMNS;
290
297
  exports.DEFAULT_VISIBLE_SESSIONS_COLUMNS = DEFAULT_VISIBLE_SESSIONS_COLUMNS;
291
298
  exports.SESSIONS_COLUMNS = SESSIONS_COLUMNS;
292
299
  exports.SESSIONS_DATE_PRESETS = SESSIONS_DATE_PRESETS;
@@ -302,4 +309,5 @@ exports.sessionStatusChip = sessionStatusChip;
302
309
  exports.sessionStatusLabel = sessionStatusLabel;
303
310
  exports.sessionsCsv = sessionsCsv;
304
311
  exports.sessionsFilterChips = sessionsFilterChips;
312
+ exports.visibleSessionsColumns = visibleSessionsColumns;
305
313
  //# sourceMappingURL=sessions-page-model.cjs.map
@@ -1 +1 @@
1
- {"version":3,"file":"sessions-page-model.cjs","sources":["../../src/threads/sessions-page-model.ts"],"sourcesContent":["/**\n * Pure derivations behind `SessionsPage` and `Inbox`: the status a row shows\n * (what the person must do, colour-coded by attention), the inbox state chip,\n * grouping, columns, the filter chips' labels and the CSV export. React-free\n * so the render tests stay thin and hosts drawing their own rows reuse them.\n */\nimport type { ConversationAttention } from '@athenaintel/agent-runtime';\nimport {\n type AthenaSessionsQuery,\n type AthenaSessionsQueryField,\n DEFAULT_COLLAB_CHANNEL,\n type SessionRunStatus,\n type SessionSessionStatus,\n} from './sessions-query';\nimport { sessionOriginLabel } from './session-list-model';\nimport type { AthenaStatewireThreadSummary } from './statewire-thread-list';\n\nexport type SessionStatusTone =\n | 'needs_you'\n | 'working'\n | 'ready'\n | 'watching'\n | 'done'\n | 'error'\n | 'muted';\n\nexport interface SessionStatusChip {\n /** Short and imperative where the person must act (\"Approve send email\", \"Merge #12\"). */\n label: string;\n tone: SessionStatusTone;\n /** The longer line behind the label (the full next action), for a tooltip. */\n detail: string | null;\n}\n\ntype StatusRow = Pick<\n AthenaStatewireThreadSummary,\n 'attention' | 'nextAction' | 'attentionSource' | 'runStatus' | 'sessionStatus' | 'pullRequests'\n>;\n\nfunction mergedPullRequestOf(row: Pick<StatusRow, 'pullRequests'>): 'merged' | 'closed' | null {\n const pullRequests = row.pullRequests ?? [];\n if (pullRequests.length === 0 || pullRequests.some((pr) => pr.state === 'OPEN')) return null;\n return pullRequests.some((pr) => pr.state === 'MERGED') ? 'merged' : 'closed';\n}\n\n/**\n * The row's status column: what the session needs from the person, from the\n * server's attention and next action (Devin-style — \"Approve design\", \"PR is\n * ready\", \"Sleeping\", \"Working\", \"Done\"). An older server's rows fall back to\n * the status planes.\n */\nexport function sessionStatusChip(row: StatusRow): SessionStatusChip {\n const nextAction = row.nextAction?.trim() || null;\n switch (row.attention) {\n case 'needs_you':\n return { label: nextAction ?? 'Needs you', tone: 'needs_you', detail: nextAction };\n case 'working':\n return { label: 'Working', tone: 'working', detail: nextAction };\n case 'ready':\n return { label: nextAction ?? 'Ready for you', tone: 'ready', detail: nextAction };\n case 'watching':\n return {\n label: row.attentionSource === 'follow_up' ? 'Sleeping' : (nextAction ?? 'Waiting'),\n tone: 'watching',\n detail: nextAction,\n };\n case 'error':\n return { label: nextAction ?? 'Error', tone: 'error', detail: nextAction };\n case 'done': {\n const merged = mergedPullRequestOf(row);\n if (merged === 'merged') return { label: 'PR merged', tone: 'done', detail: nextAction };\n return { label: 'Done', tone: 'done', detail: nextAction };\n }\n default:\n break;\n }\n if (row.runStatus === 'needs_input' || row.sessionStatus === 'needs_input') {\n return { label: 'Needs you', tone: 'needs_you', detail: null };\n }\n if (row.runStatus === 'running' || row.runStatus === 'queued') {\n return { label: 'Working', tone: 'working', detail: null };\n }\n if (row.runStatus === 'failed' || row.sessionStatus === 'error') {\n return { label: 'Error', tone: 'error', detail: null };\n }\n if (row.runStatus === 'completed') return { label: 'Done', tone: 'done', detail: null };\n return { label: 'Idle', tone: 'muted', detail: null };\n}\n\n/**\n * The inbox row's state chip (Devin's \"Answered\" / \"PR merged\"): what\n * happened last, rather than the next step the status column names.\n */\nexport function inboxStateChip(row: StatusRow): { label: string; tone: SessionStatusTone } {\n switch (row.attention) {\n case 'needs_you':\n return { label: 'Needs you', tone: 'needs_you' };\n case 'working':\n return { label: 'Working', tone: 'working' };\n case 'ready':\n return { label: row.attentionSource === 'pull_request' ? 'PR ready' : 'Ready', tone: 'ready' };\n case 'watching':\n return {\n label: row.attentionSource === 'follow_up' ? 'Sleeping' : 'Waiting',\n tone: 'watching',\n };\n case 'error':\n return { label: 'Error', tone: 'error' };\n case 'done': {\n const merged = mergedPullRequestOf(row);\n if (merged === 'merged') return { label: 'PR merged', tone: 'done' };\n if (merged === 'closed') return { label: 'PR closed', tone: 'done' };\n return { label: 'Answered', tone: 'done' };\n }\n default: {\n // An older server reports no attention: the status planes decide.\n const fallback = sessionStatusChip(row);\n return { label: fallback.label, tone: fallback.tone };\n }\n }\n}\n\nexport type SessionsGroupBy = 'attention' | 'status' | 'none';\n\nexport interface SessionsSection {\n key: string;\n /** `null` for the single ungrouped section. */\n label: string | null;\n items: AthenaStatewireThreadSummary[];\n}\n\nconst ATTENTION_GROUPS: ReadonlyArray<{ key: ConversationAttention | 'other'; label: string }> = [\n { key: 'needs_you', label: 'Needs you' },\n { key: 'working', label: 'Working' },\n { key: 'ready', label: 'Ready' },\n { key: 'watching', label: 'Waiting' },\n { key: 'error', label: 'Error' },\n { key: 'done', label: 'Done' },\n { key: 'other', label: 'Other' },\n];\n\nconst RUN_STATUS_LABEL: Record<SessionRunStatus, string> = {\n needs_input: 'Needs input',\n running: 'Running',\n queued: 'Queued',\n scheduled: 'Scheduled',\n completed: 'Completed',\n failed: 'Failed',\n canceled: 'Canceled',\n};\n\nconst SESSION_STATUS_LABEL: Record<SessionSessionStatus, string> = {\n active: 'Active',\n needs_input: 'Needs input',\n idle: 'Idle',\n error: 'Error',\n};\n\nexport function runStatusLabel(status: string | null | undefined): string {\n return (status && RUN_STATUS_LABEL[status as SessionRunStatus]) || 'No run';\n}\n\nexport function sessionStatusLabel(status: string): string {\n return SESSION_STATUS_LABEL[status as SessionSessionStatus] ?? status;\n}\n\n/** Sections in display order; empty groups are omitted and row order is kept within a group. */\nexport function groupSessionsBy(\n rows: readonly AthenaStatewireThreadSummary[],\n groupBy: SessionsGroupBy,\n): SessionsSection[] {\n if (rows.length === 0) return [];\n if (groupBy === 'none') return [{ key: 'all', label: null, items: [...rows] }];\n const buckets = new Map<string, AthenaStatewireThreadSummary[]>();\n const keyOf = (row: AthenaStatewireThreadSummary): string => {\n if (groupBy === 'attention') {\n return ATTENTION_GROUPS.some((group) => group.key === row.attention)\n ? (row.attention as string)\n : 'other';\n }\n return row.runStatus && row.runStatus in RUN_STATUS_LABEL ? row.runStatus : 'none';\n };\n for (const row of rows) {\n const key = keyOf(row);\n const bucket = buckets.get(key) ?? [];\n bucket.push(row);\n buckets.set(key, bucket);\n }\n const order: ReadonlyArray<{ key: string; label: string }> =\n groupBy === 'attention'\n ? ATTENTION_GROUPS\n : [\n ...Object.entries(RUN_STATUS_LABEL).map(([key, label]) => ({ key, label })),\n { key: 'none', label: 'No run' },\n ];\n return order.flatMap(({ key, label }) => {\n const items = buckets.get(key);\n return items ? [{ key, label, items }] : [];\n });\n}\n\nexport type SessionsColumnId =\n | 'status'\n | 'origin'\n | 'mode'\n | 'pullRequests'\n | 'creator'\n | 'created'\n | 'updated';\n\nexport interface SessionsColumn {\n id: SessionsColumnId;\n label: string;\n /** Shown until the person hides it. */\n defaultVisible: boolean;\n}\n\n/** Every column after the title, in display order. */\nexport const SESSIONS_COLUMNS: readonly SessionsColumn[] = [\n { id: 'status', label: 'Status', defaultVisible: true },\n { id: 'origin', label: 'Origin', defaultVisible: true },\n { id: 'mode', label: 'Mode', defaultVisible: false },\n { id: 'pullRequests', label: 'Pull requests', defaultVisible: true },\n { id: 'creator', label: 'Creator', defaultVisible: false },\n { id: 'created', label: 'Created', defaultVisible: false },\n { id: 'updated', label: 'Updated', defaultVisible: true },\n];\n\nexport const DEFAULT_VISIBLE_SESSIONS_COLUMNS: readonly SessionsColumnId[] = SESSIONS_COLUMNS.filter(\n (column) => column.defaultVisible,\n).map((column) => column.id);\n\n/** Names for agents and channels a host knows; ids are shown otherwise. */\nexport interface SessionsLabels {\n agents?: Readonly<Record<string, string>>;\n channels?: Readonly<Record<string, string>>;\n}\n\nfunction humanizeId(value: string): string {\n const words = value.replace(/^asset_/, '').replace(/[-_]+/g, ' ').trim();\n if (/^[0-9a-f]{8} ?[0-9a-f]{4}/i.test(words)) return `${words.slice(0, 8)}…`;\n return words ? words.charAt(0).toUpperCase() + words.slice(1) : value;\n}\n\nexport function agentLabel(agentId: string, labels?: SessionsLabels): string {\n return labels?.agents?.[agentId] ?? `Agent ${humanizeId(agentId)}`;\n}\n\n/** The session's mode: its agent channel, `Default` for the agent's default channel. */\nexport function channelLabel(channelId: string | null | undefined, labels?: SessionsLabels): string {\n const channel = channelId || DEFAULT_COLLAB_CHANNEL;\n if (labels?.channels?.[channel]) return labels.channels[channel];\n return channel === DEFAULT_COLLAB_CHANNEL ? 'Default' : humanizeId(channel);\n}\n\n/**\n * A message as one line of plain text for a preview: the mention markup the\n * server stores (`<a class=\"mention\" …>Name</a>`) keeps its text, markdown\n * links keep their label, and emphasis, code and heading marks drop.\n */\nexport function plainExcerpt(text: string | null | undefined): string {\n if (!text) return '';\n return text\n .replace(/<[^>]*>/g, '')\n .replace(/!?\\[([^\\]]*)\\]\\([^)]*\\)/g, '$1')\n .replace(/(\\*\\*|__|`+|~~)/g, '')\n .replace(/^\\s{0,3}(#{1,6}|>|[-*+]|\\d+\\.)\\s+/gm, '')\n .replace(/&nbsp;/g, ' ')\n .replace(/&amp;/g, '&')\n .replace(/&lt;/g, '<')\n .replace(/&gt;/g, '>')\n .replace(/&quot;/g, '\"')\n .replace(/&#39;/g, \"'\")\n .replace(/\\s+/g, ' ')\n .trim();\n}\n\nexport function creatorLabel(createdByMe: boolean | null | undefined): string {\n if (createdByMe === true) return 'You';\n if (createdByMe === false) return 'Shared with you';\n return '';\n}\n\nexport interface SessionsFilterChip {\n field: AthenaSessionsQueryField;\n label: string;\n}\n\nconst dateLabel = (value: string): string => {\n const at = Date.parse(value);\n return Number.isFinite(at) ? new Date(at).toLocaleDateString() : value;\n};\n\n/** One chip per active filter, in a fixed order (sort and search are not chips). */\nexport function sessionsFilterChips(\n query: AthenaSessionsQuery,\n labels?: SessionsLabels,\n): SessionsFilterChip[] {\n const chips: SessionsFilterChip[] = [];\n const join = (values: readonly string[]) => values.join(', ');\n if (query.runStatuses?.length) {\n chips.push({ field: 'runStatuses', label: `Status: ${join(query.runStatuses.map(runStatusLabel))}` });\n }\n if (query.sessionStatuses?.length) {\n chips.push({\n field: 'sessionStatuses',\n label: `Session: ${join(query.sessionStatuses.map(sessionStatusLabel))}`,\n });\n }\n if (query.unreadOnly) chips.push({ field: 'unreadOnly', label: 'Unread' });\n if (query.favoritesOnly) chips.push({ field: 'favoritesOnly', label: 'Pinned' });\n if (query.hasPullRequests !== undefined) {\n chips.push({\n field: 'hasPullRequests',\n label: query.hasPullRequests ? 'Has pull requests' : 'No pull requests',\n });\n }\n if (query.createdByMe !== undefined) {\n chips.push({\n field: 'createdByMe',\n label: query.createdByMe ? 'Creator: You' : 'Creator: Shared with you',\n });\n }\n if (query.collabAgentIds?.length) {\n chips.push({\n field: 'collabAgentIds',\n label: `Agent: ${join(query.collabAgentIds.map((id) => agentLabel(id, labels)))}`,\n });\n }\n if (query.collabChannelIds?.length) {\n chips.push({\n field: 'collabChannelIds',\n label: `Mode: ${join(query.collabChannelIds.map((id) => channelLabel(id, labels)))}`,\n });\n }\n if (query.startChannels?.length) {\n chips.push({\n field: 'startChannels',\n label: `Origin: ${join(\n query.startChannels.map(\n (channel) =>\n sessionOriginLabel({ startChannel: channel, appId: null, triggerType: null }) ?? channel,\n ),\n )}`,\n });\n }\n if (query.createdAfter) chips.push({ field: 'createdAfter', label: `Created since ${dateLabel(query.createdAfter)}` });\n if (query.createdBefore) chips.push({ field: 'createdBefore', label: `Created before ${dateLabel(query.createdBefore)}` });\n if (query.updatedAfter) chips.push({ field: 'updatedAfter', label: `Updated since ${dateLabel(query.updatedAfter)}` });\n if (query.updatedBefore) chips.push({ field: 'updatedBefore', label: `Updated before ${dateLabel(query.updatedBefore)}` });\n if (query.excludeTriggered) chips.push({ field: 'excludeTriggered', label: 'Started by a person' });\n return chips;\n}\n\nexport type SessionsDatePreset = 'today' | 'last7' | 'last30' | 'older30';\n\nexport const SESSIONS_DATE_PRESETS: ReadonlyArray<{ id: SessionsDatePreset; label: string }> = [\n { id: 'today', label: 'Today' },\n { id: 'last7', label: 'Last 7 days' },\n { id: 'last30', label: 'Last 30 days' },\n { id: 'older30', label: 'Older than 30 days' },\n];\n\n/**\n * The ISO bound a preset stands for, as of `now`: local midnight `0`, `7` or\n * `30` days back. Day-aligned, so the same preset yields the same bound all\n * day — a reopened menu still recognises the chosen preset (and a second\n * click removes it).\n */\nexport function datePresetBounds(\n preset: SessionsDatePreset,\n now: Date = new Date(),\n): { after?: string; before?: string } {\n const midnightDaysAgo = (days: number): string => {\n const midnight = new Date(now);\n midnight.setHours(0, 0, 0, 0);\n midnight.setDate(midnight.getDate() - days);\n return midnight.toISOString();\n };\n if (preset === 'today') return { after: midnightDaysAgo(0) };\n if (preset === 'last7') return { after: midnightDaysAgo(7) };\n if (preset === 'last30') return { after: midnightDaysAgo(30) };\n return { before: midnightDaysAgo(30) };\n}\n\n/** RFC 4180 quoting, with a leading `'` on cells a spreadsheet would run as a formula. */\nfunction csvCell(value: string | number | boolean | null | undefined): string {\n if (value === null || value === undefined) return '';\n let text = String(value);\n if (/^[=+\\-@\\t\\r]/.test(text)) text = `'${text}`;\n return /[\",\\r\\n]/.test(text) ? `\"${text.replace(/\"/g, '\"\"')}\"` : text;\n}\n\n/** The loaded rows as CSV (header first, CRLF line ends), the visible ones only. */\nexport function sessionsCsv(\n rows: readonly AthenaStatewireThreadSummary[],\n labels?: SessionsLabels,\n): string {\n const header = [\n 'Title',\n 'Status',\n 'Next action',\n 'Attention',\n 'Run status',\n 'Session status',\n 'Origin',\n 'Agent',\n 'Mode',\n 'Pull requests',\n 'Pinned',\n 'Unread',\n 'Creator',\n 'Created',\n 'Updated',\n 'Thread ID',\n ];\n const lines = rows.map((row) => {\n const status = sessionStatusChip(row);\n return [\n row.title ?? '',\n status.label,\n row.nextAction ?? '',\n row.attention ?? '',\n row.runStatus ?? '',\n row.sessionStatus ?? '',\n sessionOriginLabel(row) ?? '',\n row.collabAgentId ? agentLabel(row.collabAgentId, labels) : '',\n row.collabAgentId ? channelLabel(row.collabChannelId, labels) : '',\n (row.pullRequests ?? []).map((pr) => `${pr.repoFullName}#${pr.number} (${pr.state})`).join('; '),\n row.isFavorited,\n row.isUnread,\n creatorLabel(row.createdByMe),\n row.createdAt ?? '',\n row.updatedAt,\n row.id,\n ]\n .map(csvCell)\n .join(',');\n });\n return [header.map(csvCell).join(','), ...lines].join('\\r\\n');\n}\n"],"names":["DEFAULT_COLLAB_CHANNEL","sessionOriginLabel"],"mappings":"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"}
1
+ {"version":3,"file":"sessions-page-model.cjs","sources":["../../src/threads/sessions-page-model.ts"],"sourcesContent":["/**\n * Pure derivations behind `SessionsPage` and `Inbox`: the status a row shows\n * (what the person must do, colour-coded by attention), the inbox state chip,\n * grouping, columns, the filter chips' labels and the CSV export. React-free\n * so the render tests stay thin and hosts drawing their own rows reuse them.\n */\nimport type { ConversationAttention } from '@athenaintel/agent-runtime';\nimport {\n type AthenaSessionsQuery,\n type AthenaSessionsQueryField,\n DEFAULT_COLLAB_CHANNEL,\n type SessionRunStatus,\n type SessionSessionStatus,\n} from './sessions-query';\nimport { sessionOriginLabel } from './session-list-model';\nimport type { AthenaStatewireThreadSummary } from './statewire-thread-list';\n\nexport type SessionStatusTone =\n | 'needs_you'\n | 'working'\n | 'ready'\n | 'watching'\n | 'done'\n | 'error'\n | 'muted';\n\nexport interface SessionStatusChip {\n /** Short and imperative where the person must act (\"Approve send email\", \"Merge #12\"). */\n label: string;\n tone: SessionStatusTone;\n /** The longer line behind the label (the full next action), for a tooltip. */\n detail: string | null;\n}\n\ntype StatusRow = Pick<\n AthenaStatewireThreadSummary,\n 'attention' | 'nextAction' | 'attentionSource' | 'runStatus' | 'sessionStatus' | 'pullRequests'\n>;\n\nfunction mergedPullRequestOf(row: Pick<StatusRow, 'pullRequests'>): 'merged' | 'closed' | null {\n const pullRequests = row.pullRequests ?? [];\n if (pullRequests.length === 0 || pullRequests.some((pr) => pr.state === 'OPEN')) return null;\n return pullRequests.some((pr) => pr.state === 'MERGED') ? 'merged' : 'closed';\n}\n\n/**\n * The row's status column: what the session needs from the person, from the\n * server's attention and next action (Devin-style — \"Approve design\", \"PR is\n * ready\", \"Sleeping\", \"Working\", \"Done\"). An older server's rows fall back to\n * the status planes.\n */\nexport function sessionStatusChip(row: StatusRow): SessionStatusChip {\n const nextAction = row.nextAction?.trim() || null;\n switch (row.attention) {\n case 'needs_you':\n return { label: nextAction ?? 'Needs you', tone: 'needs_you', detail: nextAction };\n case 'working':\n return { label: 'Working', tone: 'working', detail: nextAction };\n case 'ready':\n return { label: nextAction ?? 'Ready for you', tone: 'ready', detail: nextAction };\n case 'watching':\n return {\n label: row.attentionSource === 'follow_up' ? 'Sleeping' : (nextAction ?? 'Waiting'),\n tone: 'watching',\n detail: nextAction,\n };\n case 'error':\n return { label: nextAction ?? 'Error', tone: 'error', detail: nextAction };\n case 'done': {\n const merged = mergedPullRequestOf(row);\n if (merged === 'merged') return { label: 'PR merged', tone: 'done', detail: nextAction };\n return { label: 'Done', tone: 'done', detail: nextAction };\n }\n default:\n break;\n }\n if (row.runStatus === 'needs_input' || row.sessionStatus === 'needs_input') {\n return { label: 'Needs you', tone: 'needs_you', detail: null };\n }\n if (row.runStatus === 'running' || row.runStatus === 'queued') {\n return { label: 'Working', tone: 'working', detail: null };\n }\n if (row.runStatus === 'failed' || row.sessionStatus === 'error') {\n return { label: 'Error', tone: 'error', detail: null };\n }\n if (row.runStatus === 'completed') return { label: 'Done', tone: 'done', detail: null };\n return { label: 'Idle', tone: 'muted', detail: null };\n}\n\n/**\n * The inbox row's state chip (Devin's \"Answered\" / \"PR merged\"): what\n * happened last, rather than the next step the status column names.\n */\nexport function inboxStateChip(row: StatusRow): { label: string; tone: SessionStatusTone } {\n switch (row.attention) {\n case 'needs_you':\n return { label: 'Needs you', tone: 'needs_you' };\n case 'working':\n return { label: 'Working', tone: 'working' };\n case 'ready':\n return { label: row.attentionSource === 'pull_request' ? 'PR ready' : 'Ready', tone: 'ready' };\n case 'watching':\n return {\n label: row.attentionSource === 'follow_up' ? 'Sleeping' : 'Waiting',\n tone: 'watching',\n };\n case 'error':\n return { label: 'Error', tone: 'error' };\n case 'done': {\n const merged = mergedPullRequestOf(row);\n if (merged === 'merged') return { label: 'PR merged', tone: 'done' };\n if (merged === 'closed') return { label: 'PR closed', tone: 'done' };\n return { label: 'Answered', tone: 'done' };\n }\n default: {\n // An older server reports no attention: the status planes decide.\n const fallback = sessionStatusChip(row);\n return { label: fallback.label, tone: fallback.tone };\n }\n }\n}\n\nexport type SessionsGroupBy = 'attention' | 'status' | 'none';\n\nexport interface SessionsSection {\n key: string;\n /** `null` for the single ungrouped section. */\n label: string | null;\n items: AthenaStatewireThreadSummary[];\n}\n\nconst ATTENTION_GROUPS: ReadonlyArray<{ key: ConversationAttention | 'other'; label: string }> = [\n { key: 'needs_you', label: 'Needs you' },\n { key: 'working', label: 'Working' },\n { key: 'ready', label: 'Ready' },\n { key: 'watching', label: 'Waiting' },\n { key: 'error', label: 'Error' },\n { key: 'done', label: 'Done' },\n { key: 'other', label: 'Other' },\n];\n\nconst RUN_STATUS_LABEL: Record<SessionRunStatus, string> = {\n needs_input: 'Needs input',\n running: 'Running',\n queued: 'Queued',\n scheduled: 'Scheduled',\n completed: 'Completed',\n failed: 'Failed',\n canceled: 'Canceled',\n};\n\nconst SESSION_STATUS_LABEL: Record<SessionSessionStatus, string> = {\n active: 'Active',\n needs_input: 'Needs input',\n idle: 'Idle',\n error: 'Error',\n};\n\nexport function runStatusLabel(status: string | null | undefined): string {\n return (status && RUN_STATUS_LABEL[status as SessionRunStatus]) || 'No run';\n}\n\nexport function sessionStatusLabel(status: string): string {\n return SESSION_STATUS_LABEL[status as SessionSessionStatus] ?? status;\n}\n\n/** Sections in display order; empty groups are omitted and row order is kept within a group. */\nexport function groupSessionsBy(\n rows: readonly AthenaStatewireThreadSummary[],\n groupBy: SessionsGroupBy,\n): SessionsSection[] {\n if (rows.length === 0) return [];\n if (groupBy === 'none') return [{ key: 'all', label: null, items: [...rows] }];\n const buckets = new Map<string, AthenaStatewireThreadSummary[]>();\n const keyOf = (row: AthenaStatewireThreadSummary): string => {\n if (groupBy === 'attention') {\n return ATTENTION_GROUPS.some((group) => group.key === row.attention)\n ? (row.attention as string)\n : 'other';\n }\n return row.runStatus && row.runStatus in RUN_STATUS_LABEL ? row.runStatus : 'none';\n };\n for (const row of rows) {\n const key = keyOf(row);\n const bucket = buckets.get(key) ?? [];\n bucket.push(row);\n buckets.set(key, bucket);\n }\n const order: ReadonlyArray<{ key: string; label: string }> =\n groupBy === 'attention'\n ? ATTENTION_GROUPS\n : [\n ...Object.entries(RUN_STATUS_LABEL).map(([key, label]) => ({ key, label })),\n { key: 'none', label: 'No run' },\n ];\n return order.flatMap(({ key, label }) => {\n const items = buckets.get(key);\n return items ? [{ key, label, items }] : [];\n });\n}\n\nexport type SessionsColumnId =\n | 'status'\n | 'origin'\n | 'mode'\n | 'pullRequests'\n | 'creator'\n | 'created'\n | 'updated';\n\nexport interface SessionsColumn {\n id: SessionsColumnId;\n label: string;\n /** Shown until the person hides it. */\n defaultVisible: boolean;\n}\n\n/** Every column after the title, in display order. */\nexport const SESSIONS_COLUMNS: readonly SessionsColumn[] = [\n { id: 'status', label: 'Status', defaultVisible: true },\n { id: 'origin', label: 'Origin', defaultVisible: true },\n { id: 'mode', label: 'Mode', defaultVisible: false },\n { id: 'pullRequests', label: 'Pull requests', defaultVisible: true },\n { id: 'creator', label: 'Creator', defaultVisible: false },\n { id: 'created', label: 'Created', defaultVisible: false },\n { id: 'updated', label: 'Updated', defaultVisible: true },\n];\n\n/**\n * The columns hidden until the person shows them, unless the host chooses its\n * own (`SessionsPage`'s `defaultHiddenColumns`): Mode, Creator and Created.\n */\nexport const DEFAULT_HIDDEN_SESSIONS_COLUMNS: readonly SessionsColumnId[] = SESSIONS_COLUMNS.filter(\n (column) => !column.defaultVisible,\n).map((column) => column.id);\n\n/** The columns shown, in display order, while `hidden` are hidden. */\nexport function visibleSessionsColumns(hidden: readonly SessionsColumnId[]): SessionsColumnId[] {\n return SESSIONS_COLUMNS.map((column) => column.id).filter((id) => !hidden.includes(id));\n}\n\nexport const DEFAULT_VISIBLE_SESSIONS_COLUMNS: readonly SessionsColumnId[] = visibleSessionsColumns(\n DEFAULT_HIDDEN_SESSIONS_COLUMNS,\n);\n\n/** Names for agents and channels a host knows; ids are shown otherwise. */\nexport interface SessionsLabels {\n agents?: Readonly<Record<string, string>>;\n channels?: Readonly<Record<string, string>>;\n}\n\nfunction humanizeId(value: string): string {\n const words = value.replace(/^asset_/, '').replace(/[-_]+/g, ' ').trim();\n if (/^[0-9a-f]{8} ?[0-9a-f]{4}/i.test(words)) return `${words.slice(0, 8)}…`;\n return words ? words.charAt(0).toUpperCase() + words.slice(1) : value;\n}\n\nexport function agentLabel(agentId: string, labels?: SessionsLabels): string {\n return labels?.agents?.[agentId] ?? `Agent ${humanizeId(agentId)}`;\n}\n\n/** The session's mode: its agent channel, `Default` for the agent's default channel. */\nexport function channelLabel(channelId: string | null | undefined, labels?: SessionsLabels): string {\n const channel = channelId || DEFAULT_COLLAB_CHANNEL;\n if (labels?.channels?.[channel]) return labels.channels[channel];\n return channel === DEFAULT_COLLAB_CHANNEL ? 'Default' : humanizeId(channel);\n}\n\n/**\n * A message as one line of plain text for a preview: the mention markup the\n * server stores (`<a class=\"mention\" …>Name</a>`) keeps its text, markdown\n * links keep their label, and emphasis, code and heading marks drop.\n */\nexport function plainExcerpt(text: string | null | undefined): string {\n if (!text) return '';\n return text\n .replace(/<[^>]*>/g, '')\n .replace(/!?\\[([^\\]]*)\\]\\([^)]*\\)/g, '$1')\n .replace(/(\\*\\*|__|`+|~~)/g, '')\n .replace(/^\\s{0,3}(#{1,6}|>|[-*+]|\\d+\\.)\\s+/gm, '')\n .replace(/&nbsp;/g, ' ')\n .replace(/&amp;/g, '&')\n .replace(/&lt;/g, '<')\n .replace(/&gt;/g, '>')\n .replace(/&quot;/g, '\"')\n .replace(/&#39;/g, \"'\")\n .replace(/\\s+/g, ' ')\n .trim();\n}\n\nexport function creatorLabel(createdByMe: boolean | null | undefined): string {\n if (createdByMe === true) return 'You';\n if (createdByMe === false) return 'Shared with you';\n return '';\n}\n\nexport interface SessionsFilterChip {\n field: AthenaSessionsQueryField;\n label: string;\n}\n\nconst dateLabel = (value: string): string => {\n const at = Date.parse(value);\n return Number.isFinite(at) ? new Date(at).toLocaleDateString() : value;\n};\n\n/** One chip per active filter, in a fixed order (sort and search are not chips). */\nexport function sessionsFilterChips(\n query: AthenaSessionsQuery,\n labels?: SessionsLabels,\n): SessionsFilterChip[] {\n const chips: SessionsFilterChip[] = [];\n const join = (values: readonly string[]) => values.join(', ');\n if (query.runStatuses?.length) {\n chips.push({ field: 'runStatuses', label: `Status: ${join(query.runStatuses.map(runStatusLabel))}` });\n }\n if (query.sessionStatuses?.length) {\n chips.push({\n field: 'sessionStatuses',\n label: `Session: ${join(query.sessionStatuses.map(sessionStatusLabel))}`,\n });\n }\n if (query.unreadOnly) chips.push({ field: 'unreadOnly', label: 'Unread' });\n if (query.favoritesOnly) chips.push({ field: 'favoritesOnly', label: 'Pinned' });\n if (query.hasPullRequests !== undefined) {\n chips.push({\n field: 'hasPullRequests',\n label: query.hasPullRequests ? 'Has pull requests' : 'No pull requests',\n });\n }\n if (query.createdByMe !== undefined) {\n chips.push({\n field: 'createdByMe',\n label: query.createdByMe ? 'Creator: You' : 'Creator: Shared with you',\n });\n }\n if (query.collabAgentIds?.length) {\n chips.push({\n field: 'collabAgentIds',\n label: `Agent: ${join(query.collabAgentIds.map((id) => agentLabel(id, labels)))}`,\n });\n }\n if (query.collabChannelIds?.length) {\n chips.push({\n field: 'collabChannelIds',\n label: `Mode: ${join(query.collabChannelIds.map((id) => channelLabel(id, labels)))}`,\n });\n }\n if (query.startChannels?.length) {\n chips.push({\n field: 'startChannels',\n label: `Origin: ${join(\n query.startChannels.map(\n (channel) =>\n sessionOriginLabel({ startChannel: channel, appId: null, triggerType: null }) ?? channel,\n ),\n )}`,\n });\n }\n if (query.createdAfter) chips.push({ field: 'createdAfter', label: `Created since ${dateLabel(query.createdAfter)}` });\n if (query.createdBefore) chips.push({ field: 'createdBefore', label: `Created before ${dateLabel(query.createdBefore)}` });\n if (query.updatedAfter) chips.push({ field: 'updatedAfter', label: `Updated since ${dateLabel(query.updatedAfter)}` });\n if (query.updatedBefore) chips.push({ field: 'updatedBefore', label: `Updated before ${dateLabel(query.updatedBefore)}` });\n if (query.excludeTriggered) chips.push({ field: 'excludeTriggered', label: 'Started by a person' });\n return chips;\n}\n\nexport type SessionsDatePreset = 'today' | 'last7' | 'last30' | 'older30';\n\nexport const SESSIONS_DATE_PRESETS: ReadonlyArray<{ id: SessionsDatePreset; label: string }> = [\n { id: 'today', label: 'Today' },\n { id: 'last7', label: 'Last 7 days' },\n { id: 'last30', label: 'Last 30 days' },\n { id: 'older30', label: 'Older than 30 days' },\n];\n\n/**\n * The ISO bound a preset stands for, as of `now`: local midnight `0`, `7` or\n * `30` days back. Day-aligned, so the same preset yields the same bound all\n * day — a reopened menu still recognises the chosen preset (and a second\n * click removes it).\n */\nexport function datePresetBounds(\n preset: SessionsDatePreset,\n now: Date = new Date(),\n): { after?: string; before?: string } {\n const midnightDaysAgo = (days: number): string => {\n const midnight = new Date(now);\n midnight.setHours(0, 0, 0, 0);\n midnight.setDate(midnight.getDate() - days);\n return midnight.toISOString();\n };\n if (preset === 'today') return { after: midnightDaysAgo(0) };\n if (preset === 'last7') return { after: midnightDaysAgo(7) };\n if (preset === 'last30') return { after: midnightDaysAgo(30) };\n return { before: midnightDaysAgo(30) };\n}\n\n/** RFC 4180 quoting, with a leading `'` on cells a spreadsheet would run as a formula. */\nfunction csvCell(value: string | number | boolean | null | undefined): string {\n if (value === null || value === undefined) return '';\n let text = String(value);\n if (/^[=+\\-@\\t\\r]/.test(text)) text = `'${text}`;\n return /[\",\\r\\n]/.test(text) ? `\"${text.replace(/\"/g, '\"\"')}\"` : text;\n}\n\n/** The loaded rows as CSV (header first, CRLF line ends), the visible ones only. */\nexport function sessionsCsv(\n rows: readonly AthenaStatewireThreadSummary[],\n labels?: SessionsLabels,\n): string {\n const header = [\n 'Title',\n 'Status',\n 'Next action',\n 'Attention',\n 'Run status',\n 'Session status',\n 'Origin',\n 'Agent',\n 'Mode',\n 'Pull requests',\n 'Pinned',\n 'Unread',\n 'Creator',\n 'Created',\n 'Updated',\n 'Thread ID',\n ];\n const lines = rows.map((row) => {\n const status = sessionStatusChip(row);\n return [\n row.title ?? '',\n status.label,\n row.nextAction ?? '',\n row.attention ?? '',\n row.runStatus ?? '',\n row.sessionStatus ?? '',\n sessionOriginLabel(row) ?? '',\n row.collabAgentId ? agentLabel(row.collabAgentId, labels) : '',\n row.collabAgentId ? channelLabel(row.collabChannelId, labels) : '',\n (row.pullRequests ?? []).map((pr) => `${pr.repoFullName}#${pr.number} (${pr.state})`).join('; '),\n row.isFavorited,\n row.isUnread,\n creatorLabel(row.createdByMe),\n row.createdAt ?? '',\n row.updatedAt,\n row.id,\n ]\n .map(csvCell)\n .join(',');\n });\n return [header.map(csvCell).join(','), ...lines].join('\\r\\n');\n}\n"],"names":["DEFAULT_COLLAB_CHANNEL","sessionOriginLabel"],"mappings":"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"}
@@ -44,6 +44,13 @@ export interface SessionsColumn {
44
44
  }
45
45
  /** Every column after the title, in display order. */
46
46
  export declare const SESSIONS_COLUMNS: readonly SessionsColumn[];
47
+ /**
48
+ * The columns hidden until the person shows them, unless the host chooses its
49
+ * own (`SessionsPage`'s `defaultHiddenColumns`): Mode, Creator and Created.
50
+ */
51
+ export declare const DEFAULT_HIDDEN_SESSIONS_COLUMNS: readonly SessionsColumnId[];
52
+ /** The columns shown, in display order, while `hidden` are hidden. */
53
+ export declare function visibleSessionsColumns(hidden: readonly SessionsColumnId[]): SessionsColumnId[];
47
54
  export declare const DEFAULT_VISIBLE_SESSIONS_COLUMNS: readonly SessionsColumnId[];
48
55
  /** Names for agents and channels a host knows; ids are shown otherwise. */
49
56
  export interface SessionsLabels {
@@ -132,9 +132,15 @@ const SESSIONS_COLUMNS = [
132
132
  { id: "created", label: "Created", defaultVisible: false },
133
133
  { id: "updated", label: "Updated", defaultVisible: true }
134
134
  ];
135
- const DEFAULT_VISIBLE_SESSIONS_COLUMNS = SESSIONS_COLUMNS.filter(
136
- (column) => column.defaultVisible
135
+ const DEFAULT_HIDDEN_SESSIONS_COLUMNS = SESSIONS_COLUMNS.filter(
136
+ (column) => !column.defaultVisible
137
137
  ).map((column) => column.id);
138
+ function visibleSessionsColumns(hidden) {
139
+ return SESSIONS_COLUMNS.map((column) => column.id).filter((id) => !hidden.includes(id));
140
+ }
141
+ const DEFAULT_VISIBLE_SESSIONS_COLUMNS = visibleSessionsColumns(
142
+ DEFAULT_HIDDEN_SESSIONS_COLUMNS
143
+ );
138
144
  function humanizeId(value) {
139
145
  const words = value.replace(/^asset_/, "").replace(/[-_]+/g, " ").trim();
140
146
  if (/^[0-9a-f]{8} ?[0-9a-f]{4}/i.test(words)) return `${words.slice(0, 8)}…`;
@@ -286,6 +292,7 @@ function sessionsCsv(rows, labels) {
286
292
  return [header.map(csvCell).join(","), ...lines].join("\r\n");
287
293
  }
288
294
  export {
295
+ DEFAULT_HIDDEN_SESSIONS_COLUMNS,
289
296
  DEFAULT_VISIBLE_SESSIONS_COLUMNS,
290
297
  SESSIONS_COLUMNS,
291
298
  SESSIONS_DATE_PRESETS,
@@ -300,6 +307,7 @@ export {
300
307
  sessionStatusChip,
301
308
  sessionStatusLabel,
302
309
  sessionsCsv,
303
- sessionsFilterChips
310
+ sessionsFilterChips,
311
+ visibleSessionsColumns
304
312
  };
305
313
  //# sourceMappingURL=sessions-page-model.js.map
@@ -1 +1 @@
1
- {"version":3,"file":"sessions-page-model.js","sources":["../../src/threads/sessions-page-model.ts"],"sourcesContent":["/**\n * Pure derivations behind `SessionsPage` and `Inbox`: the status a row shows\n * (what the person must do, colour-coded by attention), the inbox state chip,\n * grouping, columns, the filter chips' labels and the CSV export. React-free\n * so the render tests stay thin and hosts drawing their own rows reuse them.\n */\nimport type { ConversationAttention } from '@athenaintel/agent-runtime';\nimport {\n type AthenaSessionsQuery,\n type AthenaSessionsQueryField,\n DEFAULT_COLLAB_CHANNEL,\n type SessionRunStatus,\n type SessionSessionStatus,\n} from './sessions-query';\nimport { sessionOriginLabel } from './session-list-model';\nimport type { AthenaStatewireThreadSummary } from './statewire-thread-list';\n\nexport type SessionStatusTone =\n | 'needs_you'\n | 'working'\n | 'ready'\n | 'watching'\n | 'done'\n | 'error'\n | 'muted';\n\nexport interface SessionStatusChip {\n /** Short and imperative where the person must act (\"Approve send email\", \"Merge #12\"). */\n label: string;\n tone: SessionStatusTone;\n /** The longer line behind the label (the full next action), for a tooltip. */\n detail: string | null;\n}\n\ntype StatusRow = Pick<\n AthenaStatewireThreadSummary,\n 'attention' | 'nextAction' | 'attentionSource' | 'runStatus' | 'sessionStatus' | 'pullRequests'\n>;\n\nfunction mergedPullRequestOf(row: Pick<StatusRow, 'pullRequests'>): 'merged' | 'closed' | null {\n const pullRequests = row.pullRequests ?? [];\n if (pullRequests.length === 0 || pullRequests.some((pr) => pr.state === 'OPEN')) return null;\n return pullRequests.some((pr) => pr.state === 'MERGED') ? 'merged' : 'closed';\n}\n\n/**\n * The row's status column: what the session needs from the person, from the\n * server's attention and next action (Devin-style — \"Approve design\", \"PR is\n * ready\", \"Sleeping\", \"Working\", \"Done\"). An older server's rows fall back to\n * the status planes.\n */\nexport function sessionStatusChip(row: StatusRow): SessionStatusChip {\n const nextAction = row.nextAction?.trim() || null;\n switch (row.attention) {\n case 'needs_you':\n return { label: nextAction ?? 'Needs you', tone: 'needs_you', detail: nextAction };\n case 'working':\n return { label: 'Working', tone: 'working', detail: nextAction };\n case 'ready':\n return { label: nextAction ?? 'Ready for you', tone: 'ready', detail: nextAction };\n case 'watching':\n return {\n label: row.attentionSource === 'follow_up' ? 'Sleeping' : (nextAction ?? 'Waiting'),\n tone: 'watching',\n detail: nextAction,\n };\n case 'error':\n return { label: nextAction ?? 'Error', tone: 'error', detail: nextAction };\n case 'done': {\n const merged = mergedPullRequestOf(row);\n if (merged === 'merged') return { label: 'PR merged', tone: 'done', detail: nextAction };\n return { label: 'Done', tone: 'done', detail: nextAction };\n }\n default:\n break;\n }\n if (row.runStatus === 'needs_input' || row.sessionStatus === 'needs_input') {\n return { label: 'Needs you', tone: 'needs_you', detail: null };\n }\n if (row.runStatus === 'running' || row.runStatus === 'queued') {\n return { label: 'Working', tone: 'working', detail: null };\n }\n if (row.runStatus === 'failed' || row.sessionStatus === 'error') {\n return { label: 'Error', tone: 'error', detail: null };\n }\n if (row.runStatus === 'completed') return { label: 'Done', tone: 'done', detail: null };\n return { label: 'Idle', tone: 'muted', detail: null };\n}\n\n/**\n * The inbox row's state chip (Devin's \"Answered\" / \"PR merged\"): what\n * happened last, rather than the next step the status column names.\n */\nexport function inboxStateChip(row: StatusRow): { label: string; tone: SessionStatusTone } {\n switch (row.attention) {\n case 'needs_you':\n return { label: 'Needs you', tone: 'needs_you' };\n case 'working':\n return { label: 'Working', tone: 'working' };\n case 'ready':\n return { label: row.attentionSource === 'pull_request' ? 'PR ready' : 'Ready', tone: 'ready' };\n case 'watching':\n return {\n label: row.attentionSource === 'follow_up' ? 'Sleeping' : 'Waiting',\n tone: 'watching',\n };\n case 'error':\n return { label: 'Error', tone: 'error' };\n case 'done': {\n const merged = mergedPullRequestOf(row);\n if (merged === 'merged') return { label: 'PR merged', tone: 'done' };\n if (merged === 'closed') return { label: 'PR closed', tone: 'done' };\n return { label: 'Answered', tone: 'done' };\n }\n default: {\n // An older server reports no attention: the status planes decide.\n const fallback = sessionStatusChip(row);\n return { label: fallback.label, tone: fallback.tone };\n }\n }\n}\n\nexport type SessionsGroupBy = 'attention' | 'status' | 'none';\n\nexport interface SessionsSection {\n key: string;\n /** `null` for the single ungrouped section. */\n label: string | null;\n items: AthenaStatewireThreadSummary[];\n}\n\nconst ATTENTION_GROUPS: ReadonlyArray<{ key: ConversationAttention | 'other'; label: string }> = [\n { key: 'needs_you', label: 'Needs you' },\n { key: 'working', label: 'Working' },\n { key: 'ready', label: 'Ready' },\n { key: 'watching', label: 'Waiting' },\n { key: 'error', label: 'Error' },\n { key: 'done', label: 'Done' },\n { key: 'other', label: 'Other' },\n];\n\nconst RUN_STATUS_LABEL: Record<SessionRunStatus, string> = {\n needs_input: 'Needs input',\n running: 'Running',\n queued: 'Queued',\n scheduled: 'Scheduled',\n completed: 'Completed',\n failed: 'Failed',\n canceled: 'Canceled',\n};\n\nconst SESSION_STATUS_LABEL: Record<SessionSessionStatus, string> = {\n active: 'Active',\n needs_input: 'Needs input',\n idle: 'Idle',\n error: 'Error',\n};\n\nexport function runStatusLabel(status: string | null | undefined): string {\n return (status && RUN_STATUS_LABEL[status as SessionRunStatus]) || 'No run';\n}\n\nexport function sessionStatusLabel(status: string): string {\n return SESSION_STATUS_LABEL[status as SessionSessionStatus] ?? status;\n}\n\n/** Sections in display order; empty groups are omitted and row order is kept within a group. */\nexport function groupSessionsBy(\n rows: readonly AthenaStatewireThreadSummary[],\n groupBy: SessionsGroupBy,\n): SessionsSection[] {\n if (rows.length === 0) return [];\n if (groupBy === 'none') return [{ key: 'all', label: null, items: [...rows] }];\n const buckets = new Map<string, AthenaStatewireThreadSummary[]>();\n const keyOf = (row: AthenaStatewireThreadSummary): string => {\n if (groupBy === 'attention') {\n return ATTENTION_GROUPS.some((group) => group.key === row.attention)\n ? (row.attention as string)\n : 'other';\n }\n return row.runStatus && row.runStatus in RUN_STATUS_LABEL ? row.runStatus : 'none';\n };\n for (const row of rows) {\n const key = keyOf(row);\n const bucket = buckets.get(key) ?? [];\n bucket.push(row);\n buckets.set(key, bucket);\n }\n const order: ReadonlyArray<{ key: string; label: string }> =\n groupBy === 'attention'\n ? ATTENTION_GROUPS\n : [\n ...Object.entries(RUN_STATUS_LABEL).map(([key, label]) => ({ key, label })),\n { key: 'none', label: 'No run' },\n ];\n return order.flatMap(({ key, label }) => {\n const items = buckets.get(key);\n return items ? [{ key, label, items }] : [];\n });\n}\n\nexport type SessionsColumnId =\n | 'status'\n | 'origin'\n | 'mode'\n | 'pullRequests'\n | 'creator'\n | 'created'\n | 'updated';\n\nexport interface SessionsColumn {\n id: SessionsColumnId;\n label: string;\n /** Shown until the person hides it. */\n defaultVisible: boolean;\n}\n\n/** Every column after the title, in display order. */\nexport const SESSIONS_COLUMNS: readonly SessionsColumn[] = [\n { id: 'status', label: 'Status', defaultVisible: true },\n { id: 'origin', label: 'Origin', defaultVisible: true },\n { id: 'mode', label: 'Mode', defaultVisible: false },\n { id: 'pullRequests', label: 'Pull requests', defaultVisible: true },\n { id: 'creator', label: 'Creator', defaultVisible: false },\n { id: 'created', label: 'Created', defaultVisible: false },\n { id: 'updated', label: 'Updated', defaultVisible: true },\n];\n\nexport const DEFAULT_VISIBLE_SESSIONS_COLUMNS: readonly SessionsColumnId[] = SESSIONS_COLUMNS.filter(\n (column) => column.defaultVisible,\n).map((column) => column.id);\n\n/** Names for agents and channels a host knows; ids are shown otherwise. */\nexport interface SessionsLabels {\n agents?: Readonly<Record<string, string>>;\n channels?: Readonly<Record<string, string>>;\n}\n\nfunction humanizeId(value: string): string {\n const words = value.replace(/^asset_/, '').replace(/[-_]+/g, ' ').trim();\n if (/^[0-9a-f]{8} ?[0-9a-f]{4}/i.test(words)) return `${words.slice(0, 8)}…`;\n return words ? words.charAt(0).toUpperCase() + words.slice(1) : value;\n}\n\nexport function agentLabel(agentId: string, labels?: SessionsLabels): string {\n return labels?.agents?.[agentId] ?? `Agent ${humanizeId(agentId)}`;\n}\n\n/** The session's mode: its agent channel, `Default` for the agent's default channel. */\nexport function channelLabel(channelId: string | null | undefined, labels?: SessionsLabels): string {\n const channel = channelId || DEFAULT_COLLAB_CHANNEL;\n if (labels?.channels?.[channel]) return labels.channels[channel];\n return channel === DEFAULT_COLLAB_CHANNEL ? 'Default' : humanizeId(channel);\n}\n\n/**\n * A message as one line of plain text for a preview: the mention markup the\n * server stores (`<a class=\"mention\" …>Name</a>`) keeps its text, markdown\n * links keep their label, and emphasis, code and heading marks drop.\n */\nexport function plainExcerpt(text: string | null | undefined): string {\n if (!text) return '';\n return text\n .replace(/<[^>]*>/g, '')\n .replace(/!?\\[([^\\]]*)\\]\\([^)]*\\)/g, '$1')\n .replace(/(\\*\\*|__|`+|~~)/g, '')\n .replace(/^\\s{0,3}(#{1,6}|>|[-*+]|\\d+\\.)\\s+/gm, '')\n .replace(/&nbsp;/g, ' ')\n .replace(/&amp;/g, '&')\n .replace(/&lt;/g, '<')\n .replace(/&gt;/g, '>')\n .replace(/&quot;/g, '\"')\n .replace(/&#39;/g, \"'\")\n .replace(/\\s+/g, ' ')\n .trim();\n}\n\nexport function creatorLabel(createdByMe: boolean | null | undefined): string {\n if (createdByMe === true) return 'You';\n if (createdByMe === false) return 'Shared with you';\n return '';\n}\n\nexport interface SessionsFilterChip {\n field: AthenaSessionsQueryField;\n label: string;\n}\n\nconst dateLabel = (value: string): string => {\n const at = Date.parse(value);\n return Number.isFinite(at) ? new Date(at).toLocaleDateString() : value;\n};\n\n/** One chip per active filter, in a fixed order (sort and search are not chips). */\nexport function sessionsFilterChips(\n query: AthenaSessionsQuery,\n labels?: SessionsLabels,\n): SessionsFilterChip[] {\n const chips: SessionsFilterChip[] = [];\n const join = (values: readonly string[]) => values.join(', ');\n if (query.runStatuses?.length) {\n chips.push({ field: 'runStatuses', label: `Status: ${join(query.runStatuses.map(runStatusLabel))}` });\n }\n if (query.sessionStatuses?.length) {\n chips.push({\n field: 'sessionStatuses',\n label: `Session: ${join(query.sessionStatuses.map(sessionStatusLabel))}`,\n });\n }\n if (query.unreadOnly) chips.push({ field: 'unreadOnly', label: 'Unread' });\n if (query.favoritesOnly) chips.push({ field: 'favoritesOnly', label: 'Pinned' });\n if (query.hasPullRequests !== undefined) {\n chips.push({\n field: 'hasPullRequests',\n label: query.hasPullRequests ? 'Has pull requests' : 'No pull requests',\n });\n }\n if (query.createdByMe !== undefined) {\n chips.push({\n field: 'createdByMe',\n label: query.createdByMe ? 'Creator: You' : 'Creator: Shared with you',\n });\n }\n if (query.collabAgentIds?.length) {\n chips.push({\n field: 'collabAgentIds',\n label: `Agent: ${join(query.collabAgentIds.map((id) => agentLabel(id, labels)))}`,\n });\n }\n if (query.collabChannelIds?.length) {\n chips.push({\n field: 'collabChannelIds',\n label: `Mode: ${join(query.collabChannelIds.map((id) => channelLabel(id, labels)))}`,\n });\n }\n if (query.startChannels?.length) {\n chips.push({\n field: 'startChannels',\n label: `Origin: ${join(\n query.startChannels.map(\n (channel) =>\n sessionOriginLabel({ startChannel: channel, appId: null, triggerType: null }) ?? channel,\n ),\n )}`,\n });\n }\n if (query.createdAfter) chips.push({ field: 'createdAfter', label: `Created since ${dateLabel(query.createdAfter)}` });\n if (query.createdBefore) chips.push({ field: 'createdBefore', label: `Created before ${dateLabel(query.createdBefore)}` });\n if (query.updatedAfter) chips.push({ field: 'updatedAfter', label: `Updated since ${dateLabel(query.updatedAfter)}` });\n if (query.updatedBefore) chips.push({ field: 'updatedBefore', label: `Updated before ${dateLabel(query.updatedBefore)}` });\n if (query.excludeTriggered) chips.push({ field: 'excludeTriggered', label: 'Started by a person' });\n return chips;\n}\n\nexport type SessionsDatePreset = 'today' | 'last7' | 'last30' | 'older30';\n\nexport const SESSIONS_DATE_PRESETS: ReadonlyArray<{ id: SessionsDatePreset; label: string }> = [\n { id: 'today', label: 'Today' },\n { id: 'last7', label: 'Last 7 days' },\n { id: 'last30', label: 'Last 30 days' },\n { id: 'older30', label: 'Older than 30 days' },\n];\n\n/**\n * The ISO bound a preset stands for, as of `now`: local midnight `0`, `7` or\n * `30` days back. Day-aligned, so the same preset yields the same bound all\n * day — a reopened menu still recognises the chosen preset (and a second\n * click removes it).\n */\nexport function datePresetBounds(\n preset: SessionsDatePreset,\n now: Date = new Date(),\n): { after?: string; before?: string } {\n const midnightDaysAgo = (days: number): string => {\n const midnight = new Date(now);\n midnight.setHours(0, 0, 0, 0);\n midnight.setDate(midnight.getDate() - days);\n return midnight.toISOString();\n };\n if (preset === 'today') return { after: midnightDaysAgo(0) };\n if (preset === 'last7') return { after: midnightDaysAgo(7) };\n if (preset === 'last30') return { after: midnightDaysAgo(30) };\n return { before: midnightDaysAgo(30) };\n}\n\n/** RFC 4180 quoting, with a leading `'` on cells a spreadsheet would run as a formula. */\nfunction csvCell(value: string | number | boolean | null | undefined): string {\n if (value === null || value === undefined) return '';\n let text = String(value);\n if (/^[=+\\-@\\t\\r]/.test(text)) text = `'${text}`;\n return /[\",\\r\\n]/.test(text) ? `\"${text.replace(/\"/g, '\"\"')}\"` : text;\n}\n\n/** The loaded rows as CSV (header first, CRLF line ends), the visible ones only. */\nexport function sessionsCsv(\n rows: readonly AthenaStatewireThreadSummary[],\n labels?: SessionsLabels,\n): string {\n const header = [\n 'Title',\n 'Status',\n 'Next action',\n 'Attention',\n 'Run status',\n 'Session status',\n 'Origin',\n 'Agent',\n 'Mode',\n 'Pull requests',\n 'Pinned',\n 'Unread',\n 'Creator',\n 'Created',\n 'Updated',\n 'Thread ID',\n ];\n const lines = rows.map((row) => {\n const status = sessionStatusChip(row);\n return [\n row.title ?? '',\n status.label,\n row.nextAction ?? '',\n row.attention ?? '',\n row.runStatus ?? '',\n row.sessionStatus ?? '',\n sessionOriginLabel(row) ?? '',\n row.collabAgentId ? agentLabel(row.collabAgentId, labels) : '',\n row.collabAgentId ? channelLabel(row.collabChannelId, labels) : '',\n (row.pullRequests ?? []).map((pr) => `${pr.repoFullName}#${pr.number} (${pr.state})`).join('; '),\n row.isFavorited,\n row.isUnread,\n creatorLabel(row.createdByMe),\n row.createdAt ?? '',\n row.updatedAt,\n row.id,\n ]\n .map(csvCell)\n .join(',');\n });\n return [header.map(csvCell).join(','), ...lines].join('\\r\\n');\n}\n"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"sessions-page-model.js","sources":["../../src/threads/sessions-page-model.ts"],"sourcesContent":["/**\n * Pure derivations behind `SessionsPage` and `Inbox`: the status a row shows\n * (what the person must do, colour-coded by attention), the inbox state chip,\n * grouping, columns, the filter chips' labels and the CSV export. React-free\n * so the render tests stay thin and hosts drawing their own rows reuse them.\n */\nimport type { ConversationAttention } from '@athenaintel/agent-runtime';\nimport {\n type AthenaSessionsQuery,\n type AthenaSessionsQueryField,\n DEFAULT_COLLAB_CHANNEL,\n type SessionRunStatus,\n type SessionSessionStatus,\n} from './sessions-query';\nimport { sessionOriginLabel } from './session-list-model';\nimport type { AthenaStatewireThreadSummary } from './statewire-thread-list';\n\nexport type SessionStatusTone =\n | 'needs_you'\n | 'working'\n | 'ready'\n | 'watching'\n | 'done'\n | 'error'\n | 'muted';\n\nexport interface SessionStatusChip {\n /** Short and imperative where the person must act (\"Approve send email\", \"Merge #12\"). */\n label: string;\n tone: SessionStatusTone;\n /** The longer line behind the label (the full next action), for a tooltip. */\n detail: string | null;\n}\n\ntype StatusRow = Pick<\n AthenaStatewireThreadSummary,\n 'attention' | 'nextAction' | 'attentionSource' | 'runStatus' | 'sessionStatus' | 'pullRequests'\n>;\n\nfunction mergedPullRequestOf(row: Pick<StatusRow, 'pullRequests'>): 'merged' | 'closed' | null {\n const pullRequests = row.pullRequests ?? [];\n if (pullRequests.length === 0 || pullRequests.some((pr) => pr.state === 'OPEN')) return null;\n return pullRequests.some((pr) => pr.state === 'MERGED') ? 'merged' : 'closed';\n}\n\n/**\n * The row's status column: what the session needs from the person, from the\n * server's attention and next action (Devin-style — \"Approve design\", \"PR is\n * ready\", \"Sleeping\", \"Working\", \"Done\"). An older server's rows fall back to\n * the status planes.\n */\nexport function sessionStatusChip(row: StatusRow): SessionStatusChip {\n const nextAction = row.nextAction?.trim() || null;\n switch (row.attention) {\n case 'needs_you':\n return { label: nextAction ?? 'Needs you', tone: 'needs_you', detail: nextAction };\n case 'working':\n return { label: 'Working', tone: 'working', detail: nextAction };\n case 'ready':\n return { label: nextAction ?? 'Ready for you', tone: 'ready', detail: nextAction };\n case 'watching':\n return {\n label: row.attentionSource === 'follow_up' ? 'Sleeping' : (nextAction ?? 'Waiting'),\n tone: 'watching',\n detail: nextAction,\n };\n case 'error':\n return { label: nextAction ?? 'Error', tone: 'error', detail: nextAction };\n case 'done': {\n const merged = mergedPullRequestOf(row);\n if (merged === 'merged') return { label: 'PR merged', tone: 'done', detail: nextAction };\n return { label: 'Done', tone: 'done', detail: nextAction };\n }\n default:\n break;\n }\n if (row.runStatus === 'needs_input' || row.sessionStatus === 'needs_input') {\n return { label: 'Needs you', tone: 'needs_you', detail: null };\n }\n if (row.runStatus === 'running' || row.runStatus === 'queued') {\n return { label: 'Working', tone: 'working', detail: null };\n }\n if (row.runStatus === 'failed' || row.sessionStatus === 'error') {\n return { label: 'Error', tone: 'error', detail: null };\n }\n if (row.runStatus === 'completed') return { label: 'Done', tone: 'done', detail: null };\n return { label: 'Idle', tone: 'muted', detail: null };\n}\n\n/**\n * The inbox row's state chip (Devin's \"Answered\" / \"PR merged\"): what\n * happened last, rather than the next step the status column names.\n */\nexport function inboxStateChip(row: StatusRow): { label: string; tone: SessionStatusTone } {\n switch (row.attention) {\n case 'needs_you':\n return { label: 'Needs you', tone: 'needs_you' };\n case 'working':\n return { label: 'Working', tone: 'working' };\n case 'ready':\n return { label: row.attentionSource === 'pull_request' ? 'PR ready' : 'Ready', tone: 'ready' };\n case 'watching':\n return {\n label: row.attentionSource === 'follow_up' ? 'Sleeping' : 'Waiting',\n tone: 'watching',\n };\n case 'error':\n return { label: 'Error', tone: 'error' };\n case 'done': {\n const merged = mergedPullRequestOf(row);\n if (merged === 'merged') return { label: 'PR merged', tone: 'done' };\n if (merged === 'closed') return { label: 'PR closed', tone: 'done' };\n return { label: 'Answered', tone: 'done' };\n }\n default: {\n // An older server reports no attention: the status planes decide.\n const fallback = sessionStatusChip(row);\n return { label: fallback.label, tone: fallback.tone };\n }\n }\n}\n\nexport type SessionsGroupBy = 'attention' | 'status' | 'none';\n\nexport interface SessionsSection {\n key: string;\n /** `null` for the single ungrouped section. */\n label: string | null;\n items: AthenaStatewireThreadSummary[];\n}\n\nconst ATTENTION_GROUPS: ReadonlyArray<{ key: ConversationAttention | 'other'; label: string }> = [\n { key: 'needs_you', label: 'Needs you' },\n { key: 'working', label: 'Working' },\n { key: 'ready', label: 'Ready' },\n { key: 'watching', label: 'Waiting' },\n { key: 'error', label: 'Error' },\n { key: 'done', label: 'Done' },\n { key: 'other', label: 'Other' },\n];\n\nconst RUN_STATUS_LABEL: Record<SessionRunStatus, string> = {\n needs_input: 'Needs input',\n running: 'Running',\n queued: 'Queued',\n scheduled: 'Scheduled',\n completed: 'Completed',\n failed: 'Failed',\n canceled: 'Canceled',\n};\n\nconst SESSION_STATUS_LABEL: Record<SessionSessionStatus, string> = {\n active: 'Active',\n needs_input: 'Needs input',\n idle: 'Idle',\n error: 'Error',\n};\n\nexport function runStatusLabel(status: string | null | undefined): string {\n return (status && RUN_STATUS_LABEL[status as SessionRunStatus]) || 'No run';\n}\n\nexport function sessionStatusLabel(status: string): string {\n return SESSION_STATUS_LABEL[status as SessionSessionStatus] ?? status;\n}\n\n/** Sections in display order; empty groups are omitted and row order is kept within a group. */\nexport function groupSessionsBy(\n rows: readonly AthenaStatewireThreadSummary[],\n groupBy: SessionsGroupBy,\n): SessionsSection[] {\n if (rows.length === 0) return [];\n if (groupBy === 'none') return [{ key: 'all', label: null, items: [...rows] }];\n const buckets = new Map<string, AthenaStatewireThreadSummary[]>();\n const keyOf = (row: AthenaStatewireThreadSummary): string => {\n if (groupBy === 'attention') {\n return ATTENTION_GROUPS.some((group) => group.key === row.attention)\n ? (row.attention as string)\n : 'other';\n }\n return row.runStatus && row.runStatus in RUN_STATUS_LABEL ? row.runStatus : 'none';\n };\n for (const row of rows) {\n const key = keyOf(row);\n const bucket = buckets.get(key) ?? [];\n bucket.push(row);\n buckets.set(key, bucket);\n }\n const order: ReadonlyArray<{ key: string; label: string }> =\n groupBy === 'attention'\n ? ATTENTION_GROUPS\n : [\n ...Object.entries(RUN_STATUS_LABEL).map(([key, label]) => ({ key, label })),\n { key: 'none', label: 'No run' },\n ];\n return order.flatMap(({ key, label }) => {\n const items = buckets.get(key);\n return items ? [{ key, label, items }] : [];\n });\n}\n\nexport type SessionsColumnId =\n | 'status'\n | 'origin'\n | 'mode'\n | 'pullRequests'\n | 'creator'\n | 'created'\n | 'updated';\n\nexport interface SessionsColumn {\n id: SessionsColumnId;\n label: string;\n /** Shown until the person hides it. */\n defaultVisible: boolean;\n}\n\n/** Every column after the title, in display order. */\nexport const SESSIONS_COLUMNS: readonly SessionsColumn[] = [\n { id: 'status', label: 'Status', defaultVisible: true },\n { id: 'origin', label: 'Origin', defaultVisible: true },\n { id: 'mode', label: 'Mode', defaultVisible: false },\n { id: 'pullRequests', label: 'Pull requests', defaultVisible: true },\n { id: 'creator', label: 'Creator', defaultVisible: false },\n { id: 'created', label: 'Created', defaultVisible: false },\n { id: 'updated', label: 'Updated', defaultVisible: true },\n];\n\n/**\n * The columns hidden until the person shows them, unless the host chooses its\n * own (`SessionsPage`'s `defaultHiddenColumns`): Mode, Creator and Created.\n */\nexport const DEFAULT_HIDDEN_SESSIONS_COLUMNS: readonly SessionsColumnId[] = SESSIONS_COLUMNS.filter(\n (column) => !column.defaultVisible,\n).map((column) => column.id);\n\n/** The columns shown, in display order, while `hidden` are hidden. */\nexport function visibleSessionsColumns(hidden: readonly SessionsColumnId[]): SessionsColumnId[] {\n return SESSIONS_COLUMNS.map((column) => column.id).filter((id) => !hidden.includes(id));\n}\n\nexport const DEFAULT_VISIBLE_SESSIONS_COLUMNS: readonly SessionsColumnId[] = visibleSessionsColumns(\n DEFAULT_HIDDEN_SESSIONS_COLUMNS,\n);\n\n/** Names for agents and channels a host knows; ids are shown otherwise. */\nexport interface SessionsLabels {\n agents?: Readonly<Record<string, string>>;\n channels?: Readonly<Record<string, string>>;\n}\n\nfunction humanizeId(value: string): string {\n const words = value.replace(/^asset_/, '').replace(/[-_]+/g, ' ').trim();\n if (/^[0-9a-f]{8} ?[0-9a-f]{4}/i.test(words)) return `${words.slice(0, 8)}…`;\n return words ? words.charAt(0).toUpperCase() + words.slice(1) : value;\n}\n\nexport function agentLabel(agentId: string, labels?: SessionsLabels): string {\n return labels?.agents?.[agentId] ?? `Agent ${humanizeId(agentId)}`;\n}\n\n/** The session's mode: its agent channel, `Default` for the agent's default channel. */\nexport function channelLabel(channelId: string | null | undefined, labels?: SessionsLabels): string {\n const channel = channelId || DEFAULT_COLLAB_CHANNEL;\n if (labels?.channels?.[channel]) return labels.channels[channel];\n return channel === DEFAULT_COLLAB_CHANNEL ? 'Default' : humanizeId(channel);\n}\n\n/**\n * A message as one line of plain text for a preview: the mention markup the\n * server stores (`<a class=\"mention\" …>Name</a>`) keeps its text, markdown\n * links keep their label, and emphasis, code and heading marks drop.\n */\nexport function plainExcerpt(text: string | null | undefined): string {\n if (!text) return '';\n return text\n .replace(/<[^>]*>/g, '')\n .replace(/!?\\[([^\\]]*)\\]\\([^)]*\\)/g, '$1')\n .replace(/(\\*\\*|__|`+|~~)/g, '')\n .replace(/^\\s{0,3}(#{1,6}|>|[-*+]|\\d+\\.)\\s+/gm, '')\n .replace(/&nbsp;/g, ' ')\n .replace(/&amp;/g, '&')\n .replace(/&lt;/g, '<')\n .replace(/&gt;/g, '>')\n .replace(/&quot;/g, '\"')\n .replace(/&#39;/g, \"'\")\n .replace(/\\s+/g, ' ')\n .trim();\n}\n\nexport function creatorLabel(createdByMe: boolean | null | undefined): string {\n if (createdByMe === true) return 'You';\n if (createdByMe === false) return 'Shared with you';\n return '';\n}\n\nexport interface SessionsFilterChip {\n field: AthenaSessionsQueryField;\n label: string;\n}\n\nconst dateLabel = (value: string): string => {\n const at = Date.parse(value);\n return Number.isFinite(at) ? new Date(at).toLocaleDateString() : value;\n};\n\n/** One chip per active filter, in a fixed order (sort and search are not chips). */\nexport function sessionsFilterChips(\n query: AthenaSessionsQuery,\n labels?: SessionsLabels,\n): SessionsFilterChip[] {\n const chips: SessionsFilterChip[] = [];\n const join = (values: readonly string[]) => values.join(', ');\n if (query.runStatuses?.length) {\n chips.push({ field: 'runStatuses', label: `Status: ${join(query.runStatuses.map(runStatusLabel))}` });\n }\n if (query.sessionStatuses?.length) {\n chips.push({\n field: 'sessionStatuses',\n label: `Session: ${join(query.sessionStatuses.map(sessionStatusLabel))}`,\n });\n }\n if (query.unreadOnly) chips.push({ field: 'unreadOnly', label: 'Unread' });\n if (query.favoritesOnly) chips.push({ field: 'favoritesOnly', label: 'Pinned' });\n if (query.hasPullRequests !== undefined) {\n chips.push({\n field: 'hasPullRequests',\n label: query.hasPullRequests ? 'Has pull requests' : 'No pull requests',\n });\n }\n if (query.createdByMe !== undefined) {\n chips.push({\n field: 'createdByMe',\n label: query.createdByMe ? 'Creator: You' : 'Creator: Shared with you',\n });\n }\n if (query.collabAgentIds?.length) {\n chips.push({\n field: 'collabAgentIds',\n label: `Agent: ${join(query.collabAgentIds.map((id) => agentLabel(id, labels)))}`,\n });\n }\n if (query.collabChannelIds?.length) {\n chips.push({\n field: 'collabChannelIds',\n label: `Mode: ${join(query.collabChannelIds.map((id) => channelLabel(id, labels)))}`,\n });\n }\n if (query.startChannels?.length) {\n chips.push({\n field: 'startChannels',\n label: `Origin: ${join(\n query.startChannels.map(\n (channel) =>\n sessionOriginLabel({ startChannel: channel, appId: null, triggerType: null }) ?? channel,\n ),\n )}`,\n });\n }\n if (query.createdAfter) chips.push({ field: 'createdAfter', label: `Created since ${dateLabel(query.createdAfter)}` });\n if (query.createdBefore) chips.push({ field: 'createdBefore', label: `Created before ${dateLabel(query.createdBefore)}` });\n if (query.updatedAfter) chips.push({ field: 'updatedAfter', label: `Updated since ${dateLabel(query.updatedAfter)}` });\n if (query.updatedBefore) chips.push({ field: 'updatedBefore', label: `Updated before ${dateLabel(query.updatedBefore)}` });\n if (query.excludeTriggered) chips.push({ field: 'excludeTriggered', label: 'Started by a person' });\n return chips;\n}\n\nexport type SessionsDatePreset = 'today' | 'last7' | 'last30' | 'older30';\n\nexport const SESSIONS_DATE_PRESETS: ReadonlyArray<{ id: SessionsDatePreset; label: string }> = [\n { id: 'today', label: 'Today' },\n { id: 'last7', label: 'Last 7 days' },\n { id: 'last30', label: 'Last 30 days' },\n { id: 'older30', label: 'Older than 30 days' },\n];\n\n/**\n * The ISO bound a preset stands for, as of `now`: local midnight `0`, `7` or\n * `30` days back. Day-aligned, so the same preset yields the same bound all\n * day — a reopened menu still recognises the chosen preset (and a second\n * click removes it).\n */\nexport function datePresetBounds(\n preset: SessionsDatePreset,\n now: Date = new Date(),\n): { after?: string; before?: string } {\n const midnightDaysAgo = (days: number): string => {\n const midnight = new Date(now);\n midnight.setHours(0, 0, 0, 0);\n midnight.setDate(midnight.getDate() - days);\n return midnight.toISOString();\n };\n if (preset === 'today') return { after: midnightDaysAgo(0) };\n if (preset === 'last7') return { after: midnightDaysAgo(7) };\n if (preset === 'last30') return { after: midnightDaysAgo(30) };\n return { before: midnightDaysAgo(30) };\n}\n\n/** RFC 4180 quoting, with a leading `'` on cells a spreadsheet would run as a formula. */\nfunction csvCell(value: string | number | boolean | null | undefined): string {\n if (value === null || value === undefined) return '';\n let text = String(value);\n if (/^[=+\\-@\\t\\r]/.test(text)) text = `'${text}`;\n return /[\",\\r\\n]/.test(text) ? `\"${text.replace(/\"/g, '\"\"')}\"` : text;\n}\n\n/** The loaded rows as CSV (header first, CRLF line ends), the visible ones only. */\nexport function sessionsCsv(\n rows: readonly AthenaStatewireThreadSummary[],\n labels?: SessionsLabels,\n): string {\n const header = [\n 'Title',\n 'Status',\n 'Next action',\n 'Attention',\n 'Run status',\n 'Session status',\n 'Origin',\n 'Agent',\n 'Mode',\n 'Pull requests',\n 'Pinned',\n 'Unread',\n 'Creator',\n 'Created',\n 'Updated',\n 'Thread ID',\n ];\n const lines = rows.map((row) => {\n const status = sessionStatusChip(row);\n return [\n row.title ?? '',\n status.label,\n row.nextAction ?? '',\n row.attention ?? '',\n row.runStatus ?? '',\n row.sessionStatus ?? '',\n sessionOriginLabel(row) ?? '',\n row.collabAgentId ? agentLabel(row.collabAgentId, labels) : '',\n row.collabAgentId ? channelLabel(row.collabChannelId, labels) : '',\n (row.pullRequests ?? []).map((pr) => `${pr.repoFullName}#${pr.number} (${pr.state})`).join('; '),\n row.isFavorited,\n row.isUnread,\n creatorLabel(row.createdByMe),\n row.createdAt ?? '',\n row.updatedAt,\n row.id,\n ]\n .map(csvCell)\n .join(',');\n });\n return [header.map(csvCell).join(','), ...lines].join('\\r\\n');\n}\n"],"names":[],"mappings":"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"}
@@ -49,27 +49,27 @@ function sanitizeSessionsQuery(value) {
49
49
  if (record.direction === "desc" || record.direction === "asc") query.direction = record.direction;
50
50
  return sessionsQuery.normalizeSessionsQuery(query);
51
51
  }
52
- function sanitizeDisplay(value) {
53
- if (!value || typeof value !== "object") return DEFAULT_SESSIONS_PAGE_DISPLAY;
52
+ function sanitizeDisplay(value, fallback) {
53
+ if (!value || typeof value !== "object") return fallback;
54
54
  const record = value;
55
- const groupBy = record.groupBy === "attention" || record.groupBy === "status" || record.groupBy === "none" ? record.groupBy : DEFAULT_SESSIONS_PAGE_DISPLAY.groupBy;
55
+ const groupBy = record.groupBy === "attention" || record.groupBy === "status" || record.groupBy === "none" ? record.groupBy : fallback.groupBy;
56
56
  const known = new Set(sessionsPageModel.SESSIONS_COLUMNS.map((column) => column.id));
57
- const columns = isStringArray(record.columns) ? record.columns.filter((column) => known.has(column)) : DEFAULT_SESSIONS_PAGE_DISPLAY.columns;
57
+ const columns = isStringArray(record.columns) ? record.columns.filter((column) => known.has(column)) : fallback.columns;
58
58
  return { groupBy, columns };
59
59
  }
60
- function readSessionsPageSettings(key) {
60
+ function readSessionsPageSettings(key, defaultDisplay = DEFAULT_SESSIONS_PAGE_DISPLAY) {
61
61
  var _a;
62
62
  const raw = (_a = storage()) == null ? void 0 : _a.getItem(STORAGE_PREFIX + key);
63
- if (!raw) return { defaultQuery: null, display: DEFAULT_SESSIONS_PAGE_DISPLAY };
63
+ if (!raw) return { defaultQuery: null, display: defaultDisplay };
64
64
  try {
65
65
  const parsed = JSON.parse(raw);
66
66
  const record = parsed && typeof parsed === "object" ? parsed : {};
67
67
  return {
68
68
  defaultQuery: sanitizeSessionsQuery(record.defaultQuery),
69
- display: sanitizeDisplay(record.display)
69
+ display: sanitizeDisplay(record.display, defaultDisplay)
70
70
  };
71
71
  } catch {
72
- return { defaultQuery: null, display: DEFAULT_SESSIONS_PAGE_DISPLAY };
72
+ return { defaultQuery: null, display: defaultDisplay };
73
73
  }
74
74
  }
75
75
  function writeSessionsPageSettings(key, settings) {
@@ -1 +1 @@
1
- {"version":3,"file":"sessions-page-storage.cjs","sources":["../../src/threads/sessions-page-storage.ts"],"sourcesContent":["/**\n * What `SessionsPage` remembers in this browser: the filters saved with\n * \"Save as default\" and the display options (grouping, columns). Per storage\n * key (a host with several pages names each); never a credential, never a\n * row. Unreadable or foreign values read as \"nothing saved\".\n */\nimport {\n type AthenaSessionsQuery,\n normalizeSessionsQuery,\n SESSION_RUN_STATUSES,\n SESSION_SESSION_STATUSES,\n} from './sessions-query';\nimport {\n DEFAULT_VISIBLE_SESSIONS_COLUMNS,\n SESSIONS_COLUMNS,\n type SessionsColumnId,\n type SessionsGroupBy,\n} from './sessions-page-model';\n\nexport interface SessionsPageDisplay {\n groupBy: SessionsGroupBy;\n columns: SessionsColumnId[];\n}\n\nexport interface SessionsPageSettings {\n /** The saved default filters and order (no search: a search is never a default). */\n defaultQuery: AthenaSessionsQuery | null;\n display: SessionsPageDisplay;\n}\n\nexport const DEFAULT_SESSIONS_PAGE_DISPLAY: SessionsPageDisplay = {\n groupBy: 'attention',\n columns: [...DEFAULT_VISIBLE_SESSIONS_COLUMNS],\n};\n\nconst STORAGE_PREFIX = 'athena-sdk:sessions-page:v1:';\n\nfunction storage(): Storage | null {\n try {\n return typeof window === 'undefined' ? null : window.localStorage;\n } catch {\n return null;\n }\n}\n\nconst isStringArray = (value: unknown): value is string[] =>\n Array.isArray(value) && value.every((item) => typeof item === 'string');\n\n/** Keep only the fields and values a query can carry. */\nexport function sanitizeSessionsQuery(value: unknown): AthenaSessionsQuery | null {\n if (!value || typeof value !== 'object' || Array.isArray(value)) return null;\n const record = value as Record<string, unknown>;\n const query: AthenaSessionsQuery = {};\n for (const field of ['collabAgentIds', 'collabChannelIds', 'startChannels'] as const) {\n if (isStringArray(record[field])) query[field] = record[field];\n }\n if (isStringArray(record.runStatuses)) {\n query.runStatuses = record.runStatuses.filter((status) =>\n (SESSION_RUN_STATUSES as readonly string[]).includes(status),\n ) as AthenaSessionsQuery['runStatuses'];\n }\n if (isStringArray(record.sessionStatuses)) {\n query.sessionStatuses = record.sessionStatuses.filter((status) =>\n (SESSION_SESSION_STATUSES as readonly string[]).includes(status),\n ) as AthenaSessionsQuery['sessionStatuses'];\n }\n for (const field of ['createdAfter', 'createdBefore', 'updatedAfter', 'updatedBefore'] as const) {\n if (typeof record[field] === 'string') query[field] = record[field];\n }\n for (const field of [\n 'favoritesOnly',\n 'unreadOnly',\n 'hasPullRequests',\n 'createdByMe',\n 'excludeDismissed',\n 'excludeTriggered',\n ] as const) {\n if (typeof record[field] === 'boolean') query[field] = record[field];\n }\n if (record.sort === 'updated' || record.sort === 'created') query.sort = record.sort;\n if (record.direction === 'desc' || record.direction === 'asc') query.direction = record.direction;\n return normalizeSessionsQuery(query);\n}\n\nfunction sanitizeDisplay(value: unknown): SessionsPageDisplay {\n if (!value || typeof value !== 'object') return DEFAULT_SESSIONS_PAGE_DISPLAY;\n const record = value as Record<string, unknown>;\n const groupBy =\n record.groupBy === 'attention' || record.groupBy === 'status' || record.groupBy === 'none'\n ? record.groupBy\n : DEFAULT_SESSIONS_PAGE_DISPLAY.groupBy;\n const known = new Set<string>(SESSIONS_COLUMNS.map((column) => column.id));\n const columns = isStringArray(record.columns)\n ? (record.columns.filter((column) => known.has(column)) as SessionsColumnId[])\n : DEFAULT_SESSIONS_PAGE_DISPLAY.columns;\n return { groupBy, columns };\n}\n\nexport function readSessionsPageSettings(key: string): SessionsPageSettings {\n const raw = storage()?.getItem(STORAGE_PREFIX + key);\n if (!raw) return { defaultQuery: null, display: DEFAULT_SESSIONS_PAGE_DISPLAY };\n try {\n const parsed: unknown = JSON.parse(raw);\n const record = (parsed && typeof parsed === 'object' ? parsed : {}) as Record<string, unknown>;\n return {\n defaultQuery: sanitizeSessionsQuery(record.defaultQuery),\n display: sanitizeDisplay(record.display),\n };\n } catch {\n return { defaultQuery: null, display: DEFAULT_SESSIONS_PAGE_DISPLAY };\n }\n}\n\n/** Best effort: a full or blocked storage keeps the page working, unsaved. */\nexport function writeSessionsPageSettings(key: string, settings: SessionsPageSettings): void {\n try {\n const { search: _search, ...defaultQuery } = settings.defaultQuery ?? {};\n storage()?.setItem(\n STORAGE_PREFIX + key,\n JSON.stringify({\n defaultQuery: settings.defaultQuery ? defaultQuery : null,\n display: settings.display,\n }),\n );\n } catch {\n // Quota exceeded or storage disabled: nothing to do.\n }\n}\n"],"names":["DEFAULT_VISIBLE_SESSIONS_COLUMNS","SESSION_RUN_STATUSES","SESSION_SESSION_STATUSES","normalizeSessionsQuery","SESSIONS_COLUMNS"],"mappings":"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"}
1
+ {"version":3,"file":"sessions-page-storage.cjs","sources":["../../src/threads/sessions-page-storage.ts"],"sourcesContent":["/**\n * What `SessionsPage` remembers in this browser: the filters saved with\n * \"Save as default\" and the display options (grouping, columns). Per storage\n * key (a host with several pages names each); never a credential, never a\n * row. Unreadable or foreign values read as \"nothing saved\".\n */\nimport {\n type AthenaSessionsQuery,\n normalizeSessionsQuery,\n SESSION_RUN_STATUSES,\n SESSION_SESSION_STATUSES,\n} from './sessions-query';\nimport {\n DEFAULT_VISIBLE_SESSIONS_COLUMNS,\n SESSIONS_COLUMNS,\n type SessionsColumnId,\n type SessionsGroupBy,\n} from './sessions-page-model';\n\nexport interface SessionsPageDisplay {\n groupBy: SessionsGroupBy;\n columns: SessionsColumnId[];\n}\n\nexport interface SessionsPageSettings {\n /** The saved default filters and order (no search: a search is never a default). */\n defaultQuery: AthenaSessionsQuery | null;\n display: SessionsPageDisplay;\n}\n\nexport const DEFAULT_SESSIONS_PAGE_DISPLAY: SessionsPageDisplay = {\n groupBy: 'attention',\n columns: [...DEFAULT_VISIBLE_SESSIONS_COLUMNS],\n};\n\nconst STORAGE_PREFIX = 'athena-sdk:sessions-page:v1:';\n\nfunction storage(): Storage | null {\n try {\n return typeof window === 'undefined' ? null : window.localStorage;\n } catch {\n return null;\n }\n}\n\nconst isStringArray = (value: unknown): value is string[] =>\n Array.isArray(value) && value.every((item) => typeof item === 'string');\n\n/** Keep only the fields and values a query can carry. */\nexport function sanitizeSessionsQuery(value: unknown): AthenaSessionsQuery | null {\n if (!value || typeof value !== 'object' || Array.isArray(value)) return null;\n const record = value as Record<string, unknown>;\n const query: AthenaSessionsQuery = {};\n for (const field of ['collabAgentIds', 'collabChannelIds', 'startChannels'] as const) {\n if (isStringArray(record[field])) query[field] = record[field];\n }\n if (isStringArray(record.runStatuses)) {\n query.runStatuses = record.runStatuses.filter((status) =>\n (SESSION_RUN_STATUSES as readonly string[]).includes(status),\n ) as AthenaSessionsQuery['runStatuses'];\n }\n if (isStringArray(record.sessionStatuses)) {\n query.sessionStatuses = record.sessionStatuses.filter((status) =>\n (SESSION_SESSION_STATUSES as readonly string[]).includes(status),\n ) as AthenaSessionsQuery['sessionStatuses'];\n }\n for (const field of ['createdAfter', 'createdBefore', 'updatedAfter', 'updatedBefore'] as const) {\n if (typeof record[field] === 'string') query[field] = record[field];\n }\n for (const field of [\n 'favoritesOnly',\n 'unreadOnly',\n 'hasPullRequests',\n 'createdByMe',\n 'excludeDismissed',\n 'excludeTriggered',\n ] as const) {\n if (typeof record[field] === 'boolean') query[field] = record[field];\n }\n if (record.sort === 'updated' || record.sort === 'created') query.sort = record.sort;\n if (record.direction === 'desc' || record.direction === 'asc') query.direction = record.direction;\n return normalizeSessionsQuery(query);\n}\n\nfunction sanitizeDisplay(value: unknown, fallback: SessionsPageDisplay): SessionsPageDisplay {\n if (!value || typeof value !== 'object') return fallback;\n const record = value as Record<string, unknown>;\n const groupBy =\n record.groupBy === 'attention' || record.groupBy === 'status' || record.groupBy === 'none'\n ? record.groupBy\n : fallback.groupBy;\n const known = new Set<string>(SESSIONS_COLUMNS.map((column) => column.id));\n const columns = isStringArray(record.columns)\n ? (record.columns.filter((column) => known.has(column)) as SessionsColumnId[])\n : fallback.columns;\n return { groupBy, columns };\n}\n\n/**\n * What this browser remembers for `key`. `defaultDisplay` is the display when\n * nothing (or nothing readable) is remembered: the host's column defaults.\n */\nexport function readSessionsPageSettings(\n key: string,\n defaultDisplay: SessionsPageDisplay = DEFAULT_SESSIONS_PAGE_DISPLAY,\n): SessionsPageSettings {\n const raw = storage()?.getItem(STORAGE_PREFIX + key);\n if (!raw) return { defaultQuery: null, display: defaultDisplay };\n try {\n const parsed: unknown = JSON.parse(raw);\n const record = (parsed && typeof parsed === 'object' ? parsed : {}) as Record<string, unknown>;\n return {\n defaultQuery: sanitizeSessionsQuery(record.defaultQuery),\n display: sanitizeDisplay(record.display, defaultDisplay),\n };\n } catch {\n return { defaultQuery: null, display: defaultDisplay };\n }\n}\n\n/** Best effort: a full or blocked storage keeps the page working, unsaved. */\nexport function writeSessionsPageSettings(key: string, settings: SessionsPageSettings): void {\n try {\n const { search: _search, ...defaultQuery } = settings.defaultQuery ?? {};\n storage()?.setItem(\n STORAGE_PREFIX + key,\n JSON.stringify({\n defaultQuery: settings.defaultQuery ? defaultQuery : null,\n display: settings.display,\n }),\n );\n } catch {\n // Quota exceeded or storage disabled: nothing to do.\n }\n}\n"],"names":["DEFAULT_VISIBLE_SESSIONS_COLUMNS","SESSION_RUN_STATUSES","SESSION_SESSION_STATUSES","normalizeSessionsQuery","SESSIONS_COLUMNS"],"mappings":"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"}
@@ -18,6 +18,10 @@ export interface SessionsPageSettings {
18
18
  export declare const DEFAULT_SESSIONS_PAGE_DISPLAY: SessionsPageDisplay;
19
19
  /** Keep only the fields and values a query can carry. */
20
20
  export declare function sanitizeSessionsQuery(value: unknown): AthenaSessionsQuery | null;
21
- export declare function readSessionsPageSettings(key: string): SessionsPageSettings;
21
+ /**
22
+ * What this browser remembers for `key`. `defaultDisplay` is the display when
23
+ * nothing (or nothing readable) is remembered: the host's column defaults.
24
+ */
25
+ export declare function readSessionsPageSettings(key: string, defaultDisplay?: SessionsPageDisplay): SessionsPageSettings;
22
26
  /** Best effort: a full or blocked storage keeps the page working, unsaved. */
23
27
  export declare function writeSessionsPageSettings(key: string, settings: SessionsPageSettings): void;
@@ -47,27 +47,27 @@ function sanitizeSessionsQuery(value) {
47
47
  if (record.direction === "desc" || record.direction === "asc") query.direction = record.direction;
48
48
  return normalizeSessionsQuery(query);
49
49
  }
50
- function sanitizeDisplay(value) {
51
- if (!value || typeof value !== "object") return DEFAULT_SESSIONS_PAGE_DISPLAY;
50
+ function sanitizeDisplay(value, fallback) {
51
+ if (!value || typeof value !== "object") return fallback;
52
52
  const record = value;
53
- const groupBy = record.groupBy === "attention" || record.groupBy === "status" || record.groupBy === "none" ? record.groupBy : DEFAULT_SESSIONS_PAGE_DISPLAY.groupBy;
53
+ const groupBy = record.groupBy === "attention" || record.groupBy === "status" || record.groupBy === "none" ? record.groupBy : fallback.groupBy;
54
54
  const known = new Set(SESSIONS_COLUMNS.map((column) => column.id));
55
- const columns = isStringArray(record.columns) ? record.columns.filter((column) => known.has(column)) : DEFAULT_SESSIONS_PAGE_DISPLAY.columns;
55
+ const columns = isStringArray(record.columns) ? record.columns.filter((column) => known.has(column)) : fallback.columns;
56
56
  return { groupBy, columns };
57
57
  }
58
- function readSessionsPageSettings(key) {
58
+ function readSessionsPageSettings(key, defaultDisplay = DEFAULT_SESSIONS_PAGE_DISPLAY) {
59
59
  var _a;
60
60
  const raw = (_a = storage()) == null ? void 0 : _a.getItem(STORAGE_PREFIX + key);
61
- if (!raw) return { defaultQuery: null, display: DEFAULT_SESSIONS_PAGE_DISPLAY };
61
+ if (!raw) return { defaultQuery: null, display: defaultDisplay };
62
62
  try {
63
63
  const parsed = JSON.parse(raw);
64
64
  const record = parsed && typeof parsed === "object" ? parsed : {};
65
65
  return {
66
66
  defaultQuery: sanitizeSessionsQuery(record.defaultQuery),
67
- display: sanitizeDisplay(record.display)
67
+ display: sanitizeDisplay(record.display, defaultDisplay)
68
68
  };
69
69
  } catch {
70
- return { defaultQuery: null, display: DEFAULT_SESSIONS_PAGE_DISPLAY };
70
+ return { defaultQuery: null, display: defaultDisplay };
71
71
  }
72
72
  }
73
73
  function writeSessionsPageSettings(key, settings) {
@@ -1 +1 @@
1
- {"version":3,"file":"sessions-page-storage.js","sources":["../../src/threads/sessions-page-storage.ts"],"sourcesContent":["/**\n * What `SessionsPage` remembers in this browser: the filters saved with\n * \"Save as default\" and the display options (grouping, columns). Per storage\n * key (a host with several pages names each); never a credential, never a\n * row. Unreadable or foreign values read as \"nothing saved\".\n */\nimport {\n type AthenaSessionsQuery,\n normalizeSessionsQuery,\n SESSION_RUN_STATUSES,\n SESSION_SESSION_STATUSES,\n} from './sessions-query';\nimport {\n DEFAULT_VISIBLE_SESSIONS_COLUMNS,\n SESSIONS_COLUMNS,\n type SessionsColumnId,\n type SessionsGroupBy,\n} from './sessions-page-model';\n\nexport interface SessionsPageDisplay {\n groupBy: SessionsGroupBy;\n columns: SessionsColumnId[];\n}\n\nexport interface SessionsPageSettings {\n /** The saved default filters and order (no search: a search is never a default). */\n defaultQuery: AthenaSessionsQuery | null;\n display: SessionsPageDisplay;\n}\n\nexport const DEFAULT_SESSIONS_PAGE_DISPLAY: SessionsPageDisplay = {\n groupBy: 'attention',\n columns: [...DEFAULT_VISIBLE_SESSIONS_COLUMNS],\n};\n\nconst STORAGE_PREFIX = 'athena-sdk:sessions-page:v1:';\n\nfunction storage(): Storage | null {\n try {\n return typeof window === 'undefined' ? null : window.localStorage;\n } catch {\n return null;\n }\n}\n\nconst isStringArray = (value: unknown): value is string[] =>\n Array.isArray(value) && value.every((item) => typeof item === 'string');\n\n/** Keep only the fields and values a query can carry. */\nexport function sanitizeSessionsQuery(value: unknown): AthenaSessionsQuery | null {\n if (!value || typeof value !== 'object' || Array.isArray(value)) return null;\n const record = value as Record<string, unknown>;\n const query: AthenaSessionsQuery = {};\n for (const field of ['collabAgentIds', 'collabChannelIds', 'startChannels'] as const) {\n if (isStringArray(record[field])) query[field] = record[field];\n }\n if (isStringArray(record.runStatuses)) {\n query.runStatuses = record.runStatuses.filter((status) =>\n (SESSION_RUN_STATUSES as readonly string[]).includes(status),\n ) as AthenaSessionsQuery['runStatuses'];\n }\n if (isStringArray(record.sessionStatuses)) {\n query.sessionStatuses = record.sessionStatuses.filter((status) =>\n (SESSION_SESSION_STATUSES as readonly string[]).includes(status),\n ) as AthenaSessionsQuery['sessionStatuses'];\n }\n for (const field of ['createdAfter', 'createdBefore', 'updatedAfter', 'updatedBefore'] as const) {\n if (typeof record[field] === 'string') query[field] = record[field];\n }\n for (const field of [\n 'favoritesOnly',\n 'unreadOnly',\n 'hasPullRequests',\n 'createdByMe',\n 'excludeDismissed',\n 'excludeTriggered',\n ] as const) {\n if (typeof record[field] === 'boolean') query[field] = record[field];\n }\n if (record.sort === 'updated' || record.sort === 'created') query.sort = record.sort;\n if (record.direction === 'desc' || record.direction === 'asc') query.direction = record.direction;\n return normalizeSessionsQuery(query);\n}\n\nfunction sanitizeDisplay(value: unknown): SessionsPageDisplay {\n if (!value || typeof value !== 'object') return DEFAULT_SESSIONS_PAGE_DISPLAY;\n const record = value as Record<string, unknown>;\n const groupBy =\n record.groupBy === 'attention' || record.groupBy === 'status' || record.groupBy === 'none'\n ? record.groupBy\n : DEFAULT_SESSIONS_PAGE_DISPLAY.groupBy;\n const known = new Set<string>(SESSIONS_COLUMNS.map((column) => column.id));\n const columns = isStringArray(record.columns)\n ? (record.columns.filter((column) => known.has(column)) as SessionsColumnId[])\n : DEFAULT_SESSIONS_PAGE_DISPLAY.columns;\n return { groupBy, columns };\n}\n\nexport function readSessionsPageSettings(key: string): SessionsPageSettings {\n const raw = storage()?.getItem(STORAGE_PREFIX + key);\n if (!raw) return { defaultQuery: null, display: DEFAULT_SESSIONS_PAGE_DISPLAY };\n try {\n const parsed: unknown = JSON.parse(raw);\n const record = (parsed && typeof parsed === 'object' ? parsed : {}) as Record<string, unknown>;\n return {\n defaultQuery: sanitizeSessionsQuery(record.defaultQuery),\n display: sanitizeDisplay(record.display),\n };\n } catch {\n return { defaultQuery: null, display: DEFAULT_SESSIONS_PAGE_DISPLAY };\n }\n}\n\n/** Best effort: a full or blocked storage keeps the page working, unsaved. */\nexport function writeSessionsPageSettings(key: string, settings: SessionsPageSettings): void {\n try {\n const { search: _search, ...defaultQuery } = settings.defaultQuery ?? {};\n storage()?.setItem(\n STORAGE_PREFIX + key,\n JSON.stringify({\n defaultQuery: settings.defaultQuery ? defaultQuery : null,\n display: settings.display,\n }),\n );\n } catch {\n // Quota exceeded or storage disabled: nothing to do.\n }\n}\n"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"sessions-page-storage.js","sources":["../../src/threads/sessions-page-storage.ts"],"sourcesContent":["/**\n * What `SessionsPage` remembers in this browser: the filters saved with\n * \"Save as default\" and the display options (grouping, columns). Per storage\n * key (a host with several pages names each); never a credential, never a\n * row. Unreadable or foreign values read as \"nothing saved\".\n */\nimport {\n type AthenaSessionsQuery,\n normalizeSessionsQuery,\n SESSION_RUN_STATUSES,\n SESSION_SESSION_STATUSES,\n} from './sessions-query';\nimport {\n DEFAULT_VISIBLE_SESSIONS_COLUMNS,\n SESSIONS_COLUMNS,\n type SessionsColumnId,\n type SessionsGroupBy,\n} from './sessions-page-model';\n\nexport interface SessionsPageDisplay {\n groupBy: SessionsGroupBy;\n columns: SessionsColumnId[];\n}\n\nexport interface SessionsPageSettings {\n /** The saved default filters and order (no search: a search is never a default). */\n defaultQuery: AthenaSessionsQuery | null;\n display: SessionsPageDisplay;\n}\n\nexport const DEFAULT_SESSIONS_PAGE_DISPLAY: SessionsPageDisplay = {\n groupBy: 'attention',\n columns: [...DEFAULT_VISIBLE_SESSIONS_COLUMNS],\n};\n\nconst STORAGE_PREFIX = 'athena-sdk:sessions-page:v1:';\n\nfunction storage(): Storage | null {\n try {\n return typeof window === 'undefined' ? null : window.localStorage;\n } catch {\n return null;\n }\n}\n\nconst isStringArray = (value: unknown): value is string[] =>\n Array.isArray(value) && value.every((item) => typeof item === 'string');\n\n/** Keep only the fields and values a query can carry. */\nexport function sanitizeSessionsQuery(value: unknown): AthenaSessionsQuery | null {\n if (!value || typeof value !== 'object' || Array.isArray(value)) return null;\n const record = value as Record<string, unknown>;\n const query: AthenaSessionsQuery = {};\n for (const field of ['collabAgentIds', 'collabChannelIds', 'startChannels'] as const) {\n if (isStringArray(record[field])) query[field] = record[field];\n }\n if (isStringArray(record.runStatuses)) {\n query.runStatuses = record.runStatuses.filter((status) =>\n (SESSION_RUN_STATUSES as readonly string[]).includes(status),\n ) as AthenaSessionsQuery['runStatuses'];\n }\n if (isStringArray(record.sessionStatuses)) {\n query.sessionStatuses = record.sessionStatuses.filter((status) =>\n (SESSION_SESSION_STATUSES as readonly string[]).includes(status),\n ) as AthenaSessionsQuery['sessionStatuses'];\n }\n for (const field of ['createdAfter', 'createdBefore', 'updatedAfter', 'updatedBefore'] as const) {\n if (typeof record[field] === 'string') query[field] = record[field];\n }\n for (const field of [\n 'favoritesOnly',\n 'unreadOnly',\n 'hasPullRequests',\n 'createdByMe',\n 'excludeDismissed',\n 'excludeTriggered',\n ] as const) {\n if (typeof record[field] === 'boolean') query[field] = record[field];\n }\n if (record.sort === 'updated' || record.sort === 'created') query.sort = record.sort;\n if (record.direction === 'desc' || record.direction === 'asc') query.direction = record.direction;\n return normalizeSessionsQuery(query);\n}\n\nfunction sanitizeDisplay(value: unknown, fallback: SessionsPageDisplay): SessionsPageDisplay {\n if (!value || typeof value !== 'object') return fallback;\n const record = value as Record<string, unknown>;\n const groupBy =\n record.groupBy === 'attention' || record.groupBy === 'status' || record.groupBy === 'none'\n ? record.groupBy\n : fallback.groupBy;\n const known = new Set<string>(SESSIONS_COLUMNS.map((column) => column.id));\n const columns = isStringArray(record.columns)\n ? (record.columns.filter((column) => known.has(column)) as SessionsColumnId[])\n : fallback.columns;\n return { groupBy, columns };\n}\n\n/**\n * What this browser remembers for `key`. `defaultDisplay` is the display when\n * nothing (or nothing readable) is remembered: the host's column defaults.\n */\nexport function readSessionsPageSettings(\n key: string,\n defaultDisplay: SessionsPageDisplay = DEFAULT_SESSIONS_PAGE_DISPLAY,\n): SessionsPageSettings {\n const raw = storage()?.getItem(STORAGE_PREFIX + key);\n if (!raw) return { defaultQuery: null, display: defaultDisplay };\n try {\n const parsed: unknown = JSON.parse(raw);\n const record = (parsed && typeof parsed === 'object' ? parsed : {}) as Record<string, unknown>;\n return {\n defaultQuery: sanitizeSessionsQuery(record.defaultQuery),\n display: sanitizeDisplay(record.display, defaultDisplay),\n };\n } catch {\n return { defaultQuery: null, display: defaultDisplay };\n }\n}\n\n/** Best effort: a full or blocked storage keeps the page working, unsaved. */\nexport function writeSessionsPageSettings(key: string, settings: SessionsPageSettings): void {\n try {\n const { search: _search, ...defaultQuery } = settings.defaultQuery ?? {};\n storage()?.setItem(\n STORAGE_PREFIX + key,\n JSON.stringify({\n defaultQuery: settings.defaultQuery ? defaultQuery : null,\n display: settings.display,\n }),\n );\n } catch {\n // Quota exceeded or storage disabled: nothing to do.\n }\n}\n"],"names":[],"mappings":"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"}