gloomberb 0.16.3 → 0.16.4
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/package.json +4 -1
- package/src/api-client/askg.ts +43 -0
- package/src/api-client/auth.ts +15 -0
- package/src/api-client/beneficial-owners.ts +4 -0
- package/src/api-client/chat.ts +19 -0
- package/src/api-client/company-kpis.ts +14 -2
- package/src/api-client/data.ts +34 -16
- package/src/api-client/index.ts +12 -0
- package/src/api-client/normalizers.ts +27 -0
- package/src/api-client/paths.ts +88 -23
- package/src/api-client/request.ts +2 -1
- package/src/api-client/research-activity.ts +31 -0
- package/src/api-client/socket.ts +39 -8
- package/src/api-client/types.ts +57 -1
- package/src/api-client/upgrade-experiment.ts +90 -0
- package/src/app/global-shortcuts.ts +11 -1
- package/src/app/keybindings/actions.ts +10 -0
- package/src/app/pane-runtime/index.tsx +8 -0
- package/src/app/pane-runtime/pane-template-runtime.ts +5 -0
- package/src/app/pane-runtime/plugin-bindings.ts +65 -25
- package/src/app/pane-runtime/ticker-inspector-runtime.ts +12 -0
- package/src/app/pane-runtime/ticker-open-runtime.ts +18 -1
- package/src/app/runtime/desktop-deeplink.ts +5 -0
- package/src/app/star-prompt/model.ts +98 -0
- package/src/app/star-prompt/runtime.ts +41 -0
- package/src/app/star-prompt/status-line.tsx +190 -0
- package/src/app.tsx +13 -7
- package/src/architecture/core-builtin-allowlist.json +70 -0
- package/src/brokers/signed-in/adapter.ts +33 -2
- package/src/brokers/signed-in/client.ts +10 -0
- package/src/brokers/signed-in/sign-in-dialog.tsx +23 -9
- package/src/brokers/signed-in/sign-in.ts +62 -5
- package/src/capabilities/registry.ts +8 -1
- package/src/capabilities/types.ts +2 -0
- package/src/cli/commands/crypto-hints.ts +12 -4
- package/src/cli/commands/market.ts +359 -99
- package/src/cli/commands/options-chain.ts +172 -0
- package/src/cli/commands/options-leaps.ts +422 -0
- package/src/cli/commands/overview.ts +164 -26
- package/src/cli/commands/search.ts +29 -8
- package/src/cli/commands/system.ts +99 -19
- package/src/cli/commands/themes.ts +64 -0
- package/src/cli/commands/ticker.ts +62 -30
- package/src/cli/desktop-pane-shot.ts +97 -16
- package/src/cli/errors.ts +25 -2
- package/src/cli/freshness.ts +7 -4
- package/src/cli/fx-pair.ts +57 -0
- package/src/cli/help.ts +14 -1
- package/src/cli/index-roots.ts +51 -0
- package/src/cli/index.ts +9 -6
- package/src/cli/listing-arg.ts +211 -3
- package/src/cli/not-a-ticker.ts +37 -0
- package/src/cli/options.ts +50 -6
- package/src/cli/pane-functions/capabilities.ts +8 -2
- package/src/cli/pane-functions/catalog.ts +13 -2
- package/src/cli/pane-functions/data.ts +36 -5
- package/src/cli/pane-functions/dom.ts +21 -13
- package/src/cli/pane-functions/freshness.ts +205 -26
- package/src/cli/pane-functions/function-help.ts +67 -22
- package/src/cli/pane-functions/headless.ts +5 -4
- package/src/cli/pane-functions/index.ts +3 -0
- package/src/cli/pane-functions/market-session.ts +133 -0
- package/src/cli/pane-functions/options.ts +15 -4
- package/src/cli/pane-functions/report-notices.ts +63 -0
- package/src/cli/pane-functions/report.ts +4 -0
- package/src/cli/pane-functions/resolver.ts +4 -6
- package/src/cli/pane-functions/screenshot-evidence.ts +2 -0
- package/src/cli/pane-functions/screenshot.ts +105 -23
- package/src/cli/registry.ts +2 -1
- package/src/cli/result.ts +50 -13
- package/src/cli/row-window.ts +76 -0
- package/src/cli/scroll-truncation.ts +34 -0
- package/src/components/chart/composite/composite-chart.tsx +43 -4
- package/src/components/chart/composite/legend.tsx +39 -6
- package/src/components/chart/composite/rasterizer.ts +64 -4
- package/src/components/chart/composite/series-cues.ts +71 -0
- package/src/components/chart/composite/text-renderer.ts +16 -8
- package/src/components/chart/composite/types.ts +3 -0
- package/src/components/command-bar/commands/direct/index.ts +9 -1
- package/src/components/command-bar/commands/plugin/items.ts +3 -1
- package/src/components/command-bar/commands/registry.ts +7 -0
- package/src/components/command-bar/layout-items/focused-pane.ts +38 -0
- package/src/components/command-bar/pane-templates/workflow.ts +5 -0
- package/src/components/command-bar/routes/root/command-items.ts +2 -0
- package/src/components/command-bar/routes/root/plugin-turn-on.ts +92 -0
- package/src/components/command-bar/routes/root/results.ts +40 -10
- package/src/components/command-bar/routes/root/runtime.ts +8 -0
- package/src/components/command-bar/routes/root/search-providers.ts +97 -14
- package/src/components/command-bar/surface/index.tsx +18 -4
- package/src/components/command-bar/theme-picker.tsx +48 -13
- package/src/components/command-bar/workflow/ops.ts +5 -3
- package/src/components/data-table/view.tsx +28 -9
- package/src/components/layout/floating-pane.tsx +6 -2
- package/src/components/layout/market-summary.ts +23 -9
- package/src/components/layout/pane/content.tsx +46 -29
- package/src/components/layout/pane/cycle-order.ts +2 -11
- package/src/components/layout/pane/header.tsx +2 -1
- package/src/components/layout/pane/title.ts +1 -1
- package/src/components/layout/presentation.ts +22 -0
- package/src/components/layout/shell/active-drag.ts +1 -1
- package/src/components/layout/shell/drag/index.ts +4 -0
- package/src/components/layout/shell/drag/live.ts +76 -5
- package/src/components/layout/shell/drag/runtime.ts +8 -8
- package/src/components/layout/shell/index.tsx +47 -6
- package/src/components/layout/shell/layout-state.ts +5 -11
- package/src/components/layout/shell/menu.ts +28 -1
- package/src/components/layout/shell/pane/actions.ts +2 -1
- package/src/components/layout/shell/pane/layers.tsx +51 -10
- package/src/components/layout/shell/pane/management-shortcuts.ts +5 -0
- package/src/components/layout/shell/pane/new-layout.ts +116 -0
- package/src/components/layout/shell/shortcuts.ts +5 -2
- package/src/components/layout/shell/visible-layout.ts +44 -1
- package/src/components/layout/status-bar.tsx +4 -1
- package/src/components/markdown-text.tsx +9 -5
- package/src/components/metric-treemap/heat-surface.tsx +27 -8
- package/src/components/metric-treemap/heat-tiles.ts +48 -17
- package/src/components/onboarding/onboarding-frame.tsx +33 -10
- package/src/components/onboarding/onboarding-wizard.tsx +49 -40
- package/src/components/onboarding/portfolio-step/positions-panel.tsx +5 -2
- package/src/components/onboarding/pro-step-layout.ts +86 -0
- package/src/components/onboarding/use-onboarding-upgrade.ts +6 -2
- package/src/components/ui/button.tsx +10 -0
- package/src/components/ui/data-table/index.tsx +38 -0
- package/src/components/ui/data-table/types.ts +8 -1
- package/src/components/ui/data-table/visible-range.ts +2 -0
- package/src/components/ui/icon.tsx +11 -2
- package/src/components/ui/index.ts +1 -1
- package/src/core/connection-health.ts +1 -1
- package/src/core/state/app/layout-reducer.ts +89 -3
- package/src/core/state/app/state.ts +8 -5
- package/src/core/state/app/types.ts +13 -2
- package/src/data/config/layout.ts +55 -21
- package/src/data/config/store/fold-panes.ts +149 -0
- package/src/data/config/store/migrations.ts +7 -0
- package/src/data/config/store/node.ts +27 -6
- package/src/data/config/store/normalize.ts +37 -3
- package/src/i18n/es.ts +14 -1
- package/src/i18n/ja.ts +14 -1
- package/src/i18n/ko.ts +14 -1
- package/src/i18n/zh-cn.ts +14 -1
- package/src/i18n/zh-tw.ts +14 -1
- package/src/layout/desks.ts +1 -2
- package/src/layout/pane-layout-move.ts +264 -0
- package/src/layout/pane-manager/hidden-panes.ts +160 -0
- package/src/layout/pane-manager/index.ts +1 -0
- package/src/market-data/coordinator/entries.ts +7 -1
- package/src/market-data/coordinator/quotes.ts +2 -2
- package/src/market-data/market/freshness.ts +118 -18
- package/src/market-data/market/status.ts +40 -0
- package/src/market-data/options-alternatives.ts +69 -0
- package/src/market-data/quotes/contributions.ts +19 -2
- package/src/market-data/quotes/metadata.ts +16 -0
- package/src/market-data/quotes/screener-live-quotes.ts +56 -5
- package/src/plugins/builtin/account-management/keyboard.ts +3 -0
- package/src/plugins/builtin/account-management/model.ts +1 -0
- package/src/plugins/builtin/account-management/navigation.ts +1 -1
- package/src/plugins/builtin/account-management/pane.tsx +31 -4
- package/src/plugins/builtin/alerts/quotes.ts +3 -0
- package/src/plugins/builtin/analytics/risk-headless.ts +3 -1
- package/src/plugins/builtin/analytics/risk-model.ts +37 -8
- package/src/plugins/builtin/analytics/risk-pane.tsx +8 -4
- package/src/plugins/builtin/backtest/pane.tsx +1 -1
- package/src/plugins/builtin/broker-manager/detail.tsx +4 -0
- package/src/plugins/builtin/broker-manager/index.tsx +7 -3
- package/src/plugins/builtin/broker-manager/model.ts +8 -0
- package/src/plugins/builtin/broker-manager/pane-actions.tsx +8 -2
- package/src/plugins/builtin/broker-manager/sign-in-end.ts +82 -0
- package/src/plugins/builtin/broker-manager/table.ts +5 -0
- package/src/plugins/builtin/builtin-plugin-meta.ts +121 -11
- package/src/plugins/builtin/chart-composer/pane.tsx +1 -1
- package/src/plugins/builtin/chat/channels.ts +34 -36
- package/src/plugins/builtin/chat/command-bar.ts +138 -0
- package/src/plugins/builtin/chat/composer-commands.ts +21 -1
- package/src/plugins/builtin/chat/content/composer-runtime.ts +11 -1
- package/src/plugins/builtin/chat/content/footer.tsx +5 -3
- package/src/plugins/builtin/chat/content/index.tsx +21 -1
- package/src/plugins/builtin/chat/content/mentions.ts +2 -1
- package/src/plugins/builtin/chat/content/user-map.ts +3 -1
- package/src/plugins/builtin/chat/controller/index.ts +48 -0
- package/src/plugins/builtin/chat/conversations.ts +256 -0
- package/src/plugins/builtin/chat/discord-command.ts +91 -0
- package/src/plugins/builtin/chat/edit-window.ts +12 -6
- package/src/plugins/builtin/chat/ghost-user.ts +14 -0
- package/src/plugins/builtin/chat/index.tsx +40 -2
- package/src/plugins/builtin/chat/layout.ts +2 -0
- package/src/plugins/builtin/chat/message/desktop.tsx +2 -1
- package/src/plugins/builtin/chat/message/header.tsx +24 -15
- package/src/plugins/builtin/chat/message/profile-popover.tsx +2 -1
- package/src/plugins/builtin/chat/message/render-state.ts +3 -0
- package/src/plugins/builtin/chat/pane-requests.ts +60 -0
- package/src/plugins/builtin/chat/pane-state.ts +32 -2
- package/src/plugins/builtin/chat/pane.tsx +8 -0
- package/src/plugins/builtin/cloud/askg/controller.ts +112 -4
- package/src/plugins/builtin/cloud/askg/conversation-store.ts +21 -0
- package/src/plugins/builtin/cloud/askg/manifest.ts +1 -0
- package/src/plugins/builtin/cloud/askg/model.ts +129 -70
- package/src/plugins/builtin/cloud/askg/pane.tsx +772 -377
- package/src/plugins/builtin/cloud/askg/protocol.ts +40 -2
- package/src/plugins/builtin/cloud/askg/tool-display.ts +437 -0
- package/src/plugins/builtin/cloud/askg/tool-timeline.tsx +403 -0
- package/src/plugins/builtin/cloud/company-picker.tsx +1 -9
- package/src/plugins/builtin/cloud/mcp-connect/command.ts +24 -0
- package/src/plugins/builtin/cloud/mcp-connect/dialog.tsx +360 -0
- package/src/plugins/builtin/cloud/mcp-connect/model.ts +135 -0
- package/src/plugins/builtin/cloud/mcp-connect/sections.ts +62 -0
- package/src/plugins/builtin/cloud/plugin.tsx +36 -1
- package/src/plugins/builtin/cloud/starter-symbols.ts +8 -0
- package/src/plugins/builtin/cloud/terminal-relay/acm-tab.tsx +89 -0
- package/src/plugins/builtin/cloud/terminal-relay/client.ts +97 -0
- package/src/plugins/builtin/cloud/terminal-relay/connect-section.tsx +57 -0
- package/src/plugins/builtin/cloud/terminal-relay/engine.ts +666 -0
- package/src/plugins/builtin/cloud/terminal-relay/grants.ts +137 -0
- package/src/plugins/builtin/cloud/terminal-relay/host.tsx +81 -0
- package/src/plugins/builtin/cloud/terminal-relay/indicator.tsx +82 -0
- package/src/plugins/builtin/cloud/terminal-relay/manifest.ts +234 -0
- package/src/plugins/builtin/cloud/terminal-relay/policy.ts +153 -0
- package/src/plugins/builtin/cloud/terminal-relay/prompts.tsx +168 -0
- package/src/plugins/builtin/cloud/terminal-relay/redact.ts +73 -0
- package/src/plugins/builtin/cloud/terminal-relay/summary.ts +62 -0
- package/src/plugins/builtin/cloud/upgrade-dialog.tsx +26 -2
- package/src/plugins/builtin/cloud/upgrade-personalization.ts +57 -0
- package/src/plugins/builtin/cloud/upgrade-tickers.ts +124 -0
- package/src/plugins/builtin/comment-letters/client.ts +1 -3
- package/src/plugins/builtin/company-kpis/client.ts +23 -8
- package/src/plugins/builtin/company-kpis/headless.ts +3 -1
- package/src/plugins/builtin/company-kpis/pane.tsx +15 -7
- package/src/plugins/builtin/company-kpis/screenshot-evidence.ts +10 -3
- package/src/plugins/builtin/composite-plugins.ts +107 -64
- package/src/plugins/builtin/credit-boards/cdx-pane.tsx +4 -4
- package/src/plugins/builtin/credit-boards/index.tsx +21 -21
- package/src/plugins/builtin/credit-boards/model.ts +0 -1
- package/src/plugins/builtin/credit-boards/pane.tsx +30 -0
- package/src/plugins/builtin/credit-boards/sovr-pane.tsx +4 -4
- package/src/plugins/builtin/debt-maturities/client.ts +37 -9
- package/src/plugins/builtin/debt-maturities/headless.ts +3 -1
- package/src/plugins/builtin/debt-maturities/pane.tsx +5 -4
- package/src/plugins/builtin/dividend-yield/index.tsx +1 -1
- package/src/plugins/builtin/dividend-yield/pane.tsx +1 -1
- package/src/plugins/builtin/earnings-calls/data.ts +28 -7
- package/src/plugins/builtin/earnings-calls/headless.ts +3 -2
- package/src/plugins/builtin/earnings-calls/pane.tsx +10 -5
- package/src/plugins/builtin/econ/calendar-model.ts +42 -17
- package/src/plugins/builtin/econ/detail-view.tsx +2 -2
- package/src/plugins/builtin/econ/index.tsx +68 -22
- package/src/plugins/builtin/econ-statistics/headless.ts +12 -2
- package/src/plugins/builtin/econ-statistics/pane.tsx +1 -1
- package/src/plugins/builtin/econ-statistics/view.ts +17 -0
- package/src/plugins/builtin/executives/data.ts +17 -6
- package/src/plugins/builtin/executives/pane.tsx +16 -7
- package/src/plugins/builtin/filing-events/pane.tsx +22 -5
- package/src/plugins/builtin/fx-matrix/freshness.ts +65 -0
- package/src/plugins/builtin/fx-matrix/index.tsx +22 -1
- package/src/plugins/builtin/fx-matrix/pairs.ts +1 -1
- package/src/plugins/builtin/fx-matrix/settings.ts +42 -2
- package/src/plugins/builtin/gpu/headless.ts +9 -3
- package/src/plugins/builtin/gpu/model.ts +14 -5
- package/src/plugins/builtin/help/index.tsx +1 -0
- package/src/plugins/builtin/holders/beneficial-client.ts +29 -7
- package/src/plugins/builtin/holders/beneficial-view.tsx +7 -3
- package/src/plugins/builtin/holders/headless.ts +6 -1
- package/src/plugins/builtin/holders/pane.tsx +3 -0
- package/src/plugins/builtin/insider/index.tsx +4 -4
- package/src/plugins/builtin/iv-history/charts.tsx +21 -7
- package/src/plugins/builtin/iv-history/client.ts +12 -2
- package/src/plugins/builtin/iv-history/format.ts +33 -2
- package/src/plugins/builtin/iv-history/headless.ts +22 -10
- package/src/plugins/builtin/iv-history/index.tsx +3 -3
- package/src/plugins/builtin/iv-history/model.ts +61 -13
- package/src/plugins/builtin/iv-history/pane.tsx +11 -3
- package/src/plugins/builtin/iv-history/screen-pane.tsx +42 -18
- package/src/plugins/builtin/jobs/pane.tsx +1 -1
- package/src/plugins/builtin/kelly-sizer/headless.ts +149 -0
- package/src/plugins/builtin/kelly-sizer/history.ts +80 -0
- package/src/plugins/builtin/kelly-sizer/index.tsx +2 -0
- package/src/plugins/builtin/kelly-sizer/pane.tsx +109 -39
- package/src/plugins/builtin/kelly-sizer/sections.tsx +14 -0
- package/src/plugins/builtin/kelly-sizer/types.ts +9 -1
- package/src/plugins/builtin/layout-manager/index.tsx +9 -1
- package/src/plugins/builtin/macro-day/client.ts +24 -0
- package/src/plugins/builtin/macro-day/headless.ts +11 -8
- package/src/plugins/builtin/macro-day/index.tsx +3 -0
- package/src/plugins/builtin/macro-day/model.ts +11 -6
- package/src/plugins/builtin/macro-day/pane.tsx +12 -8
- package/src/plugins/builtin/macro-day/release-table.ts +40 -0
- package/src/plugins/builtin/macro-day/releases.ts +62 -44
- package/src/plugins/builtin/market-heatmap/data.ts +25 -5
- package/src/plugins/builtin/market-heatmap/evidence.ts +90 -0
- package/src/plugins/builtin/market-heatmap/index.tsx +144 -63
- package/src/plugins/builtin/market-heatmap/model.ts +94 -3
- package/src/plugins/builtin/market-heatmap/portfolio.ts +12 -2
- package/src/plugins/builtin/market-movers/headless.ts +31 -4
- package/src/plugins/builtin/market-movers/index.tsx +8 -1
- package/src/plugins/builtin/market-movers/model.ts +71 -17
- package/src/plugins/builtin/market-movers/table.ts +50 -23
- package/src/plugins/builtin/news/headless.ts +9 -2
- package/src/plugins/builtin/news/wire/news/footer.ts +10 -0
- package/src/plugins/builtin/openfda/client.ts +1 -1
- package/src/plugins/builtin/options/carry.ts +95 -0
- package/src/plugins/builtin/options/index.tsx +58 -5
- package/src/plugins/builtin/options/strike-window.ts +183 -0
- package/src/plugins/builtin/options/table.ts +55 -3
- package/src/plugins/builtin/options/types.ts +8 -1
- package/src/plugins/builtin/options/view.tsx +161 -12
- package/src/plugins/builtin/options-positioning/headless.ts +4 -2
- package/src/plugins/builtin/options-scenario/charts.tsx +2 -2
- package/src/plugins/builtin/options-scenario/client.ts +73 -17
- package/src/plugins/builtin/options-scenario/headless.ts +71 -24
- package/src/plugins/builtin/options-scenario/hedge.ts +284 -0
- package/src/plugins/builtin/options-scenario/index.tsx +9 -2
- package/src/plugins/builtin/options-scenario/model.ts +33 -0
- package/src/plugins/builtin/options-scenario/pane.tsx +40 -16
- package/src/plugins/builtin/pe-band/model.ts +2 -2
- package/src/plugins/builtin/pe-band/report-dates.ts +11 -7
- package/src/plugins/builtin/perps/equity-row.tsx +8 -5
- package/src/plugins/builtin/perps/model.ts +16 -5
- package/src/plugins/builtin/plugin-marketplace/model.ts +64 -21
- package/src/plugins/builtin/plugin-marketplace/packs.ts +118 -0
- package/src/plugins/builtin/plugin-marketplace/pane.tsx +344 -32
- package/src/plugins/builtin/plugin-marketplace/store.ts +7 -1
- package/src/plugins/builtin/plugin-module.ts +87 -4
- package/src/plugins/builtin/portfolio-list/cli/portfolio-command.ts +71 -36
- package/src/plugins/builtin/portfolio-list/cli/render.ts +87 -18
- package/src/plugins/builtin/portfolio-list/cli/shared.ts +2 -16
- package/src/plugins/builtin/portfolio-list/headless.ts +38 -7
- package/src/plugins/builtin/realized-vol/headless.ts +3 -0
- package/src/plugins/builtin/realized-vol/pane.tsx +1 -1
- package/src/plugins/builtin/research/corporate-actions-pane.tsx +2 -2
- package/src/plugins/builtin/research/equity-diagnostic-pane.tsx +1 -1
- package/src/plugins/builtin/revenue-breakdown/client.ts +13 -6
- package/src/plugins/builtin/revenue-breakdown/headless.ts +4 -1
- package/src/plugins/builtin/revenue-breakdown/pane.tsx +7 -4
- package/src/plugins/builtin/reverse-dcf/headless.ts +5 -1
- package/src/plugins/builtin/reverse-dcf/pane.tsx +1 -1
- package/src/plugins/builtin/risk-factors/data.ts +23 -9
- package/src/plugins/builtin/risk-factors/headless.ts +5 -2
- package/src/plugins/builtin/risk-factors/pane.tsx +6 -5
- package/src/plugins/builtin/seasonality/pane.tsx +1 -1
- package/src/plugins/builtin/sec/index.tsx +5 -5
- package/src/plugins/builtin/sectors/client.ts +10 -2
- package/src/plugins/builtin/sectors/headless.ts +35 -6
- package/src/plugins/builtin/sectors/index.tsx +18 -1
- package/src/plugins/builtin/sectors/sector-model.ts +150 -41
- package/src/plugins/builtin/shared/command-tab.ts +51 -0
- package/src/plugins/builtin/shared/headless-market-data.ts +33 -1
- package/src/plugins/builtin/shared/members-menu.tsx +4 -4
- package/src/plugins/builtin/shared/report-freshness.ts +50 -2
- package/src/plugins/builtin/shared/ticker-request.ts +25 -1
- package/src/plugins/builtin/shared/use-quote-board.ts +25 -5
- package/src/plugins/builtin/shared/volatility/options.ts +1 -46
- package/src/plugins/builtin/short-interest/index.tsx +19 -4
- package/src/plugins/builtin/short-interest/surface.tsx +4 -4
- package/src/plugins/builtin/short-volume/index.tsx +1 -10
- package/src/plugins/builtin/supply-chain/model.ts +1 -1
- package/src/plugins/builtin/ticker-detail/headless.ts +43 -21
- package/src/plugins/builtin/ticker-detail/pane.tsx +4 -5
- package/src/plugins/builtin/ticker-detail/quote-monitor/card.tsx +94 -6
- package/src/plugins/builtin/treasury-auctions/cache.ts +5 -2
- package/src/plugins/builtin/treasury-auctions/client.ts +22 -8
- package/src/plugins/builtin/treasury-auctions/headless.ts +40 -4
- package/src/plugins/builtin/treasury-auctions/index.tsx +11 -9
- package/src/plugins/builtin/treasury-auctions/model.ts +197 -30
- package/src/plugins/builtin/treasury-auctions/pane.tsx +35 -11
- package/src/plugins/builtin/treasury-auctions/types.ts +11 -1
- package/src/plugins/builtin/vol-surface/charts.tsx +1 -3
- package/src/plugins/builtin/vol-surface/client.ts +6 -2
- package/src/plugins/builtin/vol-surface/evidence.ts +11 -6
- package/src/plugins/builtin/vol-surface/headless.ts +124 -20
- package/src/plugins/builtin/vol-surface/model.ts +23 -11
- package/src/plugins/builtin/vol-surface/pane.tsx +38 -27
- package/src/plugins/builtin/vol-surface/tables.ts +124 -0
- package/src/plugins/builtin/world-indices/client.ts +22 -4
- package/src/plugins/builtin/world-indices/headless.ts +54 -27
- package/src/plugins/builtin/world-indices/model.ts +4 -2
- package/src/plugins/builtin/world-indices/table.tsx +13 -2
- package/src/plugins/builtin/world-venue-map/geo-series.ts +1 -1
- package/src/plugins/builtin/world-venue-map/index.ts +1 -1
- package/src/plugins/builtin/yield-curve/index.tsx +1 -1
- package/src/plugins/builtin-editorial.ts +126 -0
- package/src/plugins/catalog-backend.ts +16 -9
- package/src/plugins/catalog-browser.ts +127 -63
- package/src/plugins/catalog-manifest.ts +73 -40
- package/src/plugins/catalog-ui.ts +26 -6
- package/src/plugins/extracted-plugins.ts +7 -1
- package/src/plugins/ownership.ts +150 -7
- package/src/plugins/plugin-functions.ts +54 -0
- package/src/plugins/plugin-off.ts +36 -0
- package/src/plugins/registry/host-actions.ts +16 -0
- package/src/plugins/registry/index.ts +84 -24
- package/src/plugins/registry/plugin-state.ts +25 -1
- package/src/plugins/runtime/context.tsx +29 -0
- package/src/react/input.ts +48 -1
- package/src/remote/app-host.tsx +5 -0
- package/src/remote/controller.ts +3 -53
- package/src/remote/matching.ts +69 -0
- package/src/remote/schema.ts +1 -1
- package/src/remote/semantic-tree.tsx +14 -0
- package/src/remote/types.ts +2 -0
- package/src/renderers/dom/desktop/icons.tsx +14 -0
- package/src/renderers/dom/desktop/query-bar.tsx +59 -32
- package/src/renderers/dom/host/box.tsx +1 -1
- package/src/renderers/dom/host/drag-shield.ts +17 -6
- package/src/renderers/dom/host/live-frame.ts +10 -2
- package/src/renderers/dom/input-host.tsx +6 -1
- package/src/renderers/dom/styles.css +13 -0
- package/src/renderers/electrobun/bun/desktop/backend.ts +5 -1
- package/src/renderers/electrobun/bun/desktop/detached-windows.ts +12 -1
- package/src/renderers/electrobun/bun/desktop/initialization.ts +2 -1
- package/src/renderers/electrobun/shared/protocol.ts +2 -0
- package/src/renderers/electrobun/view/cli-pane-shot-entry.tsx +1 -1
- package/src/renderers/electrobun/view/cli-pane-shot-frame.tsx +101 -5
- package/src/renderers/electrobun/view/main.tsx +4 -1
- package/src/renderers/opentui/input-host.tsx +6 -1
- package/src/renderers/opentui/start.tsx +9 -0
- package/src/shares/portable-layout.ts +16 -6
- package/src/sources/gloomberb-cloud/index.ts +19 -10
- package/src/sources/gloomberb-cloud/normalizers.ts +4 -1
- package/src/sources/listing-symbols.ts +11 -5
- package/src/sources/provider-errors.ts +88 -3
- package/src/sources/provider-router/cached-routes.ts +8 -4
- package/src/sources/provider-router/financial-routes.ts +11 -5
- package/src/sources/provider-router/financials.ts +42 -15
- package/src/sources/provider-router/history.ts +27 -11
- package/src/sources/provider-router/index.ts +1 -1
- package/src/sources/provider-router/primary.ts +23 -5
- package/src/sources/sec-edgar.ts +68 -8
- package/src/sync/core-contributors.ts +4 -3
- package/src/test-support/cli-context.ts +2 -1
- package/src/test-support/data-provider.ts +34 -0
- package/src/test-support/shell-pane-keys.tsx +1 -0
- package/src/theme/series-colors.ts +46 -0
- package/src/theme/themes.ts +149 -0
- package/src/tickers/search/index.ts +22 -2
- package/src/tickers/search/ranking.ts +45 -1
- package/src/tickers/search/types.ts +3 -1
- package/src/time-series/resolve.ts +1 -14
- package/src/types/config.ts +61 -1
- package/src/types/headless.ts +11 -0
- package/src/types/instrument.ts +8 -0
- package/src/types/plugin.ts +49 -3
- package/src/ui/host.tsx +8 -4
- package/src/ui/index.tsx +2 -0
- package/src/utils/cli-output.ts +14 -1
- package/src/utils/exchanges.ts +13 -0
- package/src/utils/format.ts +2 -1
- package/src/utils/fx-market-hours.ts +34 -0
- package/src/utils/option-expiry.ts +126 -0
- package/src/utils/price-history.ts +39 -6
- package/src/utils/rpc-timeout-error.ts +6 -2
- package/src/utils/sec-eps-basis.ts +159 -30
- package/src/utils/sec.ts +38 -34
- package/src/utils/throttled-fetch.ts +51 -22
|
@@ -20,6 +20,8 @@ export interface ChatMessageRenderState {
|
|
|
20
20
|
replyAuthorColor: string;
|
|
21
21
|
headerStatus: string;
|
|
22
22
|
headerStatusColor: string;
|
|
23
|
+
/** The dim "Discord" tag beside the author of a message that came from Discord. */
|
|
24
|
+
originTagColor: string;
|
|
23
25
|
authorColor: string;
|
|
24
26
|
authorAttributes: number;
|
|
25
27
|
bodyColor: string;
|
|
@@ -82,6 +84,7 @@ export function getChatMessageRenderState({
|
|
|
82
84
|
: hasFailed
|
|
83
85
|
? colors.negative
|
|
84
86
|
: colors.textMuted,
|
|
87
|
+
originTagColor: isSelected ? selectedTextColor : colors.textDim,
|
|
85
88
|
authorColor: isSelected ? selectedTextColor : hasFailed ? colors.negative : colors.positive,
|
|
86
89
|
authorAttributes: (isSending ? TextAttributes.DIM : 0) | TextAttributes.BOLD,
|
|
87
90
|
bodyColor: isSelected ? selectedTextColor : hasFailed ? colors.negative : isSending ? colors.textDim : colors.text,
|
|
@@ -0,0 +1,60 @@
|
|
|
1
|
+
import { useSyncExternalStore } from "react";
|
|
2
|
+
|
|
3
|
+
/**
|
|
4
|
+
* Something a Chat pane should do once it has the keyboard, asked for from
|
|
5
|
+
* outside it: the command bar opens a conversation to write in, or the New DM
|
|
6
|
+
* dialog. The pane that is focused on that conversation takes it.
|
|
7
|
+
*/
|
|
8
|
+
export type ChatPaneRequest =
|
|
9
|
+
| { action: "compose"; channelId: string }
|
|
10
|
+
| { action: "new-dm" };
|
|
11
|
+
|
|
12
|
+
interface PendingChatPaneRequest {
|
|
13
|
+
request: ChatPaneRequest;
|
|
14
|
+
at: number;
|
|
15
|
+
}
|
|
16
|
+
|
|
17
|
+
/** A request no pane took by then (the pane never opened) must not fire later. */
|
|
18
|
+
const REQUEST_TTL_MS = 10_000;
|
|
19
|
+
|
|
20
|
+
let pending: PendingChatPaneRequest | null = null;
|
|
21
|
+
const listeners = new Set<() => void>();
|
|
22
|
+
|
|
23
|
+
function emit(): void {
|
|
24
|
+
for (const listener of listeners) listener();
|
|
25
|
+
}
|
|
26
|
+
|
|
27
|
+
export function requestChatPaneAction(request: ChatPaneRequest, now = Date.now()): void {
|
|
28
|
+
pending = { request, at: now };
|
|
29
|
+
emit();
|
|
30
|
+
}
|
|
31
|
+
|
|
32
|
+
/**
|
|
33
|
+
* Hands the request to the pane on `channelId` and clears it. Null when there
|
|
34
|
+
* is none for that pane or it went stale.
|
|
35
|
+
*/
|
|
36
|
+
export function takeChatPaneRequest(channelId: string, now = Date.now()): ChatPaneRequest | null {
|
|
37
|
+
if (!pending) return null;
|
|
38
|
+
const { request, at } = pending;
|
|
39
|
+
if (now - at > REQUEST_TTL_MS) {
|
|
40
|
+
pending = null;
|
|
41
|
+
emit();
|
|
42
|
+
return null;
|
|
43
|
+
}
|
|
44
|
+
if (request.action === "compose" && request.channelId !== channelId) return null;
|
|
45
|
+
pending = null;
|
|
46
|
+
emit();
|
|
47
|
+
return request;
|
|
48
|
+
}
|
|
49
|
+
|
|
50
|
+
function subscribe(listener: () => void): () => void {
|
|
51
|
+
listeners.add(listener);
|
|
52
|
+
return () => {
|
|
53
|
+
listeners.delete(listener);
|
|
54
|
+
};
|
|
55
|
+
}
|
|
56
|
+
|
|
57
|
+
/** The request waiting for a pane, so a pane can take it once it has the keyboard. */
|
|
58
|
+
export function usePendingChatPaneRequest(): ChatPaneRequest | null {
|
|
59
|
+
return useSyncExternalStore(subscribe, () => pending?.request ?? null);
|
|
60
|
+
}
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
import { updatePaneInstance } from "../../../pane-settings";
|
|
2
|
-
import { removePane } from "../../../layout/pane-manager";
|
|
3
|
-
import type { AppConfig } from "../../../types/config";
|
|
2
|
+
import { isPaneInLayout, removePane } from "../../../layout/pane-manager";
|
|
3
|
+
import type { AppConfig, LayoutConfig, PaneInstanceConfig } from "../../../types/config";
|
|
4
4
|
import { LAST_VISITED_CHAT_CHANNEL_KEY, normalizeChannelId } from "./channels";
|
|
5
5
|
|
|
6
6
|
type ChatPaneSettings = Record<string, unknown>;
|
|
@@ -32,6 +32,36 @@ export function clearChatPaneTargetMessage(
|
|
|
32
32
|
return nextSettings;
|
|
33
33
|
}
|
|
34
34
|
|
|
35
|
+
function paneChannelId(instance: PaneInstanceConfig): string | null {
|
|
36
|
+
return typeof instance.settings?.channelId === "string" ? normalizeChannelId(instance.settings.channelId) : null;
|
|
37
|
+
}
|
|
38
|
+
|
|
39
|
+
/**
|
|
40
|
+
* The Chat pane the command bar shows a conversation in: the one already on
|
|
41
|
+
* it, else the focused one, else the one in front. Null when none is open, so
|
|
42
|
+
* the caller opens one.
|
|
43
|
+
*/
|
|
44
|
+
export function pickChatPaneToReuse(
|
|
45
|
+
layout: LayoutConfig,
|
|
46
|
+
focusedPaneId: string | null,
|
|
47
|
+
channelId: string | null,
|
|
48
|
+
): PaneInstanceConfig | null {
|
|
49
|
+
const chatPanes = layout.instances.filter((instance) => (
|
|
50
|
+
instance.paneId === "chat" && isPaneInLayout(layout, instance.instanceId)
|
|
51
|
+
));
|
|
52
|
+
if (chatPanes.length === 0) return null;
|
|
53
|
+
const onChannel = channelId ? chatPanes.find((instance) => paneChannelId(instance) === channelId) : undefined;
|
|
54
|
+
if (onChannel) return onChannel;
|
|
55
|
+
const focused = chatPanes.find((instance) => instance.instanceId === focusedPaneId);
|
|
56
|
+
if (focused) return focused;
|
|
57
|
+
// A floating pane without a stacking order sits at the default of 50; docked panes sit below every one.
|
|
58
|
+
const zIndexOf = (instance: PaneInstanceConfig) => {
|
|
59
|
+
const entry = layout.floating.find((floating) => floating.instanceId === instance.instanceId);
|
|
60
|
+
return entry ? entry.zIndex ?? 50 : -1;
|
|
61
|
+
};
|
|
62
|
+
return [...chatPanes].sort((left, right) => zIndexOf(right) - zIndexOf(left))[0] ?? null;
|
|
63
|
+
}
|
|
64
|
+
|
|
35
65
|
function setChatPaneJump(
|
|
36
66
|
settings: ChatPaneSettings | undefined,
|
|
37
67
|
channelId: string,
|
|
@@ -77,6 +77,14 @@ export function ChatPane({ focused, width, height }: PaneProps) {
|
|
|
77
77
|
}, [dispatch, paneId, stateRef]);
|
|
78
78
|
const [channelId, setLocalChannelId] = useState(initialChannelIdRef.current);
|
|
79
79
|
const pendingChannelIdRef = useRef<string | null>(null);
|
|
80
|
+
// A channel set from outside the pane (the command bar, the unread list)
|
|
81
|
+
// usually arrives with focus. Taking it in the same render keeps the pane
|
|
82
|
+
// from showing the old channel focused for a frame, which marks it read.
|
|
83
|
+
const [followedChannelId, setFollowedChannelId] = useState(persistedChannelId);
|
|
84
|
+
if (followedChannelId !== persistedChannelId) {
|
|
85
|
+
setFollowedChannelId(persistedChannelId);
|
|
86
|
+
if (!pendingChannelIdRef.current && channelId !== persistedChannelId) setLocalChannelId(persistedChannelId);
|
|
87
|
+
}
|
|
80
88
|
|
|
81
89
|
useEffect(() => {
|
|
82
90
|
if (rawPaneChannelId) return;
|
|
@@ -8,18 +8,23 @@ import type { ASKGToolExecutor } from "./executor";
|
|
|
8
8
|
import {
|
|
9
9
|
activeTurn,
|
|
10
10
|
askgReducer,
|
|
11
|
+
canRateTurn,
|
|
11
12
|
EMPTY_ASKG_CONVERSATION,
|
|
12
13
|
isTurnRunning,
|
|
13
14
|
requiresLocalConfirmation,
|
|
14
15
|
type ASKGAction,
|
|
15
16
|
type ASKGConversationState,
|
|
16
17
|
type ASKGErrorState,
|
|
18
|
+
type ASKGTurnFeedback,
|
|
17
19
|
} from "./model";
|
|
18
20
|
import {
|
|
19
21
|
ASKG_CLIENT_CAPABILITIES,
|
|
20
22
|
ASKG_PROTOCOL_VERSION,
|
|
21
23
|
type ASKGCapabilities,
|
|
22
24
|
type ASKGClientDescriptor,
|
|
25
|
+
type ASKGFeedbackRating,
|
|
26
|
+
type ASKGFeedbackReason,
|
|
27
|
+
type ASKGFeedbackRequest,
|
|
23
28
|
type ASKGSessionContext,
|
|
24
29
|
type ASKGSessionStartResponse,
|
|
25
30
|
type ASKGSseEvent,
|
|
@@ -104,6 +109,16 @@ function turnCapabilities(session: ASKGSessionStartResponse): ASKGCapabilities |
|
|
|
104
109
|
return session.capabilities?.scripts === 1 ? { scripts: 1 } : null;
|
|
105
110
|
}
|
|
106
111
|
|
|
112
|
+
/**
|
|
113
|
+
* Refusals that say ratings cannot work from here at all: signed out, no plan
|
|
114
|
+
* that reaches Ask Gloom, or a protocol this build does not speak. The control
|
|
115
|
+
* goes away rather than failing on every click.
|
|
116
|
+
*/
|
|
117
|
+
function feedbackUnavailable(error: unknown): boolean {
|
|
118
|
+
return error instanceof ASKGTransportError
|
|
119
|
+
&& (error.code === "unauthorized" || error.code === "tier_required" || error.code === "protocol");
|
|
120
|
+
}
|
|
121
|
+
|
|
107
122
|
function errorState(error: unknown): ASKGErrorState {
|
|
108
123
|
if (error instanceof ASKGTransportError) {
|
|
109
124
|
return {
|
|
@@ -136,6 +151,10 @@ export class ASKGSessionController {
|
|
|
136
151
|
private readonly abandonedCalls = new Set<string>();
|
|
137
152
|
private readonly toolTasks = new Set<Promise<void>>();
|
|
138
153
|
private turnAbort: AbortController | null = null;
|
|
154
|
+
/** Ratings of one answer go out in the order they were made. */
|
|
155
|
+
private readonly feedbackQueues = new Map<string, Promise<void>>();
|
|
156
|
+
/** The latest rating request per answer; an older answer never wins. */
|
|
157
|
+
private readonly feedbackVersions = new Map<string, number>();
|
|
139
158
|
private disposed = false;
|
|
140
159
|
private readonly now: () => number;
|
|
141
160
|
private readonly createId: () => string;
|
|
@@ -188,6 +207,7 @@ export class ASKGSessionController {
|
|
|
188
207
|
model: session.model,
|
|
189
208
|
limits: session.limits,
|
|
190
209
|
acceptedTools: session.acceptedTools,
|
|
210
|
+
feedback: session.capabilities?.feedback === 1,
|
|
191
211
|
});
|
|
192
212
|
return session;
|
|
193
213
|
})();
|
|
@@ -311,14 +331,14 @@ export class ASKGSessionController {
|
|
|
311
331
|
}
|
|
312
332
|
|
|
313
333
|
/**
|
|
314
|
-
* Asks a failed question again. The
|
|
315
|
-
* above the retry, so a transcript reads as the conversation the
|
|
316
|
-
* rather than as a list of attempts.
|
|
334
|
+
* Asks a failed or stopped question again. The attempt is dropped rather
|
|
335
|
+
* than kept above the retry, so a transcript reads as the conversation the
|
|
336
|
+
* user had rather than as a list of attempts.
|
|
317
337
|
*/
|
|
318
338
|
async retryTurn(turnId: string): Promise<void> {
|
|
319
339
|
if (this.disposed || isTurnRunning(this.state)) return;
|
|
320
340
|
const turn = this.state.turns.find((entry) => entry.id === turnId);
|
|
321
|
-
if (!turn || turn.status !== "error") return;
|
|
341
|
+
if (!turn || (turn.status !== "error" && turn.status !== "cancelled")) return;
|
|
322
342
|
this.dispatch({ type: "drop-turn", turnId });
|
|
323
343
|
await this.ask(turn.prompt);
|
|
324
344
|
}
|
|
@@ -445,6 +465,94 @@ export class ASKGSessionController {
|
|
|
445
465
|
this.rejectPendingConfirmations();
|
|
446
466
|
}
|
|
447
467
|
|
|
468
|
+
/**
|
|
469
|
+
* Rates one answer. The control shows the choice at once; a refusal puts the
|
|
470
|
+
* previous one back without a word, because a rating is not worth an error.
|
|
471
|
+
* A thumbs down keeps the reason it already had, a thumbs up drops it.
|
|
472
|
+
*/
|
|
473
|
+
rateAnswer(turnId: string, rating: ASKGFeedbackRating): Promise<void> {
|
|
474
|
+
const current = this.state.turns.find((turn) => turn.id === turnId)?.feedback;
|
|
475
|
+
const reason = rating === "down" && current?.rating === "down" ? current.reason : null;
|
|
476
|
+
return this.sendFeedback(turnId, { rating, reason }, {
|
|
477
|
+
rating,
|
|
478
|
+
reason,
|
|
479
|
+
shared: current?.shared ?? false,
|
|
480
|
+
pending: "rating",
|
|
481
|
+
});
|
|
482
|
+
}
|
|
483
|
+
|
|
484
|
+
/** Says why an answer got a thumbs down. */
|
|
485
|
+
chooseFeedbackReason(turnId: string, reason: ASKGFeedbackReason): Promise<void> {
|
|
486
|
+
const current = this.state.turns.find((turn) => turn.id === turnId)?.feedback;
|
|
487
|
+
return this.sendFeedback(turnId, { rating: "down", reason }, {
|
|
488
|
+
rating: "down",
|
|
489
|
+
reason,
|
|
490
|
+
shared: current?.shared ?? false,
|
|
491
|
+
pending: "rating",
|
|
492
|
+
});
|
|
493
|
+
}
|
|
494
|
+
|
|
495
|
+
/**
|
|
496
|
+
* Sends one answer to Gloom with its rating. Only the consent travels: the
|
|
497
|
+
* platform copies the question, the answer and which tools ran from its own
|
|
498
|
+
* transcript, so nothing else on this machine can go with it.
|
|
499
|
+
*/
|
|
500
|
+
shareAnswer(turnId: string): Promise<void> {
|
|
501
|
+
const current = this.state.turns.find((turn) => turn.id === turnId)?.feedback;
|
|
502
|
+
if (!current?.rating || current.shared) return Promise.resolve();
|
|
503
|
+
return this.sendFeedback(
|
|
504
|
+
turnId,
|
|
505
|
+
{ rating: current.rating, reason: current.reason, share: true },
|
|
506
|
+
{ rating: current.rating, reason: current.reason, shared: false, pending: "share" },
|
|
507
|
+
);
|
|
508
|
+
}
|
|
509
|
+
|
|
510
|
+
private sendFeedback(
|
|
511
|
+
turnId: string,
|
|
512
|
+
request: ASKGFeedbackRequest,
|
|
513
|
+
optimistic: ASKGTurnFeedback,
|
|
514
|
+
): Promise<void> {
|
|
515
|
+
const turn = this.state.turns.find((entry) => entry.id === turnId);
|
|
516
|
+
if (this.disposed || !turn || !canRateTurn(this.state, turn) || !turn.remoteTurnId) {
|
|
517
|
+
return Promise.resolve();
|
|
518
|
+
}
|
|
519
|
+
const remoteTurnId = turn.remoteTurnId;
|
|
520
|
+
const previous = turn.feedback ? { ...turn.feedback, pending: null } : null;
|
|
521
|
+
const version = (this.feedbackVersions.get(turnId) ?? 0) + 1;
|
|
522
|
+
this.feedbackVersions.set(turnId, version);
|
|
523
|
+
this.dispatch({ type: "feedback", turnId, feedback: optimistic });
|
|
524
|
+
|
|
525
|
+
const send = async () => {
|
|
526
|
+
const latest = () => this.feedbackVersions.get(turnId) === version;
|
|
527
|
+
try {
|
|
528
|
+
const stored = await this.options.transport.sendFeedback(remoteTurnId, request);
|
|
529
|
+
if (!latest()) return;
|
|
530
|
+
if (!stored) {
|
|
531
|
+
// No answer of this person's under that id: nothing here can rate it.
|
|
532
|
+
this.dispatch({ type: "feedback", turnId, feedback: previous });
|
|
533
|
+
this.dispatch({ type: "feedback-unavailable" });
|
|
534
|
+
return;
|
|
535
|
+
}
|
|
536
|
+
this.dispatch({
|
|
537
|
+
type: "feedback",
|
|
538
|
+
turnId,
|
|
539
|
+
feedback: {
|
|
540
|
+
...stored,
|
|
541
|
+
pending: null,
|
|
542
|
+
...(request.share && !stored.shared ? { shareFailed: true } : {}),
|
|
543
|
+
},
|
|
544
|
+
});
|
|
545
|
+
} catch (error) {
|
|
546
|
+
if (!latest()) return;
|
|
547
|
+
this.dispatch({ type: "feedback", turnId, feedback: previous });
|
|
548
|
+
if (feedbackUnavailable(error)) this.dispatch({ type: "feedback-unavailable" });
|
|
549
|
+
}
|
|
550
|
+
};
|
|
551
|
+
const queued = (this.feedbackQueues.get(turnId) ?? Promise.resolve()).then(send);
|
|
552
|
+
this.feedbackQueues.set(turnId, queued);
|
|
553
|
+
return queued;
|
|
554
|
+
}
|
|
555
|
+
|
|
448
556
|
setExpanded(toolCallId: string, expanded: boolean): void {
|
|
449
557
|
this.dispatch({ type: "tool-expanded", toolCallId, expanded });
|
|
450
558
|
}
|
|
@@ -46,6 +46,7 @@ export class ASKGConversationListStore {
|
|
|
46
46
|
private persistence: PluginPersistence | null = null;
|
|
47
47
|
private transport: ASKGTransport | null = null;
|
|
48
48
|
private inFlight: Promise<void> | null = null;
|
|
49
|
+
private openConversationId: string | null = null;
|
|
49
50
|
|
|
50
51
|
getSnapshot(): ASKGConversationListSnapshot {
|
|
51
52
|
return this.snapshot;
|
|
@@ -126,6 +127,7 @@ export class ASKGConversationListStore {
|
|
|
126
127
|
async delete(id: string): Promise<void> {
|
|
127
128
|
const transport = this.transport;
|
|
128
129
|
if (!transport) return;
|
|
130
|
+
if (this.openConversationId === id) this.openConversationId = null;
|
|
129
131
|
const previous = this.snapshot.conversations;
|
|
130
132
|
this.remove(id);
|
|
131
133
|
try {
|
|
@@ -178,11 +180,30 @@ export class ASKGConversationListStore {
|
|
|
178
180
|
this.persistence?.setState(WIDTH_STATE_KEY, width);
|
|
179
181
|
}
|
|
180
182
|
|
|
183
|
+
/**
|
|
184
|
+
* The conversation an Ask Gloom pane last showed. Closing the pane (Esc Esc
|
|
185
|
+
* is two keys) must not lose the answer on screen, so the next pane this
|
|
186
|
+
* app session opens picks it up again. Kept in memory only: a fresh launch
|
|
187
|
+
* starts a fresh conversation, and every older one is in the list.
|
|
188
|
+
*/
|
|
189
|
+
rememberOpen(id: string | null): void {
|
|
190
|
+
this.openConversationId = id;
|
|
191
|
+
}
|
|
192
|
+
|
|
193
|
+
rememberedOpen(): string | null {
|
|
194
|
+
const id = this.openConversationId;
|
|
195
|
+
if (!id) return null;
|
|
196
|
+
// A conversation deleted since is not brought back.
|
|
197
|
+
if (this.snapshot.loaded && !this.snapshot.conversations.some((conversation) => conversation.id === id)) return null;
|
|
198
|
+
return id;
|
|
199
|
+
}
|
|
200
|
+
|
|
181
201
|
/** Test hook: drops the persisted handle, the transport and the rows. */
|
|
182
202
|
reset(): void {
|
|
183
203
|
this.persistence = null;
|
|
184
204
|
this.transport = null;
|
|
185
205
|
this.inFlight = null;
|
|
206
|
+
this.openConversationId = null;
|
|
186
207
|
this.snapshot = EMPTY;
|
|
187
208
|
}
|
|
188
209
|
|