@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.
- package/README.md +778 -9
- package/dist/agent-runtime/src/addressed-agents.cjs +16 -0
- package/dist/agent-runtime/src/addressed-agents.cjs.map +1 -0
- package/dist/agent-runtime/src/addressed-agents.d.ts +30 -0
- package/dist/agent-runtime/src/addressed-agents.js +16 -0
- package/dist/agent-runtime/src/addressed-agents.js.map +1 -0
- package/dist/agent-runtime/src/answer-label.cjs +4 -3
- package/dist/agent-runtime/src/answer-label.cjs.map +1 -1
- package/dist/agent-runtime/src/answer-label.d.ts +13 -6
- package/dist/agent-runtime/src/answer-label.js +4 -3
- package/dist/agent-runtime/src/answer-label.js.map +1 -1
- package/dist/agent-runtime/src/chat-outbox-attachments.cjs.map +1 -1
- package/dist/agent-runtime/src/chat-outbox-attachments.d.ts +1 -1
- package/dist/agent-runtime/src/chat-outbox-attachments.js.map +1 -1
- package/dist/agent-runtime/src/chat-outbox-entry.cjs +101 -0
- package/dist/agent-runtime/src/chat-outbox-entry.cjs.map +1 -0
- package/dist/agent-runtime/src/chat-outbox-entry.d.ts +99 -0
- package/dist/agent-runtime/src/chat-outbox-entry.js +101 -0
- package/dist/agent-runtime/src/chat-outbox-entry.js.map +1 -0
- package/dist/agent-runtime/src/chat-outbox-legacy.cjs +252 -0
- package/dist/agent-runtime/src/chat-outbox-legacy.cjs.map +1 -0
- package/dist/agent-runtime/src/chat-outbox-legacy.d.ts +96 -0
- package/dist/agent-runtime/src/chat-outbox-legacy.js +252 -0
- package/dist/agent-runtime/src/chat-outbox-legacy.js.map +1 -0
- package/dist/agent-runtime/src/chat-outbox-policy.cjs +30 -0
- package/dist/agent-runtime/src/chat-outbox-policy.cjs.map +1 -0
- package/dist/agent-runtime/src/chat-outbox-policy.d.ts +42 -0
- package/dist/agent-runtime/src/chat-outbox-policy.js +30 -0
- package/dist/agent-runtime/src/chat-outbox-policy.js.map +1 -0
- package/dist/agent-runtime/src/chat-outbox-storage.cjs +306 -0
- package/dist/agent-runtime/src/chat-outbox-storage.cjs.map +1 -0
- package/dist/agent-runtime/src/chat-outbox-storage.d.ts +194 -0
- package/dist/agent-runtime/src/chat-outbox-storage.js +306 -0
- package/dist/agent-runtime/src/chat-outbox-storage.js.map +1 -0
- package/dist/agent-runtime/src/chat-outbox-thread.cjs +21 -94
- package/dist/agent-runtime/src/chat-outbox-thread.cjs.map +1 -1
- package/dist/agent-runtime/src/chat-outbox-thread.d.ts +22 -18
- package/dist/agent-runtime/src/chat-outbox-thread.js +21 -94
- package/dist/agent-runtime/src/chat-outbox-thread.js.map +1 -1
- package/dist/agent-runtime/src/chat-outbox.cjs +492 -547
- package/dist/agent-runtime/src/chat-outbox.cjs.map +1 -1
- package/dist/agent-runtime/src/chat-outbox.d.ts +110 -142
- package/dist/agent-runtime/src/chat-outbox.js +492 -547
- package/dist/agent-runtime/src/chat-outbox.js.map +1 -1
- package/dist/agent-runtime/src/composer-markdown.cjs.map +1 -1
- package/dist/agent-runtime/src/composer-markdown.d.ts +1 -1
- package/dist/agent-runtime/src/composer-markdown.js.map +1 -1
- package/dist/agent-runtime/src/deep-agent-transport-recipe.cjs +3 -1
- package/dist/agent-runtime/src/deep-agent-transport-recipe.cjs.map +1 -1
- package/dist/agent-runtime/src/deep-agent-transport-recipe.d.ts +8 -1
- package/dist/agent-runtime/src/deep-agent-transport-recipe.js +3 -1
- package/dist/agent-runtime/src/deep-agent-transport-recipe.js.map +1 -1
- package/dist/agent-runtime/src/dictation-preferences.d.ts +356 -0
- package/dist/agent-runtime/src/dictation-record.d.ts +279 -0
- package/dist/agent-runtime/src/dictation-session.d.ts +106 -7
- package/dist/agent-runtime/src/dictation-snippets.d.ts +9 -0
- package/dist/agent-runtime/src/dictation-transfer.d.ts +142 -0
- package/dist/agent-runtime/src/edit-command.cjs.map +1 -1
- package/dist/agent-runtime/src/edit-command.d.ts +1 -1
- package/dist/agent-runtime/src/edit-command.js.map +1 -1
- package/dist/agent-runtime/src/errors.cjs +1 -0
- package/dist/agent-runtime/src/errors.cjs.map +1 -1
- package/dist/agent-runtime/src/errors.js +1 -0
- package/dist/agent-runtime/src/errors.js.map +1 -1
- package/dist/agent-runtime/src/generated/runconfig-contract.cjs +24 -0
- package/dist/agent-runtime/src/generated/runconfig-contract.cjs.map +1 -1
- package/dist/agent-runtime/src/generated/runconfig-contract.d.ts +3 -3
- package/dist/agent-runtime/src/generated/runconfig-contract.js +24 -0
- package/dist/agent-runtime/src/generated/runconfig-contract.js.map +1 -1
- package/dist/agent-runtime/src/index.d.ts +14 -8
- package/dist/agent-runtime/src/lane-follow.cjs +289 -0
- package/dist/agent-runtime/src/lane-follow.cjs.map +1 -0
- package/dist/agent-runtime/src/lane-follow.js +289 -0
- package/dist/agent-runtime/src/lane-follow.js.map +1 -0
- package/dist/agent-runtime/src/lane-images.cjs +387 -0
- package/dist/agent-runtime/src/lane-images.cjs.map +1 -0
- package/dist/agent-runtime/src/lane-images.js +387 -0
- package/dist/agent-runtime/src/lane-images.js.map +1 -0
- package/dist/agent-runtime/src/message-window.js +1 -1
- package/dist/agent-runtime/src/messages.cjs +19 -1
- package/dist/agent-runtime/src/messages.cjs.map +1 -1
- package/dist/agent-runtime/src/messages.d.ts +8 -0
- package/dist/agent-runtime/src/messages.js +21 -3
- package/dist/agent-runtime/src/messages.js.map +1 -1
- package/dist/agent-runtime/src/named-agents.cjs +301 -0
- package/dist/agent-runtime/src/named-agents.cjs.map +1 -0
- package/dist/agent-runtime/src/named-agents.d.ts +246 -0
- package/dist/agent-runtime/src/named-agents.js +301 -0
- package/dist/agent-runtime/src/named-agents.js.map +1 -0
- package/dist/agent-runtime/src/offline-status.cjs.map +1 -1
- package/dist/agent-runtime/src/offline-status.d.ts +66 -2
- package/dist/agent-runtime/src/offline-status.js.map +1 -1
- package/dist/agent-runtime/src/ptc-subcalls.cjs +41 -0
- package/dist/agent-runtime/src/ptc-subcalls.cjs.map +1 -0
- package/dist/agent-runtime/src/ptc-subcalls.js +41 -0
- package/dist/agent-runtime/src/ptc-subcalls.js.map +1 -0
- package/dist/agent-runtime/src/queue.cjs +2 -2
- package/dist/agent-runtime/src/queue.cjs.map +1 -1
- package/dist/agent-runtime/src/queue.d.ts +20 -25
- package/dist/agent-runtime/src/queue.js +2 -2
- package/dist/agent-runtime/src/queue.js.map +1 -1
- package/dist/agent-runtime/src/quota-safe-local-storage-session.cjs +314 -84
- package/dist/agent-runtime/src/quota-safe-local-storage-session.cjs.map +1 -1
- package/dist/agent-runtime/src/quota-safe-local-storage-session.d.ts +137 -40
- package/dist/agent-runtime/src/quota-safe-local-storage-session.js +318 -88
- package/dist/agent-runtime/src/quota-safe-local-storage-session.js.map +1 -1
- package/dist/agent-runtime/src/run-send.cjs +54 -0
- package/dist/agent-runtime/src/run-send.cjs.map +1 -0
- package/dist/agent-runtime/src/run-send.d.ts +51 -0
- package/dist/agent-runtime/src/run-send.js +54 -0
- package/dist/agent-runtime/src/run-send.js.map +1 -0
- package/dist/agent-runtime/src/running-tool-placeholder.cjs +6 -0
- package/dist/agent-runtime/src/running-tool-placeholder.cjs.map +1 -1
- package/dist/agent-runtime/src/running-tool-placeholder.js +6 -0
- package/dist/agent-runtime/src/running-tool-placeholder.js.map +1 -1
- package/dist/agent-runtime/src/runtime.d.ts +9 -5
- package/dist/agent-runtime/src/sealed-idb.cjs +64 -0
- package/dist/agent-runtime/src/sealed-idb.cjs.map +1 -1
- package/dist/agent-runtime/src/sealed-idb.d.ts +16 -0
- package/dist/agent-runtime/src/sealed-idb.js +64 -0
- package/dist/agent-runtime/src/sealed-idb.js.map +1 -1
- package/dist/agent-runtime/src/send-recovery.cjs +90 -118
- package/dist/agent-runtime/src/send-recovery.cjs.map +1 -1
- package/dist/agent-runtime/src/send-recovery.d.ts +25 -29
- package/dist/agent-runtime/src/send-recovery.js +90 -118
- package/dist/agent-runtime/src/send-recovery.js.map +1 -1
- package/dist/agent-runtime/src/statewire-diagnostics.d.ts +4 -1
- package/dist/agent-runtime/src/statewire-held-sends.cjs +191 -0
- package/dist/agent-runtime/src/statewire-held-sends.cjs.map +1 -0
- package/dist/agent-runtime/src/statewire-held-sends.d.ts +119 -0
- package/dist/agent-runtime/src/statewire-held-sends.js +191 -0
- package/dist/agent-runtime/src/statewire-held-sends.js.map +1 -0
- package/dist/agent-runtime/src/statewire-state.cjs +4 -0
- package/dist/agent-runtime/src/statewire-state.cjs.map +1 -1
- package/dist/agent-runtime/src/statewire-state.js +4 -0
- package/dist/agent-runtime/src/statewire-state.js.map +1 -1
- package/dist/agent-runtime/src/statewire-transport.cjs +8 -2
- package/dist/agent-runtime/src/statewire-transport.cjs.map +1 -1
- package/dist/agent-runtime/src/statewire-transport.d.ts +14 -5
- package/dist/agent-runtime/src/statewire-transport.js +8 -2
- package/dist/agent-runtime/src/statewire-transport.js.map +1 -1
- package/dist/agent-runtime/src/subagent-transcripts.cjs +1 -23
- package/dist/agent-runtime/src/subagent-transcripts.cjs.map +1 -1
- package/dist/agent-runtime/src/subagent-transcripts.js +3 -25
- package/dist/agent-runtime/src/subagent-transcripts.js.map +1 -1
- package/dist/agent-runtime/src/subagents.cjs +22 -29
- package/dist/agent-runtime/src/subagents.cjs.map +1 -1
- package/dist/agent-runtime/src/subagents.js +23 -30
- package/dist/agent-runtime/src/subagents.js.map +1 -1
- package/dist/agent-runtime/src/thread-extras.cjs +27 -19
- package/dist/agent-runtime/src/thread-extras.cjs.map +1 -1
- package/dist/agent-runtime/src/thread-extras.d.ts +19 -6
- package/dist/agent-runtime/src/thread-extras.js +27 -19
- package/dist/agent-runtime/src/thread-extras.js.map +1 -1
- package/dist/agent-runtime/src/thread-handoff-flow-machine.d.ts +8 -8
- package/dist/agent-runtime/src/tool-metadata.cjs +12 -0
- package/dist/agent-runtime/src/tool-metadata.cjs.map +1 -1
- package/dist/agent-runtime/src/tool-metadata.js +12 -0
- package/dist/agent-runtime/src/tool-metadata.js.map +1 -1
- package/dist/agent-runtime/src/tool-names.cjs +21 -0
- package/dist/agent-runtime/src/tool-names.cjs.map +1 -1
- package/dist/agent-runtime/src/tool-names.d.ts +8 -0
- package/dist/agent-runtime/src/tool-names.js +21 -0
- package/dist/agent-runtime/src/tool-names.js.map +1 -1
- package/dist/agent-runtime/src/typed-interrupt-kinds.cjs +247 -0
- package/dist/agent-runtime/src/typed-interrupt-kinds.cjs.map +1 -0
- package/dist/agent-runtime/src/typed-interrupt-kinds.d.ts +173 -0
- package/dist/agent-runtime/src/typed-interrupt-kinds.js +247 -0
- package/dist/agent-runtime/src/typed-interrupt-kinds.js.map +1 -0
- package/dist/agent-runtime/src/typed-interrupts.cjs +48 -0
- package/dist/agent-runtime/src/typed-interrupts.cjs.map +1 -0
- package/dist/agent-runtime/src/typed-interrupts.d.ts +75 -0
- package/dist/agent-runtime/src/typed-interrupts.js +48 -0
- package/dist/agent-runtime/src/typed-interrupts.js.map +1 -0
- package/dist/agent-runtime/src/types.d.ts +1 -1
- package/dist/agent-runtime/src/use-conversation-list.cjs +1 -0
- package/dist/agent-runtime/src/use-conversation-list.cjs.map +1 -1
- package/dist/agent-runtime/src/use-conversation-list.d.ts +7 -0
- package/dist/agent-runtime/src/use-conversation-list.js +1 -0
- package/dist/agent-runtime/src/use-conversation-list.js.map +1 -1
- package/dist/agent-runtime/src/use-deep-agent-chat-outbox.cjs +46 -29
- package/dist/agent-runtime/src/use-deep-agent-chat-outbox.cjs.map +1 -1
- package/dist/agent-runtime/src/use-deep-agent-chat-outbox.d.ts +14 -22
- package/dist/agent-runtime/src/use-deep-agent-chat-outbox.js +46 -29
- package/dist/agent-runtime/src/use-deep-agent-chat-outbox.js.map +1 -1
- package/dist/agent-runtime/src/use-deep-agent-runtime.cjs +78 -14
- package/dist/agent-runtime/src/use-deep-agent-runtime.cjs.map +1 -1
- package/dist/agent-runtime/src/use-deep-agent-runtime.d.ts +34 -7
- package/dist/agent-runtime/src/use-deep-agent-runtime.js +79 -15
- package/dist/agent-runtime/src/use-deep-agent-runtime.js.map +1 -1
- package/dist/agent-runtime/src/use-deep-agent-thread.cjs +16 -1
- package/dist/agent-runtime/src/use-deep-agent-thread.cjs.map +1 -1
- package/dist/agent-runtime/src/use-deep-agent-thread.d.ts +7 -2
- package/dist/agent-runtime/src/use-deep-agent-thread.js +16 -1
- package/dist/agent-runtime/src/use-deep-agent-thread.js.map +1 -1
- package/dist/agent-runtime/src/use-deep-agent-voice.cjs +30 -4
- package/dist/agent-runtime/src/use-deep-agent-voice.cjs.map +1 -1
- package/dist/agent-runtime/src/use-deep-agent-voice.d.ts +22 -4
- package/dist/agent-runtime/src/use-deep-agent-voice.js +30 -4
- package/dist/agent-runtime/src/use-deep-agent-voice.js.map +1 -1
- package/dist/agent-runtime/src/withdrawn-turns.d.ts +5 -4
- package/dist/agent-runtime/src/word-device-fit.d.ts +174 -0
- package/dist/agent-runtime/src/work-in.d.ts +127 -0
- package/dist/assets/AthenaAssetEmbed.cjs.map +1 -1
- package/dist/assets/AthenaAssetEmbed.d.ts +6 -1
- package/dist/assets/AthenaAssetEmbed.js.map +1 -1
- package/dist/assets/asset-panel-store.cjs +13 -5
- package/dist/assets/asset-panel-store.cjs.map +1 -1
- package/dist/assets/asset-panel-store.d.ts +33 -2
- package/dist/assets/asset-panel-store.js +13 -5
- package/dist/assets/asset-panel-store.js.map +1 -1
- package/dist/auth/AthenaCredentialSourceContext.cjs +11 -0
- package/dist/auth/AthenaCredentialSourceContext.cjs.map +1 -1
- package/dist/auth/AthenaCredentialSourceContext.d.ts +6 -0
- package/dist/auth/AthenaCredentialSourceContext.js +11 -0
- package/dist/auth/AthenaCredentialSourceContext.js.map +1 -1
- package/dist/auth/account-identity.cjs +13 -2
- package/dist/auth/account-identity.cjs.map +1 -1
- package/dist/auth/account-identity.d.ts +9 -0
- package/dist/auth/account-identity.js +13 -2
- package/dist/auth/account-identity.js.map +1 -1
- package/dist/auth/credential-source.cjs +20 -4
- package/dist/auth/credential-source.cjs.map +1 -1
- package/dist/auth/credential-source.d.ts +9 -0
- package/dist/auth/credential-source.js +20 -4
- package/dist/auth/credential-source.js.map +1 -1
- package/dist/catalog/chat-pickers.cjs +31 -0
- package/dist/catalog/chat-pickers.cjs.map +1 -1
- package/dist/catalog/chat-pickers.d.ts +17 -0
- package/dist/catalog/chat-pickers.js +33 -2
- package/dist/catalog/chat-pickers.js.map +1 -1
- package/dist/catalog/runtime-catalog.cjs +63 -3
- package/dist/catalog/runtime-catalog.cjs.map +1 -1
- package/dist/catalog/runtime-catalog.d.ts +63 -3
- package/dist/catalog/runtime-catalog.js +64 -4
- package/dist/catalog/runtime-catalog.js.map +1 -1
- package/dist/chat/AthenaChat.cjs +337 -99
- package/dist/chat/AthenaChat.cjs.map +1 -1
- package/dist/chat/AthenaChat.d.ts +80 -4
- package/dist/chat/AthenaChat.js +337 -99
- package/dist/chat/AthenaChat.js.map +1 -1
- package/dist/chat/StatewireApprovalCard.cjs +35 -5
- package/dist/chat/StatewireApprovalCard.cjs.map +1 -1
- package/dist/chat/StatewireApprovalCard.d.ts +55 -2
- package/dist/chat/StatewireApprovalCard.js +37 -7
- package/dist/chat/StatewireApprovalCard.js.map +1 -1
- package/dist/chat/StatewireQueuedMessages.cjs +17 -2
- package/dist/chat/StatewireQueuedMessages.cjs.map +1 -1
- package/dist/chat/StatewireQueuedMessages.d.ts +8 -45
- package/dist/chat/StatewireQueuedMessages.js +18 -3
- package/dist/chat/StatewireQueuedMessages.js.map +1 -1
- package/dist/chat/chat-agent-mentions.cjs +70 -0
- package/dist/chat/chat-agent-mentions.cjs.map +1 -0
- package/dist/chat/chat-agent-mentions.d.ts +13 -0
- package/dist/chat/chat-agent-mentions.js +70 -0
- package/dist/chat/chat-agent-mentions.js.map +1 -0
- package/dist/chat/composer-actions.cjs +12 -0
- package/dist/chat/composer-actions.cjs.map +1 -0
- package/dist/chat/composer-actions.d.ts +22 -0
- package/dist/chat/composer-actions.js +12 -0
- package/dist/chat/composer-actions.js.map +1 -0
- package/dist/chat/follow-up-suggestions.cjs +185 -0
- package/dist/chat/follow-up-suggestions.cjs.map +1 -0
- package/dist/chat/follow-up-suggestions.d.ts +64 -0
- package/dist/chat/follow-up-suggestions.js +185 -0
- package/dist/chat/follow-up-suggestions.js.map +1 -0
- package/dist/chat/super-grouping/ToolTimeline.cjs +4 -3
- package/dist/chat/super-grouping/ToolTimeline.cjs.map +1 -1
- package/dist/chat/super-grouping/ToolTimeline.d.ts +7 -3
- package/dist/chat/super-grouping/ToolTimeline.js +4 -3
- package/dist/chat/super-grouping/ToolTimeline.js.map +1 -1
- package/dist/chat/turn-changes.cjs +284 -0
- package/dist/chat/turn-changes.cjs.map +1 -0
- package/dist/chat/turn-changes.d.ts +130 -0
- package/dist/chat/turn-changes.js +284 -0
- package/dist/chat/turn-changes.js.map +1 -0
- package/dist/chat/typed-interrupts/StatewireTypedInterruptCard.cjs +31 -0
- package/dist/chat/typed-interrupts/StatewireTypedInterruptCard.cjs.map +1 -0
- package/dist/chat/typed-interrupts/StatewireTypedInterruptCard.d.ts +31 -0
- package/dist/chat/typed-interrupts/StatewireTypedInterruptCard.js +31 -0
- package/dist/chat/typed-interrupts/StatewireTypedInterruptCard.js.map +1 -0
- package/dist/chat/typed-interrupts/approval-cards.cjs +250 -0
- package/dist/chat/typed-interrupts/approval-cards.cjs.map +1 -0
- package/dist/chat/typed-interrupts/approval-cards.d.ts +22 -0
- package/dist/chat/typed-interrupts/approval-cards.js +250 -0
- package/dist/chat/typed-interrupts/approval-cards.js.map +1 -0
- package/dist/chat/typed-interrupts/form-cards.cjs +289 -0
- package/dist/chat/typed-interrupts/form-cards.cjs.map +1 -0
- package/dist/chat/typed-interrupts/form-cards.d.ts +6 -0
- package/dist/chat/typed-interrupts/form-cards.js +289 -0
- package/dist/chat/typed-interrupts/form-cards.js.map +1 -0
- package/dist/chat/typed-interrupts/interrupt-card-shell.cjs +182 -0
- package/dist/chat/typed-interrupts/interrupt-card-shell.cjs.map +1 -0
- package/dist/chat/typed-interrupts/interrupt-card-shell.d.ts +47 -0
- package/dist/chat/typed-interrupts/interrupt-card-shell.js +182 -0
- package/dist/chat/typed-interrupts/interrupt-card-shell.js.map +1 -0
- package/dist/chat/typed-interrupts/json-schema-form.cjs +388 -0
- package/dist/chat/typed-interrupts/json-schema-form.cjs.map +1 -0
- package/dist/chat/typed-interrupts/json-schema-form.d.ts +33 -0
- package/dist/chat/typed-interrupts/json-schema-form.js +388 -0
- package/dist/chat/typed-interrupts/json-schema-form.js.map +1 -0
- package/dist/chat/typed-interrupts/questionnaire-card.cjs +449 -0
- package/dist/chat/typed-interrupts/questionnaire-card.cjs.map +1 -0
- package/dist/chat/typed-interrupts/questionnaire-card.d.ts +20 -0
- package/dist/chat/typed-interrupts/questionnaire-card.js +449 -0
- package/dist/chat/typed-interrupts/questionnaire-card.js.map +1 -0
- package/dist/chat/typed-interrupts/request-file-card.cjs +159 -0
- package/dist/chat/typed-interrupts/request-file-card.cjs.map +1 -0
- package/dist/chat/typed-interrupts/request-file-card.d.ts +2 -0
- package/dist/chat/typed-interrupts/request-file-card.js +159 -0
- package/dist/chat/typed-interrupts/request-file-card.js.map +1 -0
- package/dist/chat/typed-interrupts/toolkit-selection-card.cjs +189 -0
- package/dist/chat/typed-interrupts/toolkit-selection-card.cjs.map +1 -0
- package/dist/chat/typed-interrupts/toolkit-selection-card.d.ts +23 -0
- package/dist/chat/typed-interrupts/toolkit-selection-card.js +189 -0
- package/dist/chat/typed-interrupts/toolkit-selection-card.js.map +1 -0
- package/dist/chat/typed-interrupts/typed-interrupt-body.cjs +26 -0
- package/dist/chat/typed-interrupts/typed-interrupt-body.cjs.map +1 -0
- package/dist/chat/typed-interrupts/typed-interrupt-body.d.ts +3 -0
- package/dist/chat/typed-interrupts/typed-interrupt-body.js +26 -0
- package/dist/chat/typed-interrupts/typed-interrupt-body.js.map +1 -0
- package/dist/chat/typed-interrupts/typed-interrupt-graphql.cjs +105 -0
- package/dist/chat/typed-interrupts/typed-interrupt-graphql.cjs.map +1 -0
- package/dist/chat/typed-interrupts/typed-interrupt-graphql.d.ts +29 -0
- package/dist/chat/typed-interrupts/typed-interrupt-graphql.js +105 -0
- package/dist/chat/typed-interrupts/typed-interrupt-graphql.js.map +1 -0
- package/dist/chat/typed-interrupts/typed-interrupt-notice.cjs +70 -0
- package/dist/chat/typed-interrupts/typed-interrupt-notice.cjs.map +1 -0
- package/dist/chat/typed-interrupts/typed-interrupt-notice.d.ts +45 -0
- package/dist/chat/typed-interrupts/typed-interrupt-notice.js +70 -0
- package/dist/chat/typed-interrupts/typed-interrupt-notice.js.map +1 -0
- package/dist/chat/typed-interrupts/typed-interrupt-panel.cjs +76 -0
- package/dist/chat/typed-interrupts/typed-interrupt-panel.cjs.map +1 -0
- package/dist/chat/typed-interrupts/typed-interrupt-panel.d.ts +11 -0
- package/dist/chat/typed-interrupts/typed-interrupt-panel.js +76 -0
- package/dist/chat/typed-interrupts/typed-interrupt-panel.js.map +1 -0
- package/dist/chat/typed-interrupts/typed-interrupt-types.d.ts +46 -0
- package/dist/chat/typed-interrupts/use-interrupt-draft.cjs +106 -0
- package/dist/chat/typed-interrupts/use-interrupt-draft.cjs.map +1 -0
- package/dist/chat/typed-interrupts/use-interrupt-draft.d.ts +29 -0
- package/dist/chat/typed-interrupts/use-interrupt-draft.js +106 -0
- package/dist/chat/typed-interrupts/use-interrupt-draft.js.map +1 -0
- package/dist/chat/typed-interrupts/use-statewire-typed-interrupt.cjs +231 -0
- package/dist/chat/typed-interrupts/use-statewire-typed-interrupt.cjs.map +1 -0
- package/dist/chat/typed-interrupts/use-statewire-typed-interrupt.d.ts +66 -0
- package/dist/chat/typed-interrupts/use-statewire-typed-interrupt.js +231 -0
- package/dist/chat/typed-interrupts/use-statewire-typed-interrupt.js.map +1 -0
- package/dist/chat-ui/composer/composer-named-agents.cjs +13 -0
- package/dist/chat-ui/composer/composer-named-agents.cjs.map +1 -0
- package/dist/chat-ui/composer/composer-named-agents.d.ts +20 -0
- package/dist/chat-ui/composer/composer-named-agents.js +13 -0
- package/dist/chat-ui/composer/composer-named-agents.js.map +1 -0
- package/dist/chat-ui/composer/slash-command-menu.cjs +143 -0
- package/dist/chat-ui/composer/slash-command-menu.cjs.map +1 -0
- package/dist/chat-ui/composer/slash-command-menu.d.ts +19 -0
- package/dist/chat-ui/composer/slash-command-menu.js +143 -0
- package/dist/chat-ui/composer/slash-command-menu.js.map +1 -0
- package/dist/chat-ui/composer/slash-commands-extension.cjs +51 -0
- package/dist/chat-ui/composer/slash-commands-extension.cjs.map +1 -0
- package/dist/chat-ui/composer/slash-commands-extension.d.ts +39 -0
- package/dist/chat-ui/composer/slash-commands-extension.js +51 -0
- package/dist/chat-ui/composer/slash-commands-extension.js.map +1 -0
- package/dist/chat-ui/composer/slash-commands.cjs +74 -0
- package/dist/chat-ui/composer/slash-commands.cjs.map +1 -0
- package/dist/chat-ui/composer/slash-commands.d.ts +82 -0
- package/dist/chat-ui/composer/slash-commands.js +74 -0
- package/dist/chat-ui/composer/slash-commands.js.map +1 -0
- package/dist/chat-ui/composer/tiptap-composer.cjs +135 -9
- package/dist/chat-ui/composer/tiptap-composer.cjs.map +1 -1
- package/dist/chat-ui/composer/tiptap-composer.d.ts +61 -2
- package/dist/chat-ui/composer/tiptap-composer.js +135 -9
- package/dist/chat-ui/composer/tiptap-composer.js.map +1 -1
- package/dist/chat-ui/index.cjs +3 -0
- package/dist/chat-ui/index.cjs.map +1 -1
- package/dist/chat-ui/index.d.ts +3 -2
- package/dist/chat-ui/index.js +3 -0
- package/dist/chat-ui/index.js.map +1 -1
- package/dist/chat-ui/mentions/mention-chip.cjs +1 -1
- package/dist/chat-ui/mentions/mention-chip.cjs.map +1 -1
- package/dist/chat-ui/mentions/mention-chip.js +2 -2
- package/dist/chat-ui/mentions/mention-chip.js.map +1 -1
- package/dist/chat-ui/mentions/mention-extension.cjs +8 -1
- package/dist/chat-ui/mentions/mention-extension.cjs.map +1 -1
- package/dist/chat-ui/mentions/mention-extension.js +8 -1
- package/dist/chat-ui/mentions/mention-extension.js.map +1 -1
- package/dist/chat-ui/mentions/suggestions/components/get-scope-name.cjs +1 -0
- package/dist/chat-ui/mentions/suggestions/components/get-scope-name.cjs.map +1 -1
- package/dist/chat-ui/mentions/suggestions/components/get-scope-name.js +1 -0
- package/dist/chat-ui/mentions/suggestions/components/get-scope-name.js.map +1 -1
- package/dist/chat-ui/mentions/suggestions/components/mention-icon.cjs +2 -0
- package/dist/chat-ui/mentions/suggestions/components/mention-icon.cjs.map +1 -1
- package/dist/chat-ui/mentions/suggestions/components/mention-icon.js +3 -1
- package/dist/chat-ui/mentions/suggestions/components/mention-icon.js.map +1 -1
- package/dist/chat-ui/mentions/suggestions/components/menu-item.cjs +1 -1
- package/dist/chat-ui/mentions/suggestions/components/menu-item.cjs.map +1 -1
- package/dist/chat-ui/mentions/suggestions/components/menu-item.js +1 -1
- package/dist/chat-ui/mentions/suggestions/components/menu-item.js.map +1 -1
- package/dist/chat-ui/mentions/suggestions/data/api-client.cjs +36 -0
- package/dist/chat-ui/mentions/suggestions/data/api-client.cjs.map +1 -1
- package/dist/chat-ui/mentions/suggestions/data/api-client.d.ts +42 -0
- package/dist/chat-ui/mentions/suggestions/data/api-client.js +36 -0
- package/dist/chat-ui/mentions/suggestions/data/api-client.js.map +1 -1
- package/dist/chat-ui/mentions/suggestions/data/sources/index.cjs +235 -19
- package/dist/chat-ui/mentions/suggestions/data/sources/index.cjs.map +1 -1
- package/dist/chat-ui/mentions/suggestions/data/sources/index.d.ts +88 -10
- package/dist/chat-ui/mentions/suggestions/data/sources/index.js +236 -20
- package/dist/chat-ui/mentions/suggestions/data/sources/index.js.map +1 -1
- package/dist/chat-ui/mentions/suggestions/data/types.cjs.map +1 -1
- package/dist/chat-ui/mentions/suggestions/data/types.d.ts +27 -1
- package/dist/chat-ui/mentions/suggestions/data/types.js.map +1 -1
- package/dist/chat-ui/mentions/suggestions/data/use-mention-suggestions.cjs +56 -5
- package/dist/chat-ui/mentions/suggestions/data/use-mention-suggestions.cjs.map +1 -1
- package/dist/chat-ui/mentions/suggestions/data/use-mention-suggestions.d.ts +26 -6
- package/dist/chat-ui/mentions/suggestions/data/use-mention-suggestions.js +57 -6
- package/dist/chat-ui/mentions/suggestions/data/use-mention-suggestions.js.map +1 -1
- package/dist/chat-ui/mentions/suggestions/mention-suggestions.extension.cjs +34 -17
- package/dist/chat-ui/mentions/suggestions/mention-suggestions.extension.cjs.map +1 -1
- package/dist/chat-ui/mentions/suggestions/mention-suggestions.extension.d.ts +19 -1
- package/dist/chat-ui/mentions/suggestions/mention-suggestions.extension.js +35 -18
- package/dist/chat-ui/mentions/suggestions/mention-suggestions.extension.js.map +1 -1
- package/dist/chat-ui/statewire.d.ts +1 -1
- package/dist/chat-ui/thread/statewire-history-edge.cjs +15 -0
- package/dist/chat-ui/thread/statewire-history-edge.cjs.map +1 -1
- package/dist/chat-ui/thread/statewire-history-edge.d.ts +4 -1
- package/dist/chat-ui/thread/statewire-history-edge.js +15 -0
- package/dist/chat-ui/thread/statewire-history-edge.js.map +1 -1
- package/dist/collab/client.cjs +17 -5
- package/dist/collab/client.cjs.map +1 -1
- package/dist/collab/client.d.ts +22 -7
- package/dist/collab/client.js +17 -5
- package/dist/collab/client.js.map +1 -1
- package/dist/composer/ComposerAttachedReferences.cjs +119 -0
- package/dist/composer/ComposerAttachedReferences.cjs.map +1 -0
- package/dist/composer/ComposerAttachedReferences.d.ts +26 -0
- package/dist/composer/ComposerAttachedReferences.js +119 -0
- package/dist/composer/ComposerAttachedReferences.js.map +1 -0
- package/dist/composer/ComposerNamedAgents.cjs +63 -0
- package/dist/composer/ComposerNamedAgents.cjs.map +1 -0
- package/dist/composer/ComposerNamedAgents.d.ts +16 -0
- package/dist/composer/ComposerNamedAgents.js +63 -0
- package/dist/composer/ComposerNamedAgents.js.map +1 -0
- package/dist/composer/attached-references.cjs +159 -0
- package/dist/composer/attached-references.cjs.map +1 -0
- package/dist/composer/attached-references.d.ts +86 -0
- package/dist/composer/attached-references.js +159 -0
- package/dist/composer/attached-references.js.map +1 -0
- package/dist/composer/build-composed-message.cjs +14 -7
- package/dist/composer/build-composed-message.cjs.map +1 -1
- package/dist/composer/build-composed-message.d.ts +6 -1
- package/dist/composer/build-composed-message.js +14 -7
- package/dist/composer/build-composed-message.js.map +1 -1
- package/dist/composer/composer-handoff.cjs +6 -2
- package/dist/composer/composer-handoff.cjs.map +1 -1
- package/dist/composer/composer-handoff.d.ts +7 -1
- package/dist/composer/composer-handoff.js +6 -2
- package/dist/composer/composer-handoff.js.map +1 -1
- package/dist/composer/folder-upload.cjs +149 -0
- package/dist/composer/folder-upload.cjs.map +1 -0
- package/dist/composer/folder-upload.d.ts +79 -0
- package/dist/composer/folder-upload.js +149 -0
- package/dist/composer/folder-upload.js.map +1 -0
- package/dist/composer/index.d.ts +1 -1
- package/dist/composer/useAttachToChat.cjs +35 -0
- package/dist/composer/useAttachToChat.cjs.map +1 -0
- package/dist/composer/useAttachToChat.d.ts +54 -0
- package/dist/composer/useAttachToChat.js +35 -0
- package/dist/composer/useAttachToChat.js.map +1 -0
- package/dist/composer/useAttachedReferencesComposerProps.cjs +19 -0
- package/dist/composer/useAttachedReferencesComposerProps.cjs.map +1 -0
- package/dist/composer/useAttachedReferencesComposerProps.d.ts +12 -0
- package/dist/composer/useAttachedReferencesComposerProps.js +19 -0
- package/dist/composer/useAttachedReferencesComposerProps.js.map +1 -0
- package/dist/composer/useFileUpload.cjs +95 -7
- package/dist/composer/useFileUpload.cjs.map +1 -1
- package/dist/composer/useFileUpload.d.ts +21 -2
- package/dist/composer/useFileUpload.js +95 -7
- package/dist/composer/useFileUpload.js.map +1 -1
- package/dist/data/athena-api-error.cjs +125 -0
- package/dist/data/athena-api-error.cjs.map +1 -0
- package/dist/data/athena-api-error.d.ts +96 -0
- package/dist/data/athena-api-error.js +125 -0
- package/dist/data/athena-api-error.js.map +1 -0
- package/dist/data/athena-data-client.cjs +106 -0
- package/dist/data/athena-data-client.cjs.map +1 -0
- package/dist/data/athena-data-client.d.ts +74 -0
- package/dist/data/athena-data-client.js +106 -0
- package/dist/data/athena-data-client.js.map +1 -0
- package/dist/data/athena-member.cjs +93 -0
- package/dist/data/athena-member.cjs.map +1 -0
- package/dist/data/athena-member.d.ts +125 -0
- package/dist/data/athena-member.js +93 -0
- package/dist/data/athena-member.js.map +1 -0
- package/dist/data/athena-request.cjs +458 -0
- package/dist/data/athena-request.cjs.map +1 -0
- package/dist/data/athena-request.d.ts +120 -0
- package/dist/data/athena-request.js +458 -0
- package/dist/data/athena-request.js.map +1 -0
- package/dist/data/use-athena-fetch.cjs +14 -0
- package/dist/data/use-athena-fetch.cjs.map +1 -0
- package/dist/data/use-athena-fetch.d.ts +19 -0
- package/dist/data/use-athena-fetch.js +14 -0
- package/dist/data/use-athena-fetch.js.map +1 -0
- package/dist/data/use-athena-graphql.cjs +66 -0
- package/dist/data/use-athena-graphql.cjs.map +1 -0
- package/dist/data/use-athena-graphql.d.ts +56 -0
- package/dist/data/use-athena-graphql.js +66 -0
- package/dist/data/use-athena-graphql.js.map +1 -0
- package/dist/data/use-athena-rest.cjs +33 -0
- package/dist/data/use-athena-rest.cjs.map +1 -0
- package/dist/data/use-athena-rest.d.ts +21 -0
- package/dist/data/use-athena-rest.js +33 -0
- package/dist/data/use-athena-rest.js.map +1 -0
- package/dist/data/use-semantic-query.cjs +44 -0
- package/dist/data/use-semantic-query.cjs.map +1 -0
- package/dist/data/use-semantic-query.d.ts +92 -0
- package/dist/data/use-semantic-query.js +44 -0
- package/dist/data/use-semantic-query.js.map +1 -0
- package/dist/diagnostics/athena-diagnostics.cjs.map +1 -1
- package/dist/diagnostics/athena-diagnostics.d.ts +5 -1
- package/dist/diagnostics/athena-diagnostics.js.map +1 -1
- package/dist/diagnostics/errors.cjs +7 -0
- package/dist/diagnostics/errors.cjs.map +1 -1
- package/dist/diagnostics/errors.d.ts +7 -0
- package/dist/diagnostics/errors.js +7 -0
- package/dist/diagnostics/errors.js.map +1 -1
- package/dist/index.cjs +155 -11
- package/dist/index.cjs.map +1 -1
- package/dist/index.d.ts +72 -13
- package/dist/index.js +148 -4
- package/dist/index.js.map +1 -1
- package/dist/keryx-http/src/initial-sync.cjs +64 -16
- package/dist/keryx-http/src/initial-sync.cjs.map +1 -1
- package/dist/keryx-http/src/initial-sync.d.ts +31 -1
- package/dist/keryx-http/src/initial-sync.js +64 -16
- package/dist/keryx-http/src/initial-sync.js.map +1 -1
- package/dist/keryx-http/src/own-awareness.cjs +20 -0
- package/dist/keryx-http/src/own-awareness.cjs.map +1 -0
- package/dist/keryx-http/src/own-awareness.d.ts +50 -0
- package/dist/keryx-http/src/own-awareness.js +20 -0
- package/dist/keryx-http/src/own-awareness.js.map +1 -0
- package/dist/keryx-http/src/update-attributions.cjs +26 -1
- package/dist/keryx-http/src/update-attributions.cjs.map +1 -1
- package/dist/keryx-http/src/update-attributions.d.ts +10 -1
- package/dist/keryx-http/src/update-attributions.js +26 -1
- package/dist/keryx-http/src/update-attributions.js.map +1 -1
- package/dist/offline/chat-outbox.cjs +262 -26
- package/dist/offline/chat-outbox.cjs.map +1 -1
- package/dist/offline/chat-outbox.d.ts +90 -12
- package/dist/offline/chat-outbox.js +263 -27
- package/dist/offline/chat-outbox.js.map +1 -1
- package/dist/provider/AthenaProvider.cjs +63 -19
- package/dist/provider/AthenaProvider.cjs.map +1 -1
- package/dist/provider/AthenaProvider.d.ts +24 -8
- package/dist/provider/AthenaProvider.js +66 -22
- package/dist/provider/AthenaProvider.js.map +1 -1
- package/dist/react/package.json.cjs +1 -1
- package/dist/react/package.json.js +1 -1
- package/dist/references/src/anchors/types.cjs +5 -0
- package/dist/references/src/anchors/types.cjs.map +1 -1
- package/dist/references/src/anchors/types.js +5 -0
- package/dist/references/src/anchors/types.js.map +1 -1
- package/dist/references/src/attachable.cjs +149 -0
- package/dist/references/src/attachable.cjs.map +1 -0
- package/dist/references/src/attachable.d.ts +87 -0
- package/dist/references/src/attachable.js +149 -0
- package/dist/references/src/attachable.js.map +1 -0
- package/dist/runtime/StatewirePlanModeLaneSync.cjs +93 -0
- package/dist/runtime/StatewirePlanModeLaneSync.cjs.map +1 -0
- package/dist/runtime/StatewirePlanModeLaneSync.d.ts +34 -0
- package/dist/runtime/StatewirePlanModeLaneSync.js +93 -0
- package/dist/runtime/StatewirePlanModeLaneSync.js.map +1 -0
- package/dist/runtime/StatewireThreadConfigLaneSync.cjs +2 -0
- package/dist/runtime/StatewireThreadConfigLaneSync.cjs.map +1 -1
- package/dist/runtime/StatewireThreadConfigLaneSync.d.ts +4 -0
- package/dist/runtime/StatewireThreadConfigLaneSync.js +2 -0
- package/dist/runtime/StatewireThreadConfigLaneSync.js.map +1 -1
- package/dist/runtime/statewire-plan-mode.cjs +71 -0
- package/dist/runtime/statewire-plan-mode.cjs.map +1 -0
- package/dist/runtime/statewire-plan-mode.d.ts +88 -0
- package/dist/runtime/statewire-plan-mode.js +71 -0
- package/dist/runtime/statewire-plan-mode.js.map +1 -0
- package/dist/runtime/statewire-run-config.cjs +18 -1
- package/dist/runtime/statewire-run-config.cjs.map +1 -1
- package/dist/runtime/statewire-run-config.d.ts +20 -0
- package/dist/runtime/statewire-run-config.js +18 -1
- package/dist/runtime/statewire-run-config.js.map +1 -1
- package/dist/runtime/statewire-session-key.cjs +11 -5
- package/dist/runtime/statewire-session-key.cjs.map +1 -1
- package/dist/runtime/statewire-session-key.d.ts +22 -10
- package/dist/runtime/statewire-session-key.js +11 -5
- package/dist/runtime/statewire-session-key.js.map +1 -1
- package/dist/runtime/useAthenaStatewireRuntime.cjs +65 -8
- package/dist/runtime/useAthenaStatewireRuntime.cjs.map +1 -1
- package/dist/runtime/useAthenaStatewireRuntime.d.ts +26 -10
- package/dist/runtime/useAthenaStatewireRuntime.js +67 -10
- package/dist/runtime/useAthenaStatewireRuntime.js.map +1 -1
- package/dist/search/useAthenaAssets.cjs +394 -0
- package/dist/search/useAthenaAssets.cjs.map +1 -0
- package/dist/search/useAthenaAssets.d.ts +186 -0
- package/dist/search/useAthenaAssets.js +394 -0
- package/dist/search/useAthenaAssets.js.map +1 -0
- package/dist/sheet-range/index.cjs +4 -0
- package/dist/sheet-range/index.cjs.map +1 -1
- package/dist/sheet-range/index.d.ts +4 -2
- package/dist/sheet-range/index.js +4 -0
- package/dist/sheet-range/index.js.map +1 -1
- package/dist/sheet-range/query-range.cjs +102 -0
- package/dist/sheet-range/query-range.cjs.map +1 -0
- package/dist/sheet-range/query-range.d.ts +46 -0
- package/dist/sheet-range/query-range.js +102 -0
- package/dist/sheet-range/query-range.js.map +1 -0
- package/dist/styles.css +1 -1
- package/dist/subagents/index.cjs +49 -0
- package/dist/subagents/index.cjs.map +1 -0
- package/dist/subagents/index.d.ts +16 -0
- package/dist/subagents/index.js +49 -0
- package/dist/subagents/index.js.map +1 -0
- package/dist/subagents/lane-follow.cjs +19 -0
- package/dist/subagents/lane-follow.cjs.map +1 -0
- package/dist/subagents/lane-follow.d.ts +9 -0
- package/dist/subagents/lane-follow.js +19 -0
- package/dist/subagents/lane-follow.js.map +1 -0
- package/dist/subagents/lane-model.cjs +178 -0
- package/dist/subagents/lane-model.cjs.map +1 -0
- package/dist/subagents/lane-model.d.ts +140 -0
- package/dist/subagents/lane-model.js +178 -0
- package/dist/subagents/lane-model.js.map +1 -0
- package/dist/subagents/lane-parts.cjs +517 -0
- package/dist/subagents/lane-parts.cjs.map +1 -0
- package/dist/subagents/lane-parts.d.ts +130 -0
- package/dist/subagents/lane-parts.js +517 -0
- package/dist/subagents/lane-parts.js.map +1 -0
- package/dist/subagents/subagent-lane-group.cjs +215 -0
- package/dist/subagents/subagent-lane-group.cjs.map +1 -0
- package/dist/subagents/subagent-lane-group.d.ts +67 -0
- package/dist/subagents/subagent-lane-group.js +215 -0
- package/dist/subagents/subagent-lane-group.js.map +1 -0
- package/dist/subagents/subagent-transcript-drawer.cjs +431 -0
- package/dist/subagents/subagent-transcript-drawer.cjs.map +1 -0
- package/dist/subagents/subagent-transcript-drawer.d.ts +78 -0
- package/dist/subagents/subagent-transcript-drawer.js +431 -0
- package/dist/subagents/subagent-transcript-drawer.js.map +1 -0
- package/dist/subagents/task-subagent-group.cjs +115 -0
- package/dist/subagents/task-subagent-group.cjs.map +1 -0
- package/dist/subagents/task-subagent-group.d.ts +36 -0
- package/dist/subagents/task-subagent-group.js +115 -0
- package/dist/subagents/task-subagent-group.js.map +1 -0
- package/dist/subagents/use-omitted-images-in-view.cjs +68 -0
- package/dist/subagents/use-omitted-images-in-view.cjs.map +1 -0
- package/dist/subagents/use-omitted-images-in-view.d.ts +21 -0
- package/dist/subagents/use-omitted-images-in-view.js +68 -0
- package/dist/subagents/use-omitted-images-in-view.js.map +1 -0
- package/dist/threads/Inbox.cjs +2 -2
- package/dist/threads/Inbox.cjs.map +1 -1
- package/dist/threads/SessionList.cjs +27 -24
- package/dist/threads/SessionList.cjs.map +1 -1
- package/dist/threads/SessionList.js +22 -19
- package/dist/threads/SessionList.js.map +1 -1
- package/dist/threads/SessionsPage.cjs +13 -7
- package/dist/threads/SessionsPage.cjs.map +1 -1
- package/dist/threads/SessionsPage.d.ts +10 -1
- package/dist/threads/SessionsPage.js +9 -3
- package/dist/threads/SessionsPage.js.map +1 -1
- package/dist/threads/live-session-rows.cjs +207 -0
- package/dist/threads/live-session-rows.cjs.map +1 -0
- package/dist/threads/live-session-rows.d.ts +175 -0
- package/dist/threads/live-session-rows.js +207 -0
- package/dist/threads/live-session-rows.js.map +1 -0
- package/dist/threads/session-list-model.cjs.map +1 -1
- package/dist/threads/session-list-model.d.ts +2 -1
- package/dist/threads/session-list-model.js.map +1 -1
- package/dist/threads/session-row-parts.cjs +3 -3
- package/dist/threads/session-row-parts.cjs.map +1 -1
- package/dist/threads/sessions-page-model.cjs +13 -5
- package/dist/threads/sessions-page-model.cjs.map +1 -1
- package/dist/threads/sessions-page-model.d.ts +7 -0
- package/dist/threads/sessions-page-model.js +11 -3
- package/dist/threads/sessions-page-model.js.map +1 -1
- package/dist/threads/sessions-page-storage.cjs +8 -8
- package/dist/threads/sessions-page-storage.cjs.map +1 -1
- package/dist/threads/sessions-page-storage.d.ts +5 -1
- package/dist/threads/sessions-page-storage.js +8 -8
- package/dist/threads/sessions-page-storage.js.map +1 -1
- package/dist/threads/statewire-thread-list.cjs +173 -20
- package/dist/threads/statewire-thread-list.cjs.map +1 -1
- package/dist/threads/statewire-thread-list.d.ts +44 -1
- package/dist/threads/statewire-thread-list.js +174 -21
- package/dist/threads/statewire-thread-list.js.map +1 -1
- package/dist/threads/use-athena-sessions.cjs +1 -0
- package/dist/threads/use-athena-sessions.cjs.map +1 -1
- package/dist/threads/use-athena-sessions.d.ts +7 -0
- package/dist/threads/use-athena-sessions.js +1 -0
- package/dist/threads/use-athena-sessions.js.map +1 -1
- package/dist/threads/use-athena-thread-agent.cjs +31 -0
- package/dist/threads/use-athena-thread-agent.cjs.map +1 -0
- package/dist/threads/use-athena-thread-agent.d.ts +38 -0
- package/dist/threads/use-athena-thread-agent.js +31 -0
- package/dist/threads/use-athena-thread-agent.js.map +1 -0
- package/dist/threads/use-athena-thread-plan-mode.cjs +18 -0
- package/dist/threads/use-athena-thread-plan-mode.cjs.map +1 -0
- package/dist/threads/use-athena-thread-plan-mode.d.ts +18 -0
- package/dist/threads/use-athena-thread-plan-mode.js +18 -0
- package/dist/threads/use-athena-thread-plan-mode.js.map +1 -0
- package/dist/threads/use-rest-conversation-history.d.ts +1 -0
- package/dist/tools/agent-creations.cjs +97 -0
- package/dist/tools/agent-creations.cjs.map +1 -0
- package/dist/tools/agent-creations.d.ts +38 -0
- package/dist/tools/agent-creations.js +97 -0
- package/dist/tools/agent-creations.js.map +1 -0
- package/dist/tools/agent-highlights.cjs +100 -0
- package/dist/tools/agent-highlights.cjs.map +1 -0
- package/dist/tools/agent-highlights.d.ts +57 -0
- package/dist/tools/agent-highlights.js +100 -0
- package/dist/tools/agent-highlights.js.map +1 -0
- package/dist/tools/append-document-tool-ui.cjs +1 -0
- package/dist/tools/append-document-tool-ui.cjs.map +1 -1
- package/dist/tools/append-document-tool-ui.d.ts +7 -0
- package/dist/tools/append-document-tool-ui.js +2 -1
- package/dist/tools/append-document-tool-ui.js.map +1 -1
- package/dist/tools/auto-open-tools.cjs +144 -71
- package/dist/tools/auto-open-tools.cjs.map +1 -1
- package/dist/tools/auto-open-tools.d.ts +131 -1
- package/dist/tools/auto-open-tools.js +145 -72
- package/dist/tools/auto-open-tools.js.map +1 -1
- package/dist/tools/browser-tool-uis.cjs +594 -0
- package/dist/tools/browser-tool-uis.cjs.map +1 -0
- package/dist/tools/browser-tool-uis.d.ts +8 -0
- package/dist/tools/browser-tool-uis.js +594 -0
- package/dist/tools/browser-tool-uis.js.map +1 -0
- package/dist/tools/computer-asset-tool-uis.cjs +313 -0
- package/dist/tools/computer-asset-tool-uis.cjs.map +1 -0
- package/dist/tools/computer-asset-tool-uis.d.ts +5 -0
- package/dist/tools/computer-asset-tool-uis.js +313 -0
- package/dist/tools/computer-asset-tool-uis.js.map +1 -0
- package/dist/tools/document-edit-tool-uis.cjs +218 -0
- package/dist/tools/document-edit-tool-uis.cjs.map +1 -0
- package/dist/tools/document-edit-tool-uis.d.ts +40 -0
- package/dist/tools/document-edit-tool-uis.js +218 -0
- package/dist/tools/document-edit-tool-uis.js.map +1 -0
- package/dist/tools/drive-tool-uis.cjs +425 -0
- package/dist/tools/drive-tool-uis.cjs.map +1 -0
- package/dist/tools/drive-tool-uis.d.ts +120 -0
- package/dist/tools/drive-tool-uis.js +425 -0
- package/dist/tools/drive-tool-uis.js.map +1 -0
- package/dist/tools/email-calendar-tool-uis.cjs +789 -0
- package/dist/tools/email-calendar-tool-uis.cjs.map +1 -0
- package/dist/tools/email-calendar-tool-uis.d.ts +129 -0
- package/dist/tools/email-calendar-tool-uis.js +789 -0
- package/dist/tools/email-calendar-tool-uis.js.map +1 -0
- package/dist/tools/ontology-tool-uis.cjs +83 -0
- package/dist/tools/ontology-tool-uis.cjs.map +1 -0
- package/dist/tools/ontology-tool-uis.d.ts +9 -0
- package/dist/tools/ontology-tool-uis.js +83 -0
- package/dist/tools/ontology-tool-uis.js.map +1 -0
- package/dist/tools/orchestration-tool-uis.cjs +586 -0
- package/dist/tools/orchestration-tool-uis.cjs.map +1 -0
- package/dist/tools/orchestration-tool-uis.d.ts +141 -0
- package/dist/tools/orchestration-tool-uis.js +586 -0
- package/dist/tools/orchestration-tool-uis.js.map +1 -0
- package/dist/tools/presentation-edit-tool-uis.cjs +516 -0
- package/dist/tools/presentation-edit-tool-uis.cjs.map +1 -0
- package/dist/tools/presentation-edit-tool-uis.d.ts +73 -0
- package/dist/tools/presentation-edit-tool-uis.js +516 -0
- package/dist/tools/presentation-edit-tool-uis.js.map +1 -0
- package/dist/tools/project-tool-uis.cjs +213 -0
- package/dist/tools/project-tool-uis.cjs.map +1 -0
- package/dist/tools/project-tool-uis.d.ts +14 -0
- package/dist/tools/project-tool-uis.js +213 -0
- package/dist/tools/project-tool-uis.js.map +1 -0
- package/dist/tools/sandbox-tool-uis.cjs +491 -0
- package/dist/tools/sandbox-tool-uis.cjs.map +1 -0
- package/dist/tools/sandbox-tool-uis.d.ts +116 -0
- package/dist/tools/sandbox-tool-uis.js +491 -0
- package/dist/tools/sandbox-tool-uis.js.map +1 -0
- package/dist/tools/sheet-query-tool-ui.cjs +138 -0
- package/dist/tools/sheet-query-tool-ui.cjs.map +1 -0
- package/dist/tools/sheet-query-tool-ui.d.ts +15 -0
- package/dist/tools/sheet-query-tool-ui.js +138 -0
- package/dist/tools/sheet-query-tool-ui.js.map +1 -0
- package/dist/tools/studio-screenshot-tool-uis.cjs +262 -0
- package/dist/tools/studio-screenshot-tool-uis.cjs.map +1 -0
- package/dist/tools/studio-screenshot-tool-uis.d.ts +52 -0
- package/dist/tools/studio-screenshot-tool-uis.js +262 -0
- package/dist/tools/studio-screenshot-tool-uis.js.map +1 -0
- package/dist/tools/subagent-task-tool-ui.cjs +24 -475
- package/dist/tools/subagent-task-tool-ui.cjs.map +1 -1
- package/dist/tools/subagent-task-tool-ui.d.ts +19 -103
- package/dist/tools/subagent-task-tool-ui.js +28 -479
- package/dist/tools/subagent-task-tool-ui.js.map +1 -1
- package/dist/tools/tool-summary.cjs +36 -0
- package/dist/tools/tool-summary.cjs.map +1 -1
- package/dist/tools/tool-summary.js +36 -0
- package/dist/tools/tool-summary.js.map +1 -1
- package/dist/tools/tool-uis.cjs +181 -53
- package/dist/tools/tool-uis.cjs.map +1 -1
- package/dist/tools/tool-uis.d.ts +40 -0
- package/dist/tools/tool-uis.js +183 -55
- package/dist/tools/tool-uis.js.map +1 -1
- package/dist/typed-interrupts/index.cjs +15 -0
- package/dist/typed-interrupts/index.cjs.map +1 -0
- package/dist/typed-interrupts/index.d.ts +20 -0
- package/dist/typed-interrupts/index.js +15 -0
- package/dist/typed-interrupts/index.js.map +1 -0
- package/dist/workbench/session-workbench-panes.cjs +6 -6
- package/dist/workbench/session-workbench-panes.cjs.map +1 -1
- package/package.json +28 -6
- package/dist/agent-runtime/src/chat-outbox-store.cjs +0 -510
- package/dist/agent-runtime/src/chat-outbox-store.cjs.map +0 -1
- package/dist/agent-runtime/src/chat-outbox-store.d.ts +0 -210
- package/dist/agent-runtime/src/chat-outbox-store.js +0 -510
- 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
|
|
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
|
|
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) =>
|
|
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
|
-
|
|
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(/ /g, ' ')\n .replace(/&/g, '&')\n .replace(/</g, '<')\n .replace(/>/g, '>')\n .replace(/"/g, '\"')\n .replace(/'/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(/ /g, ' ')\n .replace(/&/g, '&')\n .replace(/</g, '<')\n .replace(/>/g, '>')\n .replace(/"/g, '\"')\n .replace(/'/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":";;;;AAuCA,SAAS,oBAAoB,KAAkE;AAC7F,QAAM,eAAe,IAAI,gBAAgB,CAAA;AACzC,MAAI,aAAa,WAAW,KAAK,aAAa,KAAK,CAAC,OAAO,GAAG,UAAU,MAAM,EAAG,QAAO;AACxF,SAAO,aAAa,KAAK,CAAC,OAAO,GAAG,UAAU,QAAQ,IAAI,WAAW;AACvE;AAQO,SAAS,kBAAkB,KAAmC;;AACnE,QAAM,eAAa,SAAI,eAAJ,mBAAgB,WAAU;AAC7C,UAAQ,IAAI,WAAA;AAAA,IACV,KAAK;AACH,aAAO,EAAE,OAAO,cAAc,aAAa,MAAM,aAAa,QAAQ,WAAA;AAAA,IACxE,KAAK;AACH,aAAO,EAAE,OAAO,WAAW,MAAM,WAAW,QAAQ,WAAA;AAAA,IACtD,KAAK;AACH,aAAO,EAAE,OAAO,cAAc,iBAAiB,MAAM,SAAS,QAAQ,WAAA;AAAA,IACxE,KAAK;AACH,aAAO;AAAA,QACL,OAAO,IAAI,oBAAoB,cAAc,aAAc,cAAc;AAAA,QACzE,MAAM;AAAA,QACN,QAAQ;AAAA,MAAA;AAAA,IAEZ,KAAK;AACH,aAAO,EAAE,OAAO,cAAc,SAAS,MAAM,SAAS,QAAQ,WAAA;AAAA,IAChE,KAAK,QAAQ;AACX,YAAM,SAAS,oBAAoB,GAAG;AACtC,UAAI,WAAW,SAAU,QAAO,EAAE,OAAO,aAAa,MAAM,QAAQ,QAAQ,WAAA;AAC5E,aAAO,EAAE,OAAO,QAAQ,MAAM,QAAQ,QAAQ,WAAA;AAAA,IAChD;AAAA,EAEE;AAEJ,MAAI,IAAI,cAAc,iBAAiB,IAAI,kBAAkB,eAAe;AAC1E,WAAO,EAAE,OAAO,aAAa,MAAM,aAAa,QAAQ,KAAA;AAAA,EAC1D;AACA,MAAI,IAAI,cAAc,aAAa,IAAI,cAAc,UAAU;AAC7D,WAAO,EAAE,OAAO,WAAW,MAAM,WAAW,QAAQ,KAAA;AAAA,EACtD;AACA,MAAI,IAAI,cAAc,YAAY,IAAI,kBAAkB,SAAS;AAC/D,WAAO,EAAE,OAAO,SAAS,MAAM,SAAS,QAAQ,KAAA;AAAA,EAClD;AACA,MAAI,IAAI,cAAc,YAAa,QAAO,EAAE,OAAO,QAAQ,MAAM,QAAQ,QAAQ,KAAA;AACjF,SAAO,EAAE,OAAO,QAAQ,MAAM,SAAS,QAAQ,KAAA;AACjD;AAMO,SAAS,eAAe,KAA4D;AACzF,UAAQ,IAAI,WAAA;AAAA,IACV,KAAK;AACH,aAAO,EAAE,OAAO,aAAa,MAAM,YAAA;AAAA,IACrC,KAAK;AACH,aAAO,EAAE,OAAO,WAAW,MAAM,UAAA;AAAA,IACnC,KAAK;AACH,aAAO,EAAE,OAAO,IAAI,oBAAoB,iBAAiB,aAAa,SAAS,MAAM,QAAA;AAAA,IACvF,KAAK;AACH,aAAO;AAAA,QACL,OAAO,IAAI,oBAAoB,cAAc,aAAa;AAAA,QAC1D,MAAM;AAAA,MAAA;AAAA,IAEV,KAAK;AACH,aAAO,EAAE,OAAO,SAAS,MAAM,QAAA;AAAA,IACjC,KAAK,QAAQ;AACX,YAAM,SAAS,oBAAoB,GAAG;AACtC,UAAI,WAAW,SAAU,QAAO,EAAE,OAAO,aAAa,MAAM,OAAA;AAC5D,UAAI,WAAW,SAAU,QAAO,EAAE,OAAO,aAAa,MAAM,OAAA;AAC5D,aAAO,EAAE,OAAO,YAAY,MAAM,OAAA;AAAA,IACpC;AAAA,IACA,SAAS;AAEP,YAAM,WAAW,kBAAkB,GAAG;AACtC,aAAO,EAAE,OAAO,SAAS,OAAO,MAAM,SAAS,KAAA;AAAA,IACjD;AAAA,EAAA;AAEJ;AAWA,MAAM,mBAA2F;AAAA,EAC/F,EAAE,KAAK,aAAa,OAAO,YAAA;AAAA,EAC3B,EAAE,KAAK,WAAW,OAAO,UAAA;AAAA,EACzB,EAAE,KAAK,SAAS,OAAO,QAAA;AAAA,EACvB,EAAE,KAAK,YAAY,OAAO,UAAA;AAAA,EAC1B,EAAE,KAAK,SAAS,OAAO,QAAA;AAAA,EACvB,EAAE,KAAK,QAAQ,OAAO,OAAA;AAAA,EACtB,EAAE,KAAK,SAAS,OAAO,QAAA;AACzB;AAEA,MAAM,mBAAqD;AAAA,EACzD,aAAa;AAAA,EACb,SAAS;AAAA,EACT,QAAQ;AAAA,EACR,WAAW;AAAA,EACX,WAAW;AAAA,EACX,QAAQ;AAAA,EACR,UAAU;AACZ;AAEA,MAAM,uBAA6D;AAAA,EACjE,QAAQ;AAAA,EACR,aAAa;AAAA,EACb,MAAM;AAAA,EACN,OAAO;AACT;AAEO,SAAS,eAAe,QAA2C;AACxE,SAAQ,UAAU,iBAAiB,MAA0B,KAAM;AACrE;AAEO,SAAS,mBAAmB,QAAwB;AACzD,SAAO,qBAAqB,MAA8B,KAAK;AACjE;AAGO,SAAS,gBACd,MACA,SACmB;AACnB,MAAI,KAAK,WAAW,EAAG,QAAO,CAAA;AAC9B,MAAI,YAAY,OAAQ,QAAO,CAAC,EAAE,KAAK,OAAO,OAAO,MAAM,OAAO,CAAC,GAAG,IAAI,GAAG;AAC7E,QAAM,8BAAc,IAAA;AACpB,QAAM,QAAQ,CAAC,QAA8C;AAC3D,QAAI,YAAY,aAAa;AAC3B,aAAO,iBAAiB,KAAK,CAAC,UAAU,MAAM,QAAQ,IAAI,SAAS,IAC9D,IAAI,YACL;AAAA,IACN;AACA,WAAO,IAAI,aAAa,IAAI,aAAa,mBAAmB,IAAI,YAAY;AAAA,EAC9E;AACA,aAAW,OAAO,MAAM;AACtB,UAAM,MAAM,MAAM,GAAG;AACrB,UAAM,SAAS,QAAQ,IAAI,GAAG,KAAK,CAAA;AACnC,WAAO,KAAK,GAAG;AACf,YAAQ,IAAI,KAAK,MAAM;AAAA,EACzB;AACA,QAAM,QACJ,YAAY,cACR,mBACA;AAAA,IACE,GAAG,OAAO,QAAQ,gBAAgB,EAAE,IAAI,CAAC,CAAC,KAAK,KAAK,OAAO,EAAE,KAAK,QAAQ;AAAA,IAC1E,EAAE,KAAK,QAAQ,OAAO,SAAA;AAAA,EAAS;AAEvC,SAAO,MAAM,QAAQ,CAAC,EAAE,KAAK,YAAY;AACvC,UAAM,QAAQ,QAAQ,IAAI,GAAG;AAC7B,WAAO,QAAQ,CAAC,EAAE,KAAK,OAAO,MAAA,CAAO,IAAI,CAAA;AAAA,EAC3C,CAAC;AACH;AAmBO,MAAM,mBAA8C;AAAA,EACzD,EAAE,IAAI,UAAU,OAAO,UAAU,gBAAgB,KAAA;AAAA,EACjD,EAAE,IAAI,UAAU,OAAO,UAAU,gBAAgB,KAAA;AAAA,EACjD,EAAE,IAAI,QAAQ,OAAO,QAAQ,gBAAgB,MAAA;AAAA,EAC7C,EAAE,IAAI,gBAAgB,OAAO,iBAAiB,gBAAgB,KAAA;AAAA,EAC9D,EAAE,IAAI,WAAW,OAAO,WAAW,gBAAgB,MAAA;AAAA,EACnD,EAAE,IAAI,WAAW,OAAO,WAAW,gBAAgB,MAAA;AAAA,EACnD,EAAE,IAAI,WAAW,OAAO,WAAW,gBAAgB,KAAA;AACrD;AAMO,MAAM,kCAA+D,iBAAiB;AAAA,EAC3F,CAAC,WAAW,CAAC,OAAO;AACtB,EAAE,IAAI,CAAC,WAAW,OAAO,EAAE;AAGpB,SAAS,uBAAuB,QAAyD;AAC9F,SAAO,iBAAiB,IAAI,CAAC,WAAW,OAAO,EAAE,EAAE,OAAO,CAAC,OAAO,CAAC,OAAO,SAAS,EAAE,CAAC;AACxF;AAEO,MAAM,mCAAgE;AAAA,EAC3E;AACF;AAQA,SAAS,WAAW,OAAuB;AACzC,QAAM,QAAQ,MAAM,QAAQ,WAAW,EAAE,EAAE,QAAQ,UAAU,GAAG,EAAE,KAAA;AAClE,MAAI,6BAA6B,KAAK,KAAK,EAAG,QAAO,GAAG,MAAM,MAAM,GAAG,CAAC,CAAC;AACzE,SAAO,QAAQ,MAAM,OAAO,CAAC,EAAE,gBAAgB,MAAM,MAAM,CAAC,IAAI;AAClE;AAEO,SAAS,WAAW,SAAiB,QAAiC;;AAC3E,WAAO,sCAAQ,WAAR,mBAAiB,aAAY,SAAS,WAAW,OAAO,CAAC;AAClE;AAGO,SAAS,aAAa,WAAsC,QAAiC;;AAClG,QAAM,UAAU,aAAaA,cAAAA;AAC7B,OAAI,sCAAQ,aAAR,mBAAmB,SAAU,QAAO,OAAO,SAAS,OAAO;AAC/D,SAAO,YAAYA,cAAAA,yBAAyB,YAAY,WAAW,OAAO;AAC5E;AAOO,SAAS,aAAa,MAAyC;AACpE,MAAI,CAAC,KAAM,QAAO;AAClB,SAAO,KACJ,QAAQ,YAAY,EAAE,EACtB,QAAQ,4BAA4B,IAAI,EACxC,QAAQ,oBAAoB,EAAE,EAC9B,QAAQ,uCAAuC,EAAE,EACjD,QAAQ,WAAW,GAAG,EACtB,QAAQ,UAAU,GAAG,EACrB,QAAQ,SAAS,GAAG,EACpB,QAAQ,SAAS,GAAG,EACpB,QAAQ,WAAW,GAAG,EACtB,QAAQ,UAAU,GAAG,EACrB,QAAQ,QAAQ,GAAG,EACnB,KAAA;AACL;AAEO,SAAS,aAAa,aAAiD;AAC5E,MAAI,gBAAgB,KAAM,QAAO;AACjC,MAAI,gBAAgB,MAAO,QAAO;AAClC,SAAO;AACT;AAOA,MAAM,YAAY,CAAC,UAA0B;AAC3C,QAAM,KAAK,KAAK,MAAM,KAAK;AAC3B,SAAO,OAAO,SAAS,EAAE,IAAI,IAAI,KAAK,EAAE,EAAE,mBAAA,IAAuB;AACnE;AAGO,SAAS,oBACd,OACA,QACsB;;AACtB,QAAM,QAA8B,CAAA;AACpC,QAAM,OAAO,CAAC,WAA8B,OAAO,KAAK,IAAI;AAC5D,OAAI,WAAM,gBAAN,mBAAmB,QAAQ;AAC7B,UAAM,KAAK,EAAE,OAAO,eAAe,OAAO,WAAW,KAAK,MAAM,YAAY,IAAI,cAAc,CAAC,CAAC,IAAI;AAAA,EACtG;AACA,OAAI,WAAM,oBAAN,mBAAuB,QAAQ;AACjC,UAAM,KAAK;AAAA,MACT,OAAO;AAAA,MACP,OAAO,YAAY,KAAK,MAAM,gBAAgB,IAAI,kBAAkB,CAAC,CAAC;AAAA,IAAA,CACvE;AAAA,EACH;AACA,MAAI,MAAM,WAAY,OAAM,KAAK,EAAE,OAAO,cAAc,OAAO,UAAU;AACzE,MAAI,MAAM,cAAe,OAAM,KAAK,EAAE,OAAO,iBAAiB,OAAO,UAAU;AAC/E,MAAI,MAAM,oBAAoB,QAAW;AACvC,UAAM,KAAK;AAAA,MACT,OAAO;AAAA,MACP,OAAO,MAAM,kBAAkB,sBAAsB;AAAA,IAAA,CACtD;AAAA,EACH;AACA,MAAI,MAAM,gBAAgB,QAAW;AACnC,UAAM,KAAK;AAAA,MACT,OAAO;AAAA,MACP,OAAO,MAAM,cAAc,iBAAiB;AAAA,IAAA,CAC7C;AAAA,EACH;AACA,OAAI,WAAM,mBAAN,mBAAsB,QAAQ;AAChC,UAAM,KAAK;AAAA,MACT,OAAO;AAAA,MACP,OAAO,UAAU,KAAK,MAAM,eAAe,IAAI,CAAC,OAAO,WAAW,IAAI,MAAM,CAAC,CAAC,CAAC;AAAA,IAAA,CAChF;AAAA,EACH;AACA,OAAI,WAAM,qBAAN,mBAAwB,QAAQ;AAClC,UAAM,KAAK;AAAA,MACT,OAAO;AAAA,MACP,OAAO,SAAS,KAAK,MAAM,iBAAiB,IAAI,CAAC,OAAO,aAAa,IAAI,MAAM,CAAC,CAAC,CAAC;AAAA,IAAA,CACnF;AAAA,EACH;AACA,OAAI,WAAM,kBAAN,mBAAqB,QAAQ;AAC/B,UAAM,KAAK;AAAA,MACT,OAAO;AAAA,MACP,OAAO,WAAW;AAAA,QAChB,MAAM,cAAc;AAAA,UAClB,CAAC,YACCC,4CAAmB,EAAE,cAAc,SAAS,OAAO,MAAM,aAAa,KAAA,CAAM,KAAK;AAAA,QAAA;AAAA,MACrF,CACD;AAAA,IAAA,CACF;AAAA,EACH;AACA,MAAI,MAAM,aAAc,OAAM,KAAK,EAAE,OAAO,gBAAgB,OAAO,iBAAiB,UAAU,MAAM,YAAY,CAAC,IAAI;AACrH,MAAI,MAAM,cAAe,OAAM,KAAK,EAAE,OAAO,iBAAiB,OAAO,kBAAkB,UAAU,MAAM,aAAa,CAAC,IAAI;AACzH,MAAI,MAAM,aAAc,OAAM,KAAK,EAAE,OAAO,gBAAgB,OAAO,iBAAiB,UAAU,MAAM,YAAY,CAAC,IAAI;AACrH,MAAI,MAAM,cAAe,OAAM,KAAK,EAAE,OAAO,iBAAiB,OAAO,kBAAkB,UAAU,MAAM,aAAa,CAAC,IAAI;AACzH,MAAI,MAAM,iBAAkB,OAAM,KAAK,EAAE,OAAO,oBAAoB,OAAO,uBAAuB;AAClG,SAAO;AACT;AAIO,MAAM,wBAAkF;AAAA,EAC7F,EAAE,IAAI,SAAS,OAAO,QAAA;AAAA,EACtB,EAAE,IAAI,SAAS,OAAO,cAAA;AAAA,EACtB,EAAE,IAAI,UAAU,OAAO,eAAA;AAAA,EACvB,EAAE,IAAI,WAAW,OAAO,qBAAA;AAC1B;AAQO,SAAS,iBACd,QACA,MAAY,oBAAI,QACqB;AACrC,QAAM,kBAAkB,CAAC,SAAyB;AAChD,UAAM,WAAW,IAAI,KAAK,GAAG;AAC7B,aAAS,SAAS,GAAG,GAAG,GAAG,CAAC;AAC5B,aAAS,QAAQ,SAAS,QAAA,IAAY,IAAI;AAC1C,WAAO,SAAS,YAAA;AAAA,EAClB;AACA,MAAI,WAAW,QAAS,QAAO,EAAE,OAAO,gBAAgB,CAAC,EAAA;AACzD,MAAI,WAAW,QAAS,QAAO,EAAE,OAAO,gBAAgB,CAAC,EAAA;AACzD,MAAI,WAAW,SAAU,QAAO,EAAE,OAAO,gBAAgB,EAAE,EAAA;AAC3D,SAAO,EAAE,QAAQ,gBAAgB,EAAE,EAAA;AACrC;AAGA,SAAS,QAAQ,OAA6D;AAC5E,MAAI,UAAU,QAAQ,UAAU,OAAW,QAAO;AAClD,MAAI,OAAO,OAAO,KAAK;AACvB,MAAI,eAAe,KAAK,IAAI,EAAG,QAAO,IAAI,IAAI;AAC9C,SAAO,WAAW,KAAK,IAAI,IAAI,IAAI,KAAK,QAAQ,MAAM,IAAI,CAAC,MAAM;AACnE;AAGO,SAAS,YACd,MACA,QACQ;AACR,QAAM,SAAS;AAAA,IACb;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,EAAA;AAEF,QAAM,QAAQ,KAAK,IAAI,CAAC,QAAQ;AAC9B,UAAM,SAAS,kBAAkB,GAAG;AACpC,WAAO;AAAA,MACL,IAAI,SAAS;AAAA,MACb,OAAO;AAAA,MACP,IAAI,cAAc;AAAA,MAClB,IAAI,aAAa;AAAA,MACjB,IAAI,aAAa;AAAA,MACjB,IAAI,iBAAiB;AAAA,MACrBA,yBAAAA,mBAAmB,GAAG,KAAK;AAAA,MAC3B,IAAI,gBAAgB,WAAW,IAAI,eAAe,MAAM,IAAI;AAAA,MAC5D,IAAI,gBAAgB,aAAa,IAAI,iBAAiB,MAAM,IAAI;AAAA,OAC/D,IAAI,gBAAgB,IAAI,IAAI,CAAC,OAAO,GAAG,GAAG,YAAY,IAAI,GAAG,MAAM,KAAK,GAAG,KAAK,GAAG,EAAE,KAAK,IAAI;AAAA,MAC/F,IAAI;AAAA,MACJ,IAAI;AAAA,MACJ,aAAa,IAAI,WAAW;AAAA,MAC5B,IAAI,aAAa;AAAA,MACjB,IAAI;AAAA,MACJ,IAAI;AAAA,IAAA,EAEH,IAAI,OAAO,EACX,KAAK,GAAG;AAAA,EACb,CAAC;AACD,SAAO,CAAC,OAAO,IAAI,OAAO,EAAE,KAAK,GAAG,GAAG,GAAG,KAAK,EAAE,KAAK,MAAM;AAC9D;;;;;;;;;;;;;;;;;;"}
|
|
@@ -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
|
|
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(/ /g, ' ')\n .replace(/&/g, '&')\n .replace(/</g, '<')\n .replace(/>/g, '>')\n .replace(/"/g, '\"')\n .replace(/'/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(/ /g, ' ')\n .replace(/&/g, '&')\n .replace(/</g, '<')\n .replace(/>/g, '>')\n .replace(/"/g, '\"')\n .replace(/'/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
|
|
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 :
|
|
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)) :
|
|
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:
|
|
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:
|
|
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
|
|
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
|
-
|
|
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
|
|
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 :
|
|
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)) :
|
|
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:
|
|
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:
|
|
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
|
|
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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"}
|