gloomberb 0.16.5 → 0.17.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/package.json +3 -1
- package/src/api-client/central-bank-rates.ts +6 -1
- package/src/api-client/chat-pane-link.ts +47 -0
- package/src/api-client/chat.ts +35 -1
- package/src/api-client/credit-boards.ts +2 -0
- package/src/api-client/data.ts +85 -1
- package/src/api-client/equity-screener.ts +3 -0
- package/src/api-client/europe-energy.ts +197 -0
- package/src/api-client/index.ts +15 -0
- package/src/api-client/letters.ts +41 -0
- package/src/api-client/market-discovery.ts +3 -0
- package/src/api-client/normalizers.ts +68 -6
- package/src/api-client/organization-tickers.ts +44 -0
- package/src/api-client/perps.ts +8 -0
- package/src/api-client/request.ts +11 -2
- package/src/api-client/socket.ts +29 -0
- package/src/api-client/themes.ts +22 -1
- package/src/api-client/types.ts +88 -2
- package/src/app/global-shortcuts.ts +35 -1
- package/src/app/keybindings/actions.ts +12 -1
- package/src/app/pane-runtime/plugin-bindings.ts +2 -2
- package/src/app/pane-runtime/ticker-open-runtime.ts +9 -3
- package/src/app/runtime/desktop-deeplink.ts +58 -20
- package/src/app/runtime/startup.ts +1 -1
- package/src/app.tsx +6 -0
- package/src/architecture/core-builtin-allowlist.json +5 -14
- package/src/architecture/dom-cell-metrics-allowlist.json +28 -0
- package/src/ask-gloom/pane-context.ts +118 -0
- package/src/ask-gloom/pane-request.ts +70 -0
- package/src/ask-gloom/pane-text.ts +201 -0
- package/src/capabilities/chart-series.ts +8 -1
- package/src/capabilities/factories.ts +1 -0
- package/src/cli/central-bank-events.ts +23 -0
- package/src/cli/command-options.ts +17 -5
- package/src/cli/commands/crypto-hints.ts +28 -2
- package/src/cli/commands/fred-series.ts +155 -4
- package/src/cli/commands/market.ts +175 -35
- package/src/cli/commands/overview.ts +62 -20
- package/src/cli/commands/search.ts +254 -23
- package/src/cli/commands/ticker.ts +137 -24
- package/src/cli/desktop-pane-shot-view.ts +114 -0
- package/src/cli/desktop-pane-shot.ts +53 -37
- package/src/cli/entry.ts +7 -0
- package/src/cli/errors.ts +7 -5
- package/src/cli/exit-codes.ts +8 -0
- package/src/cli/export-source.ts +101 -0
- package/src/cli/freshness.ts +18 -3
- package/src/cli/glossary.ts +79 -8
- package/src/cli/help.ts +10 -0
- package/src/cli/helpers.ts +2 -5
- package/src/cli/history-rows.ts +244 -13
- package/src/cli/index.ts +9 -3
- package/src/cli/known-gaps.ts +76 -8
- package/src/cli/listing-arg.ts +201 -90
- package/src/cli/listing-suggestion.ts +159 -0
- package/src/cli/native-smoke.ts +13 -0
- package/src/cli/not-a-ticker.ts +24 -4
- package/src/cli/pane-functions/access-gate.ts +8 -2
- package/src/cli/pane-functions/capabilities.ts +17 -9
- package/src/cli/pane-functions/catalog.ts +183 -39
- package/src/cli/pane-functions/data.ts +30 -0
- package/src/cli/pane-functions/dom.ts +44 -14
- package/src/cli/pane-functions/freshness.ts +48 -24
- package/src/cli/pane-functions/function-help.ts +66 -12
- package/src/cli/pane-functions/headless.ts +81 -22
- package/src/cli/pane-functions/index.ts +90 -18
- package/src/cli/pane-functions/options.ts +8 -0
- package/src/cli/pane-functions/report-notices.ts +6 -3
- package/src/cli/pane-functions/report.ts +16 -2
- package/src/cli/pane-functions/resolver.ts +32 -11
- package/src/cli/pane-functions/screenshot.ts +145 -9
- package/src/cli/perpetual-contract.ts +60 -0
- package/src/cli/registry.ts +3 -1
- package/src/cli/report-tables.ts +53 -13
- package/src/cli/result.ts +91 -17
- package/src/cli/series-search.ts +111 -0
- package/src/cli/staged-tickers.ts +1 -1
- package/src/cli/symbol-args.ts +18 -0
- package/src/cli/symbol-list.ts +1 -19
- package/src/cli/symbol-rows.ts +171 -0
- package/src/cli/ticker-resolution.ts +99 -8
- package/src/components/chart/composite/axis-overlays.tsx +10 -1
- package/src/components/chart/composite/composite-chart.tsx +24 -15
- package/src/components/chart/composite/downsample.ts +1 -1
- package/src/components/chart/composite/format.ts +29 -0
- package/src/components/chart/composite/interactions.ts +9 -2
- package/src/components/chart/composite/legend.tsx +57 -33
- package/src/components/chart/composite/panel-bitmap.ts +70 -35
- package/src/components/chart/composite/panel-labels.ts +18 -17
- package/src/components/chart/composite/panel-series.ts +1 -0
- package/src/components/chart/composite/panel-surface.tsx +6 -8
- package/src/components/chart/composite/price-axis-labels.tsx +1 -0
- package/src/components/chart/composite/rasterizer.ts +50 -8
- package/src/components/chart/composite/scene.ts +2 -1
- package/src/components/chart/composite/time-scale.ts +26 -9
- package/src/components/chart/composite/types.ts +18 -0
- package/src/components/chart/composite/use-composite-viewport.ts +30 -2
- package/src/components/chart/native/raster/crosshair.ts +8 -3
- package/src/components/chart/native/raster/primitives.ts +85 -21
- package/src/components/chart/native/surface/manager.ts +33 -8
- package/src/components/chart/surface3d/chart.tsx +1 -1
- package/src/components/command-bar/action-runtime.ts +1 -1
- package/src/components/command-bar/commands/collection-list.ts +210 -0
- package/src/components/command-bar/commands/collection.ts +40 -1
- package/src/components/command-bar/commands/direct/index.ts +4 -0
- package/src/components/command-bar/commands/registry.ts +8 -0
- package/src/components/command-bar/list/model.ts +2 -0
- package/src/components/command-bar/pane-templates/items.ts +1 -1
- package/src/components/command-bar/routes/root/plugin-install.ts +4 -4
- package/src/components/command-bar/routes/ticker-search/actions.ts +1 -0
- package/src/components/command-bar/routes/ticker-search/results.ts +3 -1
- package/src/components/command-bar/routing/actions.ts +1 -1
- package/src/components/command-bar/workflow/ops.ts +8 -97
- package/src/components/command-bar/workflow/pane-reuse.ts +177 -0
- package/src/components/command-bar/workflow/tickers.ts +35 -29
- package/src/components/data-table/view.tsx +1 -0
- package/src/components/feed-data-table/stack-view.tsx +18 -42
- package/src/components/layout/detached-pane-shell.tsx +59 -39
- package/src/components/layout/floating-pane.tsx +7 -1
- package/src/components/layout/header.tsx +5 -0
- package/src/components/layout/missing-pane.tsx +5 -3
- package/src/components/layout/pane/capture-stamp.ts +41 -0
- package/src/components/layout/pane/capture-status.ts +12 -0
- package/src/components/layout/pane/footer/keyboard.ts +3 -0
- package/src/components/layout/pane/footer/model.ts +7 -1
- package/src/components/layout/pane/header.tsx +26 -0
- package/src/components/layout/pane/index.tsx +9 -1
- package/src/components/layout/pane/sidebar.tsx +10 -11
- package/src/components/layout/shell/cursor-occlusion.ts +2 -1
- package/src/components/layout/shell/index.tsx +62 -60
- package/src/components/layout/shell/menu.ts +9 -1
- package/src/components/layout/shell/pane/actions.ts +32 -10
- package/src/components/layout/shell/pane/ask.ts +136 -0
- package/src/components/layout/shell/pane/capture.ts +136 -0
- package/src/components/layout/shell/pane/layers.tsx +26 -5
- package/src/components/layout/shell/pane/management-shortcuts.ts +46 -1
- package/src/components/layout/shell/shortcuts.ts +21 -4
- package/src/components/markdown-text.tsx +37 -6
- package/src/components/metric-treemap/heat-surface.tsx +1 -3
- package/src/components/reader/article-reader.tsx +467 -0
- package/src/components/reader/article-text.ts +527 -0
- package/src/components/reader/detail-reader.tsx +210 -0
- package/src/components/reader/reader-text.tsx +239 -0
- package/src/components/table-view-shared.tsx +8 -4
- package/src/components/ticker/badge/list.tsx +15 -4
- package/src/components/ticker/list-table-view.tsx +19 -1
- package/src/components/ui/choice-dialog.tsx +3 -0
- package/src/components/ui/data-table/index.tsx +1 -0
- package/src/components/ui/data-table/types.ts +7 -0
- package/src/components/ui/detail-scroll-body.tsx +31 -4
- package/src/components/ui/display.tsx +46 -1
- package/src/components/ui/icon.tsx +14 -1
- package/src/components/ui/list-view.tsx +3 -1
- package/src/components/ui/query-bar-keys.tsx +2 -0
- package/src/components/ui/query-bar.tsx +18 -1
- package/src/components/ui/select-button.tsx +3 -0
- package/src/data/config/store/fold-panes.ts +202 -11
- package/src/data/config/store/migrations.ts +20 -1
- package/src/data/config/store/portfolio-as-of-column.ts +57 -0
- package/src/docs/snapshot.json +191 -23
- package/src/i18n/es.ts +18 -1
- package/src/i18n/ja.ts +18 -1
- package/src/i18n/ko.ts +18 -1
- package/src/i18n/zh-cn.ts +18 -1
- package/src/i18n/zh-tw.ts +18 -1
- package/src/layout/desk-keys.ts +7 -0
- package/src/layout/desks.ts +2 -2
- package/src/layout-marketplace/gallery.tsx +1 -1
- package/src/market-data/market/freshness.ts +3 -2
- package/src/market-data/market/session-close-note.ts +3 -2
- package/src/market-data/market/status.ts +67 -6
- package/src/market-data/quotes/contributions.ts +17 -0
- package/src/market-data/quotes/metadata.ts +12 -0
- package/src/market-data/quotes/regular-session-valuation.ts +131 -0
- package/src/market-data/quotes/resolution.ts +7 -0
- package/src/market-data/snapshot-provider.ts +6 -3
- package/src/notifications/app-badge.ts +30 -0
- package/src/notifications/app-notifier.ts +17 -1
- package/src/notifications/notification-log.ts +180 -0
- package/src/plugins/auto-update-node.ts +2 -2
- package/src/plugins/auto-update.ts +2 -2
- package/src/plugins/builtin/account-management/calendar-tab.tsx +1 -1
- package/src/plugins/builtin/account-management/form-components.tsx +53 -1
- package/src/plugins/builtin/account-management/index.tsx +1 -0
- package/src/plugins/builtin/account-management/keyboard.ts +5 -0
- package/src/plugins/builtin/account-management/model.ts +27 -0
- package/src/plugins/builtin/account-management/pane.tsx +62 -2
- package/src/plugins/builtin/alerts/catalysts.ts +1 -1
- package/src/plugins/builtin/alerts/cli.ts +6 -4
- package/src/plugins/builtin/alerts/focus.ts +27 -0
- package/src/plugins/builtin/alerts/index.tsx +6 -2
- package/src/plugins/builtin/alerts/pane.tsx +19 -1
- package/src/plugins/builtin/analytics/index.tsx +5 -2
- package/src/plugins/builtin/analytics/risk-headless.ts +30 -15
- package/src/plugins/builtin/attention/headless.ts +1 -1
- package/src/plugins/builtin/awards/headless.ts +88 -18
- package/src/plugins/builtin/awards/model.ts +41 -1
- package/src/plugins/builtin/awards/pane.tsx +48 -30
- package/src/plugins/builtin/backtest/headless.ts +2 -2
- package/src/plugins/builtin/backtest/pane.tsx +2 -1
- package/src/plugins/builtin/bond-calculator/index.tsx +3 -5
- package/src/plugins/builtin/broker-manager/index.tsx +1 -0
- package/src/plugins/builtin/buildout/detail/company.tsx +7 -4
- package/src/plugins/builtin/builtin-plugin-meta.ts +5 -4
- package/src/plugins/builtin/catalysts/headless.ts +1 -1
- package/src/plugins/builtin/catalysts/model.ts +92 -10
- package/src/plugins/builtin/catalysts/pane.tsx +6 -4
- package/src/plugins/builtin/cds/client.ts +11 -31
- package/src/plugins/builtin/cds/headless.ts +5 -2
- package/src/plugins/builtin/cds/index.tsx +21 -30
- package/src/plugins/builtin/cds/model.ts +21 -1
- package/src/plugins/builtin/cds/pane.tsx +6 -4
- package/src/plugins/builtin/central-bank-rates/client.ts +4 -0
- package/src/plugins/builtin/central-bank-rates/headless.ts +46 -16
- package/src/plugins/builtin/central-bank-rates/index.tsx +1 -1
- package/src/plugins/builtin/central-bank-rates/model.ts +99 -0
- package/src/plugins/builtin/central-bank-rates/pane.tsx +1 -1
- package/src/plugins/builtin/central-bank-rates/series.ts +19 -25
- package/src/plugins/builtin/changelog/index.tsx +11 -12
- package/src/plugins/builtin/chart-composer/catalog-inventory.ts +1 -0
- package/src/plugins/builtin/chart-composer/headless-schema.ts +3 -1
- package/src/plugins/builtin/chart-composer/headless.ts +151 -9
- package/src/plugins/builtin/chart-composer/index.tsx +6 -1
- package/src/plugins/builtin/chart-composer/pane.tsx +84 -40
- package/src/plugins/builtin/chart-composer/session-history.ts +20 -5
- package/src/plugins/builtin/chat/command-bar.ts +6 -8
- package/src/plugins/builtin/chat/content/composer-runtime.ts +6 -1
- package/src/plugins/builtin/chat/content/composer.tsx +15 -2
- package/src/plugins/builtin/chat/content/footer.tsx +27 -5
- package/src/plugins/builtin/chat/content/handle-prompt.tsx +326 -0
- package/src/plugins/builtin/chat/content/index.tsx +201 -13
- package/src/plugins/builtin/chat/content/layout-metrics.ts +4 -0
- package/src/plugins/builtin/chat/content/new-messages.tsx +89 -0
- package/src/plugins/builtin/chat/content/open-targets.ts +20 -4
- package/src/plugins/builtin/chat/content/row-activity.ts +132 -0
- package/src/plugins/builtin/chat/content/scroll.ts +133 -28
- package/src/plugins/builtin/chat/content/shortcuts.ts +2 -2
- package/src/plugins/builtin/chat/content/transcript.tsx +155 -79
- package/src/plugins/builtin/chat/content/types.ts +1 -0
- package/src/plugins/builtin/chat/controller/fetch.ts +8 -2
- package/src/plugins/builtin/chat/controller/index.ts +121 -1
- package/src/plugins/builtin/chat/controller/message-loading.ts +3 -0
- package/src/plugins/builtin/chat/controller/messages.ts +7 -2
- package/src/plugins/builtin/chat/controller/realtime.ts +10 -1
- package/src/plugins/builtin/chat/controller/send.ts +61 -1
- package/src/plugins/builtin/chat/controller/state.ts +8 -0
- package/src/plugins/builtin/chat/ghost-user.ts +20 -0
- package/src/plugins/builtin/chat/handle-prompt.ts +128 -0
- package/src/plugins/builtin/chat/index.tsx +66 -25
- package/src/plugins/builtin/chat/layout.ts +84 -18
- package/src/plugins/builtin/chat/message/desktop.tsx +111 -14
- package/src/plugins/builtin/chat/message/header.tsx +81 -21
- package/src/plugins/builtin/chat/message/pane-chip.tsx +223 -0
- package/src/plugins/builtin/chat/message/person-icons.tsx +53 -0
- package/src/plugins/builtin/chat/message/profile-popover.tsx +77 -9
- package/src/plugins/builtin/chat/message/reactions.tsx +210 -0
- package/src/plugins/builtin/chat/message/render-state.ts +33 -4
- package/src/plugins/builtin/chat/message/terminal.tsx +72 -8
- package/src/plugins/builtin/chat/message/types.ts +15 -0
- package/src/plugins/builtin/chat/pane-links/model.ts +149 -0
- package/src/plugins/builtin/chat/pane-links/open.ts +29 -0
- package/src/plugins/builtin/chat/pane-links/previews.ts +119 -0
- package/src/plugins/builtin/chat/pane-state.ts +5 -8
- package/src/plugins/builtin/chat/people.ts +202 -0
- package/src/plugins/builtin/chat/profile-popover.ts +18 -2
- package/src/plugins/builtin/chat/reactions.ts +197 -0
- package/src/plugins/builtin/chat/share/flow.tsx +87 -0
- package/src/plugins/builtin/chat/share/targets.ts +27 -0
- package/src/plugins/builtin/chat/status-widget.tsx +7 -9
- package/src/plugins/builtin/chat/unread-badge.ts +65 -0
- package/src/plugins/builtin/chat/unread-inbox-pane.tsx +151 -27
- package/src/plugins/builtin/chat/unread-inbox.ts +22 -0
- package/src/plugins/builtin/clinical-trials/client.ts +26 -1
- package/src/plugins/builtin/clinical-trials/index.tsx +10 -2
- package/src/plugins/builtin/clinical-trials/model.ts +269 -0
- package/src/plugins/builtin/clinical-trials/pane.tsx +247 -62
- package/src/plugins/builtin/clinical-trials/sponsor-tickers.ts +156 -0
- package/src/plugins/builtin/cloud/askg/attached-pane.tsx +69 -0
- package/src/plugins/builtin/cloud/askg/pane-attachment.ts +94 -0
- package/src/plugins/builtin/cloud/askg/pane.tsx +141 -12
- package/src/plugins/builtin/cloud/askg/pending-question.ts +11 -0
- package/src/plugins/builtin/cloud/mcp-connect/dialog.tsx +1 -0
- package/src/plugins/builtin/cloud/plugin.tsx +19 -2
- package/src/plugins/builtin/cloud/team/model.ts +5 -0
- package/src/plugins/builtin/cloud/team/module.tsx +1 -0
- package/src/plugins/builtin/cloud/team/store.ts +8 -3
- package/src/plugins/builtin/cloud/thesis/module.tsx +1 -0
- package/src/plugins/builtin/comment-letters/pane.tsx +30 -11
- package/src/plugins/builtin/commodities-energy/index.tsx +179 -0
- package/src/plugins/builtin/commodity-balances/client.ts +208 -0
- package/src/plugins/builtin/commodity-balances/headless.ts +66 -0
- package/src/plugins/builtin/commodity-balances/index.tsx +32 -0
- package/src/plugins/builtin/commodity-balances/model.ts +261 -0
- package/src/plugins/builtin/commodity-balances/pane.tsx +227 -0
- package/src/plugins/builtin/company-attention/headless.ts +2 -2
- package/src/plugins/builtin/company-kpis/headless.ts +97 -10
- package/src/plugins/builtin/company-kpis/model.ts +24 -2
- package/src/plugins/builtin/company-kpis/pane.tsx +13 -14
- package/src/plugins/builtin/composite-plugins.ts +26 -1
- package/src/plugins/builtin/connections/index.ts +1 -0
- package/src/plugins/builtin/cot/headless.ts +1 -1
- package/src/plugins/builtin/cpi/headless.ts +3 -3
- package/src/plugins/builtin/credit-boards/cdx-pane.tsx +10 -1
- package/src/plugins/builtin/credit-boards/client.ts +6 -2
- package/src/plugins/builtin/credit-boards/headless.ts +108 -31
- package/src/plugins/builtin/credit-boards/index.tsx +21 -42
- package/src/plugins/builtin/credit-boards/model.ts +11 -3
- package/src/plugins/builtin/credit-conditions/client.ts +12 -9
- package/src/plugins/builtin/credit-conditions/headless.ts +13 -2
- package/src/plugins/builtin/credit-conditions/index.tsx +20 -22
- package/src/plugins/builtin/credit-conditions/model.ts +19 -11
- package/src/plugins/builtin/credit-conditions/series.ts +8 -18
- package/src/plugins/builtin/credit-documents/headless.ts +2 -2
- package/src/plugins/builtin/credit-documents/index.tsx +27 -10
- package/src/plugins/builtin/debt-maturities/headless.ts +17 -11
- package/src/plugins/builtin/debt-maturities/index.tsx +3 -17
- package/src/plugins/builtin/debug/index.tsx +2 -2
- package/src/plugins/builtin/dividend-yield/client.ts +6 -1
- package/src/plugins/builtin/dividend-yield/headless.ts +8 -3
- package/src/plugins/builtin/dividend-yield/index.tsx +1 -1
- package/src/plugins/builtin/dividend-yield/pane.tsx +6 -2
- package/src/plugins/builtin/dividend-yield/provider-client.ts +3 -1
- package/src/plugins/builtin/dividend-yield/types.ts +2 -0
- package/src/plugins/builtin/docs/blocks.tsx +4 -3
- package/src/plugins/builtin/docs/pane.tsx +16 -8
- package/src/plugins/builtin/doe/headless.ts +12 -8
- package/src/plugins/builtin/earnings/index.tsx +11 -0
- package/src/plugins/builtin/earnings-calls/headless.ts +28 -2
- package/src/plugins/builtin/earnings-calls/index.tsx +1 -1
- package/src/plugins/builtin/earnings-calls/pane.tsx +2 -12
- package/src/plugins/builtin/earnings-ripple/index.tsx +2 -0
- package/src/plugins/builtin/econ/fred-catalog.ts +9 -0
- package/src/plugins/builtin/equity-screener/client.ts +1 -1
- package/src/plugins/builtin/equity-screener/headless.ts +39 -5
- package/src/plugins/builtin/equity-screener/model.ts +121 -68
- package/src/plugins/builtin/estimate-revisions/headless.ts +3 -3
- package/src/plugins/builtin/executives/pane.tsx +3 -1
- package/src/plugins/builtin/exposure/drivers.ts +13 -0
- package/src/plugins/builtin/exposure/headless.ts +205 -13
- package/src/plugins/builtin/exposure/index.tsx +1 -0
- package/src/plugins/builtin/exposure/model.ts +23 -3
- package/src/plugins/builtin/exposure/pane.tsx +11 -11
- package/src/plugins/builtin/fear-greed/index.tsx +14 -10
- package/src/plugins/builtin/filing-events/index.tsx +20 -0
- package/src/plugins/builtin/fixed-income/index.tsx +46 -0
- package/src/plugins/builtin/fixed-income/model.ts +27 -0
- package/src/plugins/builtin/fixed-income/pane.tsx +162 -0
- package/src/plugins/builtin/fixed-income/shortcut.ts +52 -0
- package/src/plugins/builtin/futures/index.tsx +24 -7
- package/src/plugins/builtin/futures/series.ts +23 -2
- package/src/plugins/builtin/futures/use-front-returns.ts +3 -2
- package/src/plugins/builtin/futures-curve/headless.ts +1 -1
- package/src/plugins/builtin/futures-curve/index.tsx +1 -1
- package/src/plugins/builtin/futures-curve/pane.tsx +6 -4
- package/src/plugins/builtin/fx-matrix/client.ts +63 -0
- package/src/plugins/builtin/fx-matrix/export.ts +2 -1
- package/src/plugins/builtin/fx-matrix/headless.ts +154 -0
- package/src/plugins/builtin/fx-matrix/index.tsx +3 -3
- package/src/plugins/builtin/gpu/headless.ts +4 -4
- package/src/plugins/builtin/help/function-index.ts +2 -0
- package/src/plugins/builtin/help/index.tsx +14 -1
- package/src/plugins/builtin/help/shortcut-table.tsx +4 -2
- package/src/plugins/builtin/insider/detail.tsx +20 -12
- package/src/plugins/builtin/insider/index.tsx +2 -2
- package/src/plugins/builtin/ipo-calendar/headless.ts +1 -1
- package/src/plugins/builtin/iv-history/client.ts +6 -2
- package/src/plugins/builtin/iv-history/format.ts +9 -0
- package/src/plugins/builtin/iv-history/headless.ts +50 -18
- package/src/plugins/builtin/iv-history/index.tsx +3 -0
- package/src/plugins/builtin/iv-history/model.ts +35 -4
- package/src/plugins/builtin/iv-history/screen-pane.tsx +13 -5
- package/src/plugins/builtin/jobs/headless.ts +6 -8
- package/src/plugins/builtin/jodi/client.ts +220 -0
- package/src/plugins/builtin/jodi/headless.ts +63 -0
- package/src/plugins/builtin/jodi/index.tsx +32 -0
- package/src/plugins/builtin/jodi/model.ts +75 -0
- package/src/plugins/builtin/jodi/pane.tsx +141 -0
- package/src/plugins/builtin/kelly-sizer/index.tsx +2 -0
- package/src/plugins/builtin/market-heatmap/evidence.ts +13 -4
- package/src/plugins/builtin/market-heatmap/headless.ts +22 -7
- package/src/plugins/builtin/market-heatmap/index.tsx +47 -23
- package/src/plugins/builtin/market-heatmap/live.ts +2 -1
- package/src/plugins/builtin/market-heatmap/portfolio.ts +67 -21
- package/src/plugins/builtin/market-movers/table.ts +2 -2
- package/src/plugins/builtin/market-valuation/align.ts +10 -9
- package/src/plugins/builtin/members/headless.ts +1 -1
- package/src/plugins/builtin/members/pane.tsx +3 -2
- package/src/plugins/builtin/mna/distress/headless.ts +4 -4
- package/src/plugins/builtin/mna/distress/model.ts +52 -1
- package/src/plugins/builtin/mna/distress/pane.tsx +17 -12
- package/src/plugins/builtin/mna/headless.ts +3 -3
- package/src/plugins/builtin/mna/index.tsx +2 -0
- package/src/plugins/builtin/money-markets/headless.ts +5 -4
- package/src/plugins/builtin/news/index.tsx +0 -2
- package/src/plugins/builtin/news/wire/index.tsx +2 -2
- package/src/plugins/builtin/news/wire/industry-pane.tsx +28 -14
- package/src/plugins/builtin/news/wire/letters/client.ts +108 -0
- package/src/plugins/builtin/news/wire/letters/model.ts +69 -0
- package/src/plugins/builtin/news/wire/letters/pane.tsx +155 -0
- package/src/plugins/builtin/news/wire/mutes.ts +2 -1
- package/src/plugins/builtin/news/wire/news/detail-view.tsx +53 -104
- package/src/plugins/builtin/news/wire/news/footer.ts +2 -25
- package/src/plugins/builtin/news/wire/news/preset-pane.tsx +0 -2
- package/src/plugins/builtin/news/wire/news/query-presets.ts +4 -1
- package/src/plugins/builtin/notes/index.tsx +1 -0
- package/src/plugins/builtin/openfda/client.ts +123 -15
- package/src/plugins/builtin/openfda/model.ts +163 -0
- package/src/plugins/builtin/openfda/pane.tsx +109 -65
- package/src/plugins/builtin/openfda/types.ts +25 -0
- package/src/plugins/builtin/options/index.tsx +3 -0
- package/src/plugins/builtin/options/view.tsx +1 -1
- package/src/plugins/builtin/options-positioning/headless.ts +3 -3
- package/src/plugins/builtin/pe-band/model.ts +3 -2
- package/src/plugins/builtin/perps/client.ts +50 -10
- package/src/plugins/builtin/perps/equity-row.tsx +29 -16
- package/src/plugins/builtin/perps/headless.ts +2 -2
- package/src/plugins/builtin/perps/index.tsx +5 -3
- package/src/plugins/builtin/perps/list-perpetuals.ts +118 -0
- package/src/plugins/builtin/perps/open-market.ts +15 -0
- package/src/plugins/builtin/plugin-marketplace/index.tsx +1 -1
- package/src/plugins/builtin/plugin-marketplace/pane.tsx +7 -7
- package/src/plugins/builtin/plugin-module.ts +3 -1
- package/src/plugins/builtin/portfolio-list/allocation.ts +5 -4
- package/src/plugins/builtin/portfolio-list/cell-version.ts +8 -1
- package/src/plugins/builtin/portfolio-list/cli/bulk-symbols.ts +24 -136
- package/src/plugins/builtin/portfolio-list/cli/portfolio-command.ts +78 -19
- package/src/plugins/builtin/portfolio-list/cli/render.ts +249 -52
- package/src/plugins/builtin/portfolio-list/cli/shared.ts +44 -12
- package/src/plugins/builtin/portfolio-list/cli/watchlist-command.ts +21 -7
- package/src/plugins/builtin/portfolio-list/column-values.ts +103 -25
- package/src/plugins/builtin/portfolio-list/headless.ts +51 -15
- package/src/plugins/builtin/portfolio-list/index.tsx +5 -1
- package/src/plugins/builtin/portfolio-list/live-valuation.ts +25 -13
- package/src/plugins/builtin/portfolio-list/mutations.ts +2 -9
- package/src/plugins/builtin/portfolio-list/pane/data.ts +5 -1
- package/src/plugins/builtin/portfolio-list/pane/index.tsx +46 -8
- package/src/plugins/builtin/portfolio-list/quick-add/index.tsx +16 -10
- package/src/plugins/builtin/portfolio-list/quick-add/resolution.ts +21 -1
- package/src/plugins/builtin/portfolio-list/settings.ts +17 -0
- package/src/plugins/builtin/portfolio-list/summary/index.tsx +12 -0
- package/src/plugins/builtin/portfolio-list/summary/totals.ts +8 -3
- package/src/plugins/builtin/portfolio-list/table.tsx +30 -6
- package/src/plugins/builtin/power/evidence.ts +86 -8
- package/src/plugins/builtin/power/gas-client.ts +110 -0
- package/src/plugins/builtin/power/gas-model.ts +194 -0
- package/src/plugins/builtin/power/gas.tsx +145 -0
- package/src/plugins/builtin/power/headless.ts +9 -2
- package/src/plugins/builtin/power/index.tsx +35 -3
- package/src/plugins/builtin/power/model.ts +2 -2
- package/src/plugins/builtin/power/pane.tsx +7 -3
- package/src/plugins/builtin/power/prices-client.ts +139 -0
- package/src/plugins/builtin/power/prices-headless.ts +205 -0
- package/src/plugins/builtin/power/prices-model.ts +103 -0
- package/src/plugins/builtin/power/prices.tsx +202 -0
- package/src/plugins/builtin/primary-dealers/client.ts +108 -0
- package/src/plugins/builtin/primary-dealers/headless.ts +53 -0
- package/src/plugins/builtin/primary-dealers/index.tsx +17 -0
- package/src/plugins/builtin/primary-dealers/model.ts +206 -0
- package/src/plugins/builtin/primary-dealers/pane.tsx +149 -0
- package/src/plugins/builtin/rate-path/headless.ts +38 -18
- package/src/plugins/builtin/relative-rotation/headless.ts +3 -3
- package/src/plugins/builtin/relative-rotation/index.tsx +3 -0
- package/src/plugins/builtin/research/analyst-model.ts +9 -5
- package/src/plugins/builtin/research/headless-schema.ts +2 -1
- package/src/plugins/builtin/research/index.tsx +2 -0
- package/src/plugins/builtin/research/relative-valuation-headless.ts +68 -32
- package/src/plugins/builtin/research/relative-valuation-model.ts +45 -24
- package/src/plugins/builtin/research/relative-valuation-pane.tsx +39 -4
- package/src/plugins/builtin/research-search/article.ts +65 -0
- package/src/plugins/builtin/research-search/document-view.tsx +33 -215
- package/src/plugins/builtin/research-search/model.ts +0 -9
- package/src/plugins/builtin/research-search/pane.tsx +41 -30
- package/src/plugins/builtin/research-search/snippet.ts +0 -29
- package/src/plugins/builtin/revenue-breakdown/headless.ts +18 -6
- package/src/plugins/builtin/scanner/flow-pane.tsx +8 -1
- package/src/plugins/builtin/sec/filing-display.tsx +3 -36
- package/src/plugins/builtin/sec/headless.ts +25 -3
- package/src/plugins/builtin/sec/index.tsx +133 -44
- package/src/plugins/builtin/sec/model.ts +148 -2
- package/src/plugins/builtin/sec/row-summaries.ts +105 -0
- package/src/plugins/builtin/sectors/index.tsx +2 -0
- package/src/plugins/builtin/sectors/sector-model.ts +2 -2
- package/src/plugins/builtin/series-inventory.ts +3 -0
- package/src/plugins/builtin/shared/cloud-denied.ts +15 -0
- package/src/plugins/builtin/shared/free-preview.ts +47 -0
- package/src/plugins/builtin/shared/locked-rows.tsx +1 -1
- package/src/plugins/builtin/shared/report-freshness.ts +3 -1
- package/src/plugins/builtin/shared/use-quote-board.ts +179 -43
- package/src/plugins/builtin/shared/volatility/options.ts +4 -1
- package/src/plugins/builtin/shared/wall-teaser.tsx +2 -2
- package/src/plugins/builtin/shared/zip-text.ts +46 -0
- package/src/plugins/builtin/short-interest/watch-headless.ts +2 -2
- package/src/plugins/builtin/short-interest/watch-model.ts +11 -2
- package/src/plugins/builtin/short-volume/headless.ts +1 -1
- package/src/plugins/builtin/social-mentions/headless.ts +1 -1
- package/src/plugins/builtin/supply-chain/headless.ts +43 -11
- package/src/plugins/builtin/supply-chain/model.ts +13 -0
- package/src/plugins/builtin/supply-chain/pane.tsx +5 -5
- package/src/plugins/builtin/themes/headless.ts +74 -10
- package/src/plugins/builtin/themes/model.ts +71 -4
- package/src/plugins/builtin/themes/pane.tsx +22 -5
- package/src/plugins/builtin/ticker-detail/data-panes/returns-history.ts +114 -0
- package/src/plugins/builtin/ticker-detail/data-panes/returns-model.ts +57 -2
- package/src/plugins/builtin/ticker-detail/data-panes/returns-pane.tsx +19 -55
- package/src/plugins/builtin/ticker-detail/financials/aggregation.ts +11 -0
- package/src/plugins/builtin/ticker-detail/financials/ratios.ts +81 -19
- package/src/plugins/builtin/ticker-detail/financials/tab.tsx +1 -1
- package/src/plugins/builtin/ticker-detail/headless-schema.ts +30 -0
- package/src/plugins/builtin/ticker-detail/headless.ts +88 -2
- package/src/plugins/builtin/ticker-detail/index.tsx +23 -11
- package/src/plugins/builtin/ticker-detail/overview/model.ts +3 -1
- package/src/plugins/builtin/ticker-detail/overview-tab.tsx +8 -6
- package/src/plugins/builtin/ticker-detail/quote-monitor/card.tsx +8 -6
- package/src/plugins/builtin/time-sales/headless.ts +23 -1
- package/src/plugins/builtin/time-sales/index.tsx +2 -1
- package/src/plugins/builtin/trace-bonds/client.ts +196 -0
- package/src/plugins/builtin/trace-bonds/headless.ts +69 -0
- package/src/plugins/builtin/trace-bonds/index.tsx +33 -0
- package/src/plugins/builtin/trace-bonds/model.ts +115 -0
- package/src/plugins/builtin/trace-bonds/pane.tsx +191 -0
- package/src/plugins/builtin/treasury-auctions/index.tsx +33 -47
- package/src/plugins/builtin/treasury-daily/client.ts +96 -0
- package/src/plugins/builtin/treasury-daily/headless.ts +69 -0
- package/src/plugins/builtin/treasury-daily/index.tsx +17 -0
- package/src/plugins/builtin/treasury-daily/model.ts +69 -0
- package/src/plugins/builtin/treasury-daily/pane.tsx +140 -0
- package/src/plugins/builtin/vol-surface/evidence.ts +7 -1
- package/src/plugins/builtin/vol-surface/headless.ts +50 -17
- package/src/plugins/builtin/vol-surface/heat-grid.tsx +113 -0
- package/src/plugins/builtin/vol-surface/model.ts +39 -6
- package/src/plugins/builtin/vol-surface/pane.tsx +14 -13
- package/src/plugins/builtin/vol-surface/stored.ts +63 -3
- package/src/plugins/builtin/vol-surface/surface.tsx +30 -2
- package/src/plugins/builtin/world-venue-map/basemap-layer.tsx +6 -5
- package/src/plugins/builtin/world-venue-map/basemap.ts +6 -3
- package/src/plugins/builtin/world-venue-map/entity-detail.tsx +15 -2
- package/src/plugins/builtin/world-venue-map/geo-draw.tsx +2 -1
- package/src/plugins/builtin/world-venue-map/geo-svg.tsx +6 -6
- package/src/plugins/builtin/world-venue-map/layered-pane.tsx +16 -9
- package/src/plugins/builtin/world-venue-map/map.tsx +145 -13
- package/src/plugins/builtin/world-venue-map/model.ts +56 -19
- package/src/plugins/builtin/world-venue-map/pane.tsx +5 -2
- package/src/plugins/builtin/yield-curve/index.tsx +1 -1
- package/src/plugins/builtin-editorial.ts +1 -1
- package/src/plugins/catalog-browser.ts +25 -2
- package/src/plugins/installer.ts +2 -2
- package/src/plugins/loader.ts +15 -0
- package/src/plugins/manager-node.ts +1 -1
- package/src/plugins/{builtin/plugin-marketplace → marketplace}/feed.ts +2 -2
- package/src/plugins/{builtin/plugin-marketplace → marketplace}/model.ts +63 -27
- package/src/plugins/{builtin/plugin-marketplace → marketplace}/store.ts +1 -1
- package/src/plugins/registry/host-actions.ts +11 -0
- package/src/portfolio/collection-name.ts +31 -0
- package/src/portfolio/valuation-basis.ts +79 -0
- package/src/public/time-series.ts +1 -1
- package/src/react/input.ts +33 -1
- package/src/react/key-repeat.ts +86 -0
- package/src/remote/controller.ts +21 -1
- package/src/remote/schema.ts +3 -2
- package/src/renderers/browser/main.tsx +1 -1
- package/src/renderers/browser/research-entry.ts +4 -2
- package/src/renderers/dom/build-assets.ts +14 -5
- package/src/renderers/dom/data-table/index.tsx +5 -3
- package/src/renderers/dom/data-table/row.tsx +3 -0
- package/src/renderers/dom/desktop/controls.tsx +2 -1
- package/src/renderers/dom/desktop/icons.tsx +34 -0
- package/src/renderers/dom/desktop/list-view.tsx +1 -1
- package/src/renderers/dom/desktop/menu.tsx +1 -1
- package/src/renderers/dom/desktop/query-bar.tsx +3 -1
- package/src/renderers/dom/host/block-glyph-canvas.tsx +6 -3
- package/src/renderers/dom/host/box.tsx +7 -2
- package/src/renderers/dom/host/chart-surface.tsx +34 -2
- package/src/renderers/dom/host/resize-rows.ts +111 -0
- package/src/renderers/dom/host/scroll-box.tsx +32 -0
- package/src/renderers/dom/host/size-observer.ts +24 -9
- package/src/renderers/dom/host/sticky-scroll.ts +147 -0
- package/src/renderers/dom/host/style.ts +15 -1
- package/src/renderers/dom/host/surface-3d.tsx +15 -7
- package/src/renderers/dom/host/surface-fit.ts +410 -0
- package/src/renderers/dom/host/text.tsx +2 -2
- package/src/renderers/dom/input-host.tsx +1 -0
- package/src/renderers/dom/styles.css +109 -16
- package/src/renderers/electrobun/bun/application-menu/click.ts +18 -0
- package/src/renderers/electrobun/bun/desktop/app-badge.ts +37 -0
- package/src/renderers/electrobun/bun/desktop/backend.ts +1 -0
- package/src/renderers/electrobun/bun/desktop/host-requests.ts +8 -0
- package/src/renderers/electrobun/bun/desktop/macos-dock-badge.ts +37 -0
- package/src/renderers/electrobun/bun/desktop/macos-dock-icon.ts +2 -40
- package/src/renderers/electrobun/bun/desktop/macos-objc.ts +41 -0
- package/src/renderers/electrobun/bun/index.ts +3 -2
- package/src/renderers/electrobun/bun/tui-entry.ts +18 -1
- package/src/renderers/electrobun/shared/protocol.ts +3 -1
- package/src/renderers/electrobun/view/app-badge-host.ts +17 -0
- package/src/renderers/electrobun/view/cli-pane-shot-entry.tsx +20 -3
- package/src/renderers/electrobun/view/cli-pane-shot-frame.tsx +59 -24
- package/src/renderers/electrobun/view/main.tsx +5 -3
- package/src/renderers/electrobun/view/remote/asset-data-client.ts +7 -1
- package/src/renderers/opentui/chart-surface.tsx +1 -0
- package/src/renderers/opentui/frame-capture.ts +33 -0
- package/src/renderers/opentui/host.tsx +10 -13
- package/src/renderers/opentui/pane-image/glyphs-license.txt +107 -0
- package/src/renderers/opentui/pane-image/glyphs.json +1 -0
- package/src/renderers/opentui/pane-image/index.ts +107 -0
- package/src/renderers/opentui/pane-image/raster.ts +428 -0
- package/src/renderers/opentui/start.tsx +3 -3
- package/src/renderers/opentui/test-utils.tsx +3 -0
- package/src/renderers/opentui/ui-host.tsx +29 -1
- package/src/series/resolve.ts +3 -2
- package/src/series/types.ts +8 -0
- package/src/series/validate.ts +2 -2
- package/src/shares/api.ts +5 -1
- package/src/shares/chat.ts +34 -0
- package/src/shares/dialog.tsx +295 -0
- package/src/shares/flow.tsx +56 -0
- package/src/shares/live.ts +14 -22
- package/src/shares/location.ts +31 -0
- package/src/shares/open.ts +26 -0
- package/src/shares/pane-image.ts +164 -0
- package/src/shares/personal-pane.ts +52 -0
- package/src/shares/portable-layout.ts +4 -2
- package/src/shares/prepare.ts +20 -0
- package/src/sources/gloomberb-cloud/index.ts +109 -5
- package/src/sources/gloomberb-cloud/normalizers.ts +7 -0
- package/src/sources/gloomberb-cloud/perpetuals.ts +249 -0
- package/src/sources/history-coverage.ts +22 -4
- package/src/sources/history-result.ts +3 -1
- package/src/sources/history-retention.ts +11 -0
- package/src/sources/listing-target.ts +4 -0
- package/src/sources/provider-errors.ts +2 -1
- package/src/sources/provider-router/batches.ts +18 -2
- package/src/sources/provider-router/index.ts +16 -1
- package/src/state/app/context/index.tsx +3 -2
- package/src/state/hooks/inline-tickers.ts +49 -11
- package/src/test-support/builtin-panes.ts +31 -0
- package/src/test-support/shell-pane-keys.tsx +1 -0
- package/src/theme/theme-context.tsx +15 -1
- package/src/tickers/instrument-kind.ts +9 -1
- package/src/tickers/listing-name.ts +34 -0
- package/src/tickers/listing-venues.ts +154 -0
- package/src/tickers/open-target.ts +11 -3
- package/src/tickers/perpetual-listing.ts +151 -0
- package/src/tickers/prediction-listing.ts +26 -0
- package/src/tickers/search/index.ts +34 -6
- package/src/tickers/search/ranking.ts +85 -4
- package/src/tickers/ticker-changes.ts +213 -0
- package/src/time-series/chart-data.ts +2 -0
- package/src/time-series/economic.ts +2 -6
- package/src/time-series/ice-credit.ts +39 -0
- package/src/time-series/parsed-history-cache.ts +41 -11
- package/src/time-series/resolve.ts +163 -28
- package/src/time-series/studies.ts +1 -0
- package/src/time-series/types.ts +8 -0
- package/src/types/config.ts +4 -2
- package/src/types/data-provider.ts +19 -1
- package/src/types/financials.ts +23 -0
- package/src/types/headless.ts +74 -0
- package/src/types/instrument.ts +4 -0
- package/src/types/plugin.ts +60 -2
- package/src/types/price-history.ts +2 -0
- package/src/types/ticker-changes.ts +26 -0
- package/src/ui/context-menu.tsx +13 -1
- package/src/ui/host.tsx +49 -7
- package/src/ui/live-resize.ts +10 -0
- package/src/ui/live-stretch.ts +51 -19
- package/src/ui/sticky-scroll.ts +7 -0
- package/src/utils/central-banks.ts +76 -0
- package/src/utils/cli-output.ts +126 -16
- package/src/utils/crypto-pair.ts +1 -1
- package/src/utils/currency-pair.ts +66 -0
- package/src/utils/currency-units.ts +11 -0
- package/src/utils/datetime-format.ts +27 -6
- package/src/utils/decimal-comma.ts +57 -0
- package/src/utils/dom-screenshot.ts +3 -1
- package/src/utils/double-escape-close.ts +15 -1
- package/src/utils/exchanges.ts +36 -0
- package/src/utils/format.ts +19 -2
- package/src/utils/forward-dividend.ts +14 -0
- package/src/utils/fx-status.ts +6 -1
- package/src/utils/guards.ts +25 -0
- package/src/utils/inline-content-tokenizer.ts +22 -3
- package/src/utils/local-utc-offset.ts +37 -0
- package/src/utils/market-capitalization.ts +8 -0
- package/src/utils/one-shot.ts +73 -0
- package/src/utils/options.ts +37 -8
- package/src/utils/plugin-proxy-hosts.json +8 -1
- package/src/utils/utc-time.ts +12 -0
- package/src/plugins/builtin/credit-boards/pane.tsx +0 -30
- package/src/ui/pane-fill.ts +0 -11
- /package/src/plugins/{builtin/plugin-marketplace → marketplace}/activation.ts +0 -0
- /package/src/plugins/{builtin/plugin-marketplace → marketplace}/ids.ts +0 -0
- /package/src/plugins/{builtin/plugin-marketplace → marketplace}/packs.ts +0 -0
|
@@ -6,7 +6,11 @@ import type {
|
|
|
6
6
|
ChatMessage,
|
|
7
7
|
ChatMessageOrigin,
|
|
8
8
|
ChatNotification,
|
|
9
|
+
ChatReaction,
|
|
10
|
+
ChatReactionUser,
|
|
9
11
|
ChatStateResponse,
|
|
12
|
+
ChatUserBadge,
|
|
13
|
+
ChatUserSummary,
|
|
10
14
|
CloudSavedSearch,
|
|
11
15
|
CloudSearchHit,
|
|
12
16
|
CloudSearchResponse,
|
|
@@ -15,6 +19,7 @@ import type {
|
|
|
15
19
|
TeamNotification,
|
|
16
20
|
} from "./types";
|
|
17
21
|
import { normalizeTimestamp } from "../utils/timestamp";
|
|
22
|
+
import { parseChatPaneLink } from "./chat-pane-link";
|
|
18
23
|
|
|
19
24
|
/**
|
|
20
25
|
* Saved-search writes answer with either the record itself or `{ search }`.
|
|
@@ -80,17 +85,37 @@ export function normalizeChatAttachments(value: unknown): ChatAttachment[] {
|
|
|
80
85
|
const CHAT_ACCOUNT_TYPES: readonly string[] = ["human", "managed_llm", "discord"] satisfies ChatAccountType[];
|
|
81
86
|
const CHAT_MESSAGE_ORIGINS: readonly string[] = ["app", "discord"] satisfies ChatMessageOrigin[];
|
|
82
87
|
|
|
83
|
-
|
|
84
|
-
|
|
85
|
-
|
|
86
|
-
|
|
87
|
-
|
|
88
|
+
const CHAT_USER_BADGES: readonly string[] = ["team", "pro"] satisfies ChatUserBadge[];
|
|
89
|
+
|
|
90
|
+
/**
|
|
91
|
+
* A value a newer server adds that this client does not know reads as absent:
|
|
92
|
+
* a human, a message from the app, no badge. A clock or desks that are not
|
|
93
|
+
* what the server promises are dropped rather than shown wrong.
|
|
94
|
+
*/
|
|
95
|
+
function normalizeChatUser(user: ChatUserSummary): ChatUserSummary {
|
|
96
|
+
if (!user || typeof user !== "object") return user;
|
|
97
|
+
const { accountType, badges, utcOffsetMinutes, desks, ...rest } = user;
|
|
98
|
+
const knownBadges = Array.isArray(badges)
|
|
99
|
+
? CHAT_USER_BADGES.filter((badge) => badges.includes(badge as ChatUserBadge)) as ChatUserBadge[]
|
|
100
|
+
: [];
|
|
101
|
+
const knownDesks = Array.isArray(desks) ? desks.filter((desk): desk is string => typeof desk === "string" && !!desk) : [];
|
|
102
|
+
const offset = typeof utcOffsetMinutes === "number" && Number.isInteger(utcOffsetMinutes)
|
|
103
|
+
&& utcOffsetMinutes >= -12 * 60 && utcOffsetMinutes <= 14 * 60
|
|
104
|
+
? utcOffsetMinutes
|
|
105
|
+
: null;
|
|
106
|
+
return {
|
|
107
|
+
...rest,
|
|
108
|
+
...(accountType !== undefined && CHAT_ACCOUNT_TYPES.includes(accountType) ? { accountType } : {}),
|
|
109
|
+
...(knownBadges.length > 0 ? { badges: knownBadges } : {}),
|
|
110
|
+
...(offset !== null ? { utcOffsetMinutes: offset } : {}),
|
|
111
|
+
...(knownDesks.length > 0 ? { desks: knownDesks } : {}),
|
|
112
|
+
};
|
|
88
113
|
}
|
|
89
114
|
|
|
90
115
|
export function normalizeChatMessage(message: ChatMessage): ChatMessage {
|
|
91
116
|
const normalized: ChatMessage = {
|
|
92
117
|
...message,
|
|
93
|
-
user:
|
|
118
|
+
user: normalizeChatUser(message.user),
|
|
94
119
|
content: typeof message.content === "string" ? message.content : "",
|
|
95
120
|
createdAt: normalizeTimestamp(message.createdAt),
|
|
96
121
|
...(message.editedAt
|
|
@@ -98,10 +123,16 @@ export function normalizeChatMessage(message: ChatMessage): ChatMessage {
|
|
|
98
123
|
: {}),
|
|
99
124
|
};
|
|
100
125
|
if ("attachments" in message) normalized.attachments = normalizeChatAttachments(message.attachments);
|
|
126
|
+
if ("reactions" in message) normalized.reactions = normalizeChatReactions(message.reactions);
|
|
101
127
|
if (message.origin !== undefined && !CHAT_MESSAGE_ORIGINS.includes(message.origin)) delete normalized.origin;
|
|
102
128
|
if (message.attachmentReview !== "pending" && message.attachmentReview !== "failed") {
|
|
103
129
|
delete normalized.attachmentReview;
|
|
104
130
|
}
|
|
131
|
+
if ("paneLink" in message) {
|
|
132
|
+
const paneLink = parseChatPaneLink(message.paneLink);
|
|
133
|
+
if (paneLink) normalized.paneLink = paneLink;
|
|
134
|
+
else delete normalized.paneLink;
|
|
135
|
+
}
|
|
105
136
|
return normalized;
|
|
106
137
|
}
|
|
107
138
|
|
|
@@ -117,6 +148,35 @@ export function normalizeChatDiscordLink(value: unknown): ChatDiscordLink {
|
|
|
117
148
|
};
|
|
118
149
|
}
|
|
119
150
|
|
|
151
|
+
/** Reactions as the server sent them, dropping anything malformed. */
|
|
152
|
+
export function normalizeChatReactions(value: unknown): ChatReaction[] {
|
|
153
|
+
if (!Array.isArray(value)) return [];
|
|
154
|
+
const reactions: ChatReaction[] = [];
|
|
155
|
+
for (const entry of value) {
|
|
156
|
+
if (!entry || typeof entry !== "object") continue;
|
|
157
|
+
const raw = entry as Record<string, unknown>;
|
|
158
|
+
if (typeof raw.emoji !== "string" || !raw.emoji) continue;
|
|
159
|
+
const count = typeof raw.count === "number" && Number.isFinite(raw.count) ? Math.max(0, Math.floor(raw.count)) : 0;
|
|
160
|
+
if (count === 0) continue;
|
|
161
|
+
const users = Array.isArray(raw.users)
|
|
162
|
+
? raw.users.flatMap((user): ChatReactionUser[] => {
|
|
163
|
+
if (!user || typeof user !== "object") return [];
|
|
164
|
+
const candidate = user as Record<string, unknown>;
|
|
165
|
+
if (typeof candidate.id !== "string") return [];
|
|
166
|
+
const accountType = candidate.accountType;
|
|
167
|
+
return [{
|
|
168
|
+
id: candidate.id,
|
|
169
|
+
username: typeof candidate.username === "string" ? candidate.username : null,
|
|
170
|
+
displayName: typeof candidate.displayName === "string" ? candidate.displayName : "User",
|
|
171
|
+
...(accountType === "human" || accountType === "managed_llm" || accountType === "discord" ? { accountType } : {}),
|
|
172
|
+
}];
|
|
173
|
+
})
|
|
174
|
+
: [];
|
|
175
|
+
reactions.push({ emoji: raw.emoji, count, me: raw.me === true, users });
|
|
176
|
+
}
|
|
177
|
+
return reactions;
|
|
178
|
+
}
|
|
179
|
+
|
|
120
180
|
export function normalizeChatMessages(messages: ChatMessage[]): ChatMessage[] {
|
|
121
181
|
return messages.map((message) => normalizeChatMessage(message));
|
|
122
182
|
}
|
|
@@ -139,6 +199,8 @@ export function normalizeChatChannel(
|
|
|
139
199
|
...channel,
|
|
140
200
|
kind: channel.kind ?? fallbackKind,
|
|
141
201
|
created_at: normalizeTimestamp(channel.created_at),
|
|
202
|
+
...(channel.dmUser ? { dmUser: normalizeChatUser(channel.dmUser) } : {}),
|
|
203
|
+
...(Array.isArray(channel.members) ? { members: channel.members.map(normalizeChatUser) } : {}),
|
|
142
204
|
};
|
|
143
205
|
}
|
|
144
206
|
|
|
@@ -0,0 +1,44 @@
|
|
|
1
|
+
/** Names per request: one page of a list, such as a clinical trial search page's lead sponsors. */
|
|
2
|
+
export const ORGANIZATION_TICKERS_BATCH_LIMIT = 50;
|
|
3
|
+
|
|
4
|
+
/**
|
|
5
|
+
* What Gloom Cloud resolved an organization name to: the listing of the
|
|
6
|
+
* company the name belongs to, or why there is none. The match is the
|
|
7
|
+
* server's, from reviewed and exact aliases only; the app never matches a
|
|
8
|
+
* name to a ticker itself.
|
|
9
|
+
*/
|
|
10
|
+
export interface OrganizationTicker {
|
|
11
|
+
name: string;
|
|
12
|
+
/** Null when the name is unlinked, ambiguous, or resolved to a company without a listing. */
|
|
13
|
+
ticker: string | null;
|
|
14
|
+
exchange: string | null;
|
|
15
|
+
/** The company the name resolved to; null when unlinked. */
|
|
16
|
+
entityName: string | null;
|
|
17
|
+
resolution: "identifier" | "alias" | "unresolved";
|
|
18
|
+
/** Left unlinked because the name fits more than one company. */
|
|
19
|
+
ambiguous: boolean;
|
|
20
|
+
}
|
|
21
|
+
|
|
22
|
+
export interface OrganizationTickersResponse {
|
|
23
|
+
results: OrganizationTicker[];
|
|
24
|
+
}
|
|
25
|
+
|
|
26
|
+
function isResult(value: unknown): value is OrganizationTicker {
|
|
27
|
+
if (!value || typeof value !== "object") return false;
|
|
28
|
+
const row = value as Record<string, unknown>;
|
|
29
|
+
const text = (field: unknown) => field === null || typeof field === "string";
|
|
30
|
+
return typeof row.name === "string"
|
|
31
|
+
&& text(row.ticker) && text(row.exchange) && text(row.entityName)
|
|
32
|
+
&& (row.resolution === "identifier" || row.resolution === "alias" || row.resolution === "unresolved")
|
|
33
|
+
&& typeof row.ambiguous === "boolean";
|
|
34
|
+
}
|
|
35
|
+
|
|
36
|
+
/** The answers in the order asked; throws when the server answered something else. */
|
|
37
|
+
export function validateOrganizationTickers(payload: unknown, names: readonly string[]): OrganizationTicker[] {
|
|
38
|
+
const results = (payload as Partial<OrganizationTickersResponse> | null)?.results;
|
|
39
|
+
if (!Array.isArray(results) || results.length !== names.length || !results.every(isResult)
|
|
40
|
+
|| results.some((result, index) => result.name !== names[index])) {
|
|
41
|
+
throw new Error("The server returned invalid organization tickers.");
|
|
42
|
+
}
|
|
43
|
+
return results;
|
|
44
|
+
}
|
package/src/api-client/perps.ts
CHANGED
|
@@ -147,6 +147,14 @@ export interface PerpBoardPayload {
|
|
|
147
147
|
access: "pro" | "preview"; sources?: unknown[];
|
|
148
148
|
}
|
|
149
149
|
export interface PerpEquityListing { symbol: string; exchange: string }
|
|
150
|
+
/**
|
|
151
|
+
* The batch lookup a watchlist or portfolio makes: one entry per requested listing, in its order, with the contract
|
|
152
|
+
* the single equity lookup would list first, or none. `listing` is null when the server cannot read the listing.
|
|
153
|
+
*/
|
|
154
|
+
export interface PerpEquitiesPayload {
|
|
155
|
+
status: string; asOf: string | null; access: "pro" | "preview"; locked: number;
|
|
156
|
+
results: { listing: PerpEquityListing | null; market: PerpBoardRow | null }[];
|
|
157
|
+
}
|
|
150
158
|
export interface PerpHistoryPayload {
|
|
151
159
|
status: string; marketId: string; rows: PerpHistoryPoint[]; funding: PerpFunding[]; candles: PerpCandle[];
|
|
152
160
|
/** Absent from servers older than the long/short series: read as empty. */
|
|
@@ -408,8 +408,17 @@ export class CloudApiRequestTransport {
|
|
|
408
408
|
// Crash reports, usage counts and command-search reports are background
|
|
409
409
|
// traffic: a rate-limited, timed-out or missing one must not show up as a
|
|
410
410
|
// Cloud outage in the connections pane. Nor must the map's probe for geo
|
|
411
|
-
// layers, which a server without them answers with 404
|
|
412
|
-
|
|
411
|
+
// layers, which a server without them answers with 404, or a ticker
|
|
412
|
+
// change lookup: a note beside a quote, never one of the refused market
|
|
413
|
+
// requests a lookup of many symbols waits out and retries. Nor the
|
|
414
|
+
// tickers beside a list of organization names, which say so in place.
|
|
415
|
+
if (
|
|
416
|
+
path.startsWith("/telemetry/")
|
|
417
|
+
|| path === "/assist/searches"
|
|
418
|
+
|| path === "/cloud/geo/layers"
|
|
419
|
+
|| path.startsWith("/market/ticker-changes?")
|
|
420
|
+
|| path === "/market/organization-tickers"
|
|
421
|
+
) return request();
|
|
413
422
|
return this.connectionHealth.track(
|
|
414
423
|
GLOOM_CLOUD_HTTP_CONNECTION_ID,
|
|
415
424
|
operation,
|
package/src/api-client/socket.ts
CHANGED
|
@@ -3,6 +3,7 @@ import type {
|
|
|
3
3
|
AuthUser,
|
|
4
4
|
ChatMessage,
|
|
5
5
|
ChatNotification,
|
|
6
|
+
ChatReactionsUpdate,
|
|
6
7
|
CloudQuotePayload,
|
|
7
8
|
QuoteStreamTarget,
|
|
8
9
|
ScannerFeedEvent,
|
|
@@ -12,6 +13,7 @@ import type {
|
|
|
12
13
|
import {
|
|
13
14
|
normalizeChatMessage,
|
|
14
15
|
normalizeChatNotification,
|
|
16
|
+
normalizeChatReactions,
|
|
15
17
|
normalizeTeamNotification,
|
|
16
18
|
} from "./normalizers";
|
|
17
19
|
import { debugLog } from "../utils/debug-log";
|
|
@@ -41,6 +43,7 @@ const cloudApiLog = debugLog.createLogger("cloud-api");
|
|
|
41
43
|
type ChannelListener = (message: ChatMessage) => void;
|
|
42
44
|
type ChatNotificationListener = (notification: ChatNotification) => void;
|
|
43
45
|
type ChatPresenceListener = (onlineCount: number) => void;
|
|
46
|
+
type ChatReactionsListener = (update: ChatReactionsUpdate) => void;
|
|
44
47
|
type TeamNotificationListener = (notification: TeamNotification) => void;
|
|
45
48
|
type CloudEventListener = (data: unknown) => void;
|
|
46
49
|
type QuoteListener = (
|
|
@@ -106,6 +109,7 @@ export class CloudApiSocket {
|
|
|
106
109
|
private readonly chatNotificationListeners =
|
|
107
110
|
new Set<ChatNotificationListener>();
|
|
108
111
|
private readonly chatPresenceListeners = new Set<ChatPresenceListener>();
|
|
112
|
+
private readonly chatReactionsListeners = new Set<ChatReactionsListener>();
|
|
109
113
|
private readonly teamNotificationListeners =
|
|
110
114
|
new Set<TeamNotificationListener>();
|
|
111
115
|
private readonly cloudEventListeners = new Map<
|
|
@@ -245,6 +249,14 @@ export class CloudApiSocket {
|
|
|
245
249
|
};
|
|
246
250
|
}
|
|
247
251
|
|
|
252
|
+
/** A message's reactions changed in a channel this socket reads. */
|
|
253
|
+
subscribeChatReactions(listener: ChatReactionsListener): () => void {
|
|
254
|
+
this.chatReactionsListeners.add(listener);
|
|
255
|
+
return () => {
|
|
256
|
+
this.chatReactionsListeners.delete(listener);
|
|
257
|
+
};
|
|
258
|
+
}
|
|
259
|
+
|
|
248
260
|
subscribeChatPresence(listener: ChatPresenceListener): () => void {
|
|
249
261
|
this.chatPresenceListeners.add(listener);
|
|
250
262
|
return () => {
|
|
@@ -500,6 +512,7 @@ export class CloudApiSocket {
|
|
|
500
512
|
this.connectionListeners.clear();
|
|
501
513
|
this.chatNotificationListeners.clear();
|
|
502
514
|
this.chatPresenceListeners.clear();
|
|
515
|
+
this.chatReactionsListeners.clear();
|
|
503
516
|
this.teamNotificationListeners.clear();
|
|
504
517
|
this.cloudEventListeners.clear();
|
|
505
518
|
this.quoteSubscriptions.clear();
|
|
@@ -575,6 +588,22 @@ export class CloudApiSocket {
|
|
|
575
588
|
return;
|
|
576
589
|
}
|
|
577
590
|
|
|
591
|
+
if (
|
|
592
|
+
parsed?.type === "chat.reactions" &&
|
|
593
|
+
typeof parsed.channelId === "string" &&
|
|
594
|
+
typeof parsed.data?.messageId === "string"
|
|
595
|
+
) {
|
|
596
|
+
const update: ChatReactionsUpdate = {
|
|
597
|
+
channelId: parsed.channelId,
|
|
598
|
+
messageId: parsed.data.messageId,
|
|
599
|
+
reactions: normalizeChatReactions(parsed.data.reactions),
|
|
600
|
+
};
|
|
601
|
+
for (const listener of this.chatReactionsListeners) {
|
|
602
|
+
listener(update);
|
|
603
|
+
}
|
|
604
|
+
return;
|
|
605
|
+
}
|
|
606
|
+
|
|
578
607
|
if (parsed?.type === "chat.notification" && parsed.data) {
|
|
579
608
|
const notification = normalizeChatNotification(
|
|
580
609
|
parsed.data as ChatNotification,
|
package/src/api-client/themes.ts
CHANGED
|
@@ -15,6 +15,12 @@ export interface ThemeSummary {
|
|
|
15
15
|
worst: { symbol: string; changePercent: number } | null;
|
|
16
16
|
stale: boolean;
|
|
17
17
|
}
|
|
18
|
+
/**
|
|
19
|
+
* A member's figures. `price`, `changePercent` and the returns are the regular
|
|
20
|
+
* session's: outside it, its close and that close's move. The extended fields
|
|
21
|
+
* are the pre-market or after-hours print measured from that close; a server
|
|
22
|
+
* sends them only when there is one, and older servers never do.
|
|
23
|
+
*/
|
|
18
24
|
export interface ThemeMember extends Record<ThemePeriod | "price", number | null> {
|
|
19
25
|
symbol: string;
|
|
20
26
|
name: string | null;
|
|
@@ -22,7 +28,22 @@ export interface ThemeMember extends Record<ThemePeriod | "price", number | null
|
|
|
22
28
|
present: boolean;
|
|
23
29
|
asOf: Record<ThemePeriod | "price", string | null>;
|
|
24
30
|
stale: boolean;
|
|
31
|
+
extendedSession?: "PRE" | "POST" | null;
|
|
32
|
+
extendedPrice?: number | null;
|
|
33
|
+
extendedChange?: number | null;
|
|
34
|
+
extendedChangePercent?: number | null;
|
|
35
|
+
}
|
|
36
|
+
interface SnapshotMetadata {
|
|
37
|
+
/** When the server put the snapshot together, not a trade time. */
|
|
38
|
+
asOf: string;
|
|
39
|
+
snapshotId: string;
|
|
40
|
+
stale: boolean;
|
|
41
|
+
/** The US market as the server's delayed board reads it. Absent from older servers. */
|
|
42
|
+
session?: "PRE" | "REGULAR" | "POST" | "CLOSED" | null;
|
|
43
|
+
/** Outside the regular session, the completed session every figure describes; null while one trades. */
|
|
44
|
+
regularSessionDate?: string | null;
|
|
45
|
+
/** When that session closed, in epoch milliseconds (13:00 New York on an early close). */
|
|
46
|
+
regularSessionClosedAt?: number | null;
|
|
25
47
|
}
|
|
26
|
-
interface SnapshotMetadata { asOf: string; snapshotId: string; stale: boolean }
|
|
27
48
|
export interface ThemesPayload extends SnapshotMetadata { themes: ThemeSummary[] }
|
|
28
49
|
export interface ThemeMembersPayload extends SnapshotMetadata { theme: ThemeSummary; members: ThemeMember[] }
|
package/src/api-client/types.ts
CHANGED
|
@@ -9,6 +9,7 @@ import type {
|
|
|
9
9
|
TickerFinancials,
|
|
10
10
|
} from "../types/financials";
|
|
11
11
|
import type { SyncSettings, SyncSnapshot } from "../sync/types";
|
|
12
|
+
import type { ChatPaneLink } from "./chat-pane-link";
|
|
12
13
|
|
|
13
14
|
/**
|
|
14
15
|
* What stands behind a chat account. `discord` is a person on the Gloom
|
|
@@ -20,6 +21,9 @@ export type ChatAccountType = "human" | "managed_llm" | "discord";
|
|
|
20
21
|
/** Where a message was written. A message without one came from the app. */
|
|
21
22
|
export type ChatMessageOrigin = "app" | "discord";
|
|
22
23
|
|
|
24
|
+
/** A badge an account earns in chat: `team` for Gloom staff, `pro` with Pro access. */
|
|
25
|
+
export type ChatUserBadge = "team" | "pro";
|
|
26
|
+
|
|
23
27
|
export interface ChatUserSummary {
|
|
24
28
|
id: string;
|
|
25
29
|
/** A person, a managed assistant (Gloombot), or a Discord user bridged into public channels. */
|
|
@@ -32,6 +36,15 @@ export interface ChatUserSummary {
|
|
|
32
36
|
profilePublic?: boolean;
|
|
33
37
|
acceptUnknownDms?: boolean;
|
|
34
38
|
portfolioAnalytics?: PublicPortfolioAnalytics | null;
|
|
39
|
+
/** Badges the account earns. A server that predates them, or a person with none, leaves this out. */
|
|
40
|
+
badges?: ChatUserBadge[];
|
|
41
|
+
/**
|
|
42
|
+
* The person's current offset from UTC in minutes, as their app last
|
|
43
|
+
* reported it: left out while they keep their local time hidden.
|
|
44
|
+
*/
|
|
45
|
+
utcOffsetMinutes?: number;
|
|
46
|
+
/** The desks (equities, options, ...) the person chose to show; left out unless they did. */
|
|
47
|
+
desks?: string[];
|
|
35
48
|
}
|
|
36
49
|
|
|
37
50
|
/**
|
|
@@ -49,6 +62,33 @@ export interface ChatAttachment {
|
|
|
49
62
|
url: string;
|
|
50
63
|
}
|
|
51
64
|
|
|
65
|
+
/** Someone who reacted, as a reaction lists the first few. */
|
|
66
|
+
export interface ChatReactionUser {
|
|
67
|
+
id: string;
|
|
68
|
+
username: string | null;
|
|
69
|
+
displayName: string;
|
|
70
|
+
accountType?: ChatAccountType | null;
|
|
71
|
+
}
|
|
72
|
+
|
|
73
|
+
/**
|
|
74
|
+
* One emoji on a message: how many reacted, whether you did, and the first
|
|
75
|
+
* few who did, oldest first. `emoji` is the character, or `:name:` for a
|
|
76
|
+
* custom Discord server emoji.
|
|
77
|
+
*/
|
|
78
|
+
export interface ChatReaction {
|
|
79
|
+
emoji: string;
|
|
80
|
+
count: number;
|
|
81
|
+
me: boolean;
|
|
82
|
+
users?: ChatReactionUser[];
|
|
83
|
+
}
|
|
84
|
+
|
|
85
|
+
/** A message's reactions as they stand after a change, from the `chat.reactions` frame or a reaction request. */
|
|
86
|
+
export interface ChatReactionsUpdate {
|
|
87
|
+
channelId: string;
|
|
88
|
+
messageId: string;
|
|
89
|
+
reactions: ChatReaction[];
|
|
90
|
+
}
|
|
91
|
+
|
|
52
92
|
export interface ChatMessage {
|
|
53
93
|
id: string;
|
|
54
94
|
channelId: string;
|
|
@@ -66,12 +106,20 @@ export interface ChatMessage {
|
|
|
66
106
|
} | null;
|
|
67
107
|
/** Images in display order. A server that predates them leaves this out. */
|
|
68
108
|
attachments?: ChatAttachment[];
|
|
109
|
+
/**
|
|
110
|
+
* Emoji reactions in the order they first appeared. Message lists from a
|
|
111
|
+
* server that knows reactions always carry it; a live copy of a message
|
|
112
|
+
* (an edit) leaves it out, and the reactions held stay.
|
|
113
|
+
*/
|
|
114
|
+
reactions?: ChatReaction[];
|
|
69
115
|
/**
|
|
70
116
|
* Only on the author's copy of a public message whose images are still being
|
|
71
117
|
* checked ("pending") or could not be checked ("failed"). Nobody else has the
|
|
72
118
|
* message yet.
|
|
73
119
|
*/
|
|
74
120
|
attachmentReview?: "pending" | "failed";
|
|
121
|
+
/** What the message opens in the terminal (a Gloom Wire story or calendar). Only the server sets it. */
|
|
122
|
+
paneLink?: ChatPaneLink;
|
|
75
123
|
clientStatus?: "sending" | "failed";
|
|
76
124
|
clientError?: string | null;
|
|
77
125
|
/** The idempotency key a local send went out with, so a retry repeats it. */
|
|
@@ -175,6 +223,12 @@ export interface AccountProfile {
|
|
|
175
223
|
acceptUnknownDms: boolean;
|
|
176
224
|
chatEmailNotificationsEnabled: boolean;
|
|
177
225
|
portfolioAnalytics?: PublicPortfolioAnalytics | null;
|
|
226
|
+
/** Chat shows your local time on your card. A server that predates the setting leaves it out. */
|
|
227
|
+
showLocalTime?: boolean;
|
|
228
|
+
/** The desks chat shows beside your name; empty shows none. */
|
|
229
|
+
chatDesks?: string[];
|
|
230
|
+
/** Your answer to "What do you trade?" at the first run: private, it pre-fills `chatDesks`. */
|
|
231
|
+
onboardingDesks?: string[];
|
|
178
232
|
syncEnabled: boolean;
|
|
179
233
|
weeklyRoundupEnabled: boolean;
|
|
180
234
|
positionAlertsEnabled: boolean;
|
|
@@ -318,6 +372,9 @@ export type AccountProfileUpdate = Partial<{
|
|
|
318
372
|
syncEnabled: boolean;
|
|
319
373
|
weeklyRoundupEnabled: boolean;
|
|
320
374
|
positionAlertsEnabled: boolean;
|
|
375
|
+
showLocalTime: boolean;
|
|
376
|
+
/** Null or empty shows no desks. */
|
|
377
|
+
chatDesks: string[] | null;
|
|
321
378
|
}>;
|
|
322
379
|
|
|
323
380
|
export interface CloudSyncSnapshotResponse {
|
|
@@ -402,6 +459,10 @@ export interface CloudPricePointPayload {
|
|
|
402
459
|
low?: number;
|
|
403
460
|
close: number;
|
|
404
461
|
volume?: number;
|
|
462
|
+
/** A coin's daily bar for the UTC day still forming when served; it has no volume yet. */
|
|
463
|
+
partial?: boolean;
|
|
464
|
+
/** A coin's daily bar whose prices were rebuilt from hourly bars; a day the source left empty has no volume. */
|
|
465
|
+
filled?: boolean;
|
|
405
466
|
}
|
|
406
467
|
|
|
407
468
|
type CloudEconImpact = "high" | "medium" | "low";
|
|
@@ -432,6 +493,13 @@ export interface CloudMacroReleaseDaysPayload {
|
|
|
432
493
|
export interface CloudFredObservationPayload {
|
|
433
494
|
date: string;
|
|
434
495
|
value: number | null;
|
|
496
|
+
/**
|
|
497
|
+
* Who published a value FRED does not list yet, such as a Treasury yield
|
|
498
|
+
* Gloom Cloud read from the Treasury first. Absent on FRED's own values.
|
|
499
|
+
*/
|
|
500
|
+
publisher?: string;
|
|
501
|
+
/** When that publisher's value was first read, ISO in UTC. */
|
|
502
|
+
publishedAt?: string;
|
|
435
503
|
}
|
|
436
504
|
|
|
437
505
|
export interface CloudFredSeriesInfoPayload {
|
|
@@ -538,6 +606,22 @@ export interface CloudCdsHistoryResponse {
|
|
|
538
606
|
points: CloudCdsHistoryPointPayload[];
|
|
539
607
|
}
|
|
540
608
|
|
|
609
|
+
/** An issuer's latest 5Y level: the last point of its history over the last month. */
|
|
610
|
+
export interface CloudCdsLevelPayload {
|
|
611
|
+
/** The reference entity as the history response names it. */
|
|
612
|
+
issuer: string;
|
|
613
|
+
spreadBp: number;
|
|
614
|
+
date: string;
|
|
615
|
+
}
|
|
616
|
+
|
|
617
|
+
export interface CloudCdsLevelsResponse {
|
|
618
|
+
source: string;
|
|
619
|
+
tenor: string;
|
|
620
|
+
asOf: string | null;
|
|
621
|
+
/** Every issuer traded in the last month whose 5Y line has a level in it. */
|
|
622
|
+
levels: CloudCdsLevelPayload[];
|
|
623
|
+
}
|
|
624
|
+
|
|
541
625
|
interface CloudShortInterestPointPayload {
|
|
542
626
|
settlementDate: string;
|
|
543
627
|
shortPercentFloat?: number | null;
|
|
@@ -1098,7 +1182,7 @@ export interface CloudSearchResponse {
|
|
|
1098
1182
|
tookMs: number;
|
|
1099
1183
|
}
|
|
1100
1184
|
|
|
1101
|
-
|
|
1185
|
+
interface CloudSearchDocumentChunk {
|
|
1102
1186
|
id: string;
|
|
1103
1187
|
chunkIndex: number;
|
|
1104
1188
|
body: string;
|
|
@@ -1361,7 +1445,9 @@ export interface CloudHistoryCoverage {
|
|
|
1361
1445
|
/** First bar date (YYYY-MM-DD) the source serves, such as a fund's inception. */
|
|
1362
1446
|
firstAllowedBarDate?: string;
|
|
1363
1447
|
inceptionDate?: string;
|
|
1364
|
-
|
|
1448
|
+
/** Why nothing earlier is served, such as "old-shekel quotes before 1992 are not served". */
|
|
1449
|
+
note?: string;
|
|
1450
|
+
sourceUrl?: string;
|
|
1365
1451
|
firstBarDate: string | null;
|
|
1366
1452
|
lastBarDate: string | null;
|
|
1367
1453
|
barCount: number;
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import { useEffect, useRef, type Dispatch } from "react";
|
|
1
|
+
import { useEffect, useRef, useState, type Dispatch } from "react";
|
|
2
2
|
import { useShortcut } from "../react/input";
|
|
3
3
|
import { useNativeRenderer, useRendererHost, useUiHost } from "../ui";
|
|
4
4
|
import { useDialogState } from "../ui/dialog";
|
|
@@ -13,6 +13,7 @@ import { getVisiblePaneCycleOrder } from "../components/layout/pane/cycle-order"
|
|
|
13
13
|
import { requestFunctionHelp, useFunctionHelpHost } from "../plugins/builtin/help/function-card";
|
|
14
14
|
import { buildRegistryHelpIndex, helpFunctionForPane } from "../plugins/builtin/help/function-index";
|
|
15
15
|
import { recordFunctionOpen } from "../telemetry/usage-counts";
|
|
16
|
+
import { createOneShots } from "../utils/one-shot";
|
|
16
17
|
import { DOCS_PANE_TEMPLATE_ID } from "../docs/content";
|
|
17
18
|
import { registerPaneDocsHandler } from "../docs/requests";
|
|
18
19
|
import { isMoveDownShortcut, isMoveUpShortcut } from "../components/command-bar/keyboard-handlers";
|
|
@@ -117,6 +118,10 @@ export function useAppGlobalShortcuts({
|
|
|
117
118
|
const uiKind = useUiHost().kind;
|
|
118
119
|
const toastHost = useToastHost();
|
|
119
120
|
useKeybindingIssueNotice(keybindings, pluginRegistry, state.initialized);
|
|
121
|
+
// Every action here runs once per press: a held key, or a terminal that does
|
|
122
|
+
// not say it is a repeat, must not run it again. Only moving focus between
|
|
123
|
+
// panes (Tab) and switching layouts by number (idempotent) are left to repeat.
|
|
124
|
+
const [shots] = useState(createOneShots);
|
|
120
125
|
useFunctionHelpHost({
|
|
121
126
|
closeCommandBar: () => {
|
|
122
127
|
if (state.commandBarOpen) dispatch({ type: "SET_COMMAND_BAR", open: false });
|
|
@@ -149,6 +154,23 @@ export function useAppGlobalShortcuts({
|
|
|
149
154
|
|
|
150
155
|
const match = matchKeybinding(keybindings, event);
|
|
151
156
|
const action = match?.kind === "action" ? match.id : null;
|
|
157
|
+
/**
|
|
158
|
+
* Whether the action already ran for this press or hold. An action that
|
|
159
|
+
* takes the key (`claims`) swallows the refused ones as well; one that
|
|
160
|
+
* leaves it to the pane (R) does not, so a pane's own key keeps working.
|
|
161
|
+
*/
|
|
162
|
+
const ranAlready = (id: string, claims = true): boolean => {
|
|
163
|
+
const shot = shots.get(id);
|
|
164
|
+
if (shot.refuses(event)) {
|
|
165
|
+
if (claims) {
|
|
166
|
+
event.preventDefault();
|
|
167
|
+
event.stopPropagation();
|
|
168
|
+
}
|
|
169
|
+
return true;
|
|
170
|
+
}
|
|
171
|
+
shot.end();
|
|
172
|
+
return false;
|
|
173
|
+
};
|
|
152
174
|
|
|
153
175
|
// Terminals send Ctrl; the browser and the desktop webview send Cmd on
|
|
154
176
|
// macOS, which the OpenTUI host also reports as `super` under the kitty
|
|
@@ -172,6 +194,7 @@ export function useAppGlobalShortcuts({
|
|
|
172
194
|
// The status bar's star line answers the same keys once no toast does,
|
|
173
195
|
// but only over the workspace itself.
|
|
174
196
|
if (action === "notification-action" || action === "notification-dismiss") {
|
|
197
|
+
if (ranAlready(action)) return;
|
|
175
198
|
const toastHandled = action === "notification-action"
|
|
176
199
|
? toastHost.activateNewest?.() === true
|
|
177
200
|
: toastHost.dismissNewest?.() === true;
|
|
@@ -195,12 +218,14 @@ export function useAppGlobalShortcuts({
|
|
|
195
218
|
// Ctrl+P and Ctrl+N move the open bar's selection, so a bar chord that
|
|
196
219
|
// is one of them only opens it; Esc and the bar's other chords close it.
|
|
197
220
|
if (state.commandBarOpen && (isMoveUpShortcut(event) || isMoveDownShortcut(event))) return;
|
|
221
|
+
if (ranAlready(action)) return;
|
|
198
222
|
event.preventDefault();
|
|
199
223
|
event.stopPropagation();
|
|
200
224
|
dispatch({ type: "TOGGLE_COMMAND_BAR" });
|
|
201
225
|
return;
|
|
202
226
|
}
|
|
203
227
|
if (!isDetachedWindow && action === "ticker-search" && !state.commandBarOpen) {
|
|
228
|
+
if (ranAlready(action)) return;
|
|
204
229
|
event.preventDefault();
|
|
205
230
|
event.stopPropagation();
|
|
206
231
|
dispatch({
|
|
@@ -233,6 +258,7 @@ export function useAppGlobalShortcuts({
|
|
|
233
258
|
// Command and function keys are never text, so they still fire.
|
|
234
259
|
const editing = state.inputCaptured || event.targetEditable === true;
|
|
235
260
|
if (editing && event.ctrl && !(event.meta || event.super)) return;
|
|
261
|
+
if (ranAlready(`command:${match.command.query}`)) return;
|
|
236
262
|
event.preventDefault();
|
|
237
263
|
event.stopPropagation();
|
|
238
264
|
dispatch({
|
|
@@ -246,6 +272,7 @@ export function useAppGlobalShortcuts({
|
|
|
246
272
|
|
|
247
273
|
// A function key is never text, so the card opens from a focused field too.
|
|
248
274
|
if (action === "function-help") {
|
|
275
|
+
if (ranAlready(action)) return;
|
|
249
276
|
event.preventDefault();
|
|
250
277
|
event.stopPropagation();
|
|
251
278
|
recordFunctionOpen({ shortcut: "HELP", externalPluginId: null });
|
|
@@ -259,6 +286,7 @@ export function useAppGlobalShortcuts({
|
|
|
259
286
|
if (state.inputCaptured) return;
|
|
260
287
|
|
|
261
288
|
if (!isDetachedWindow && action === "help") {
|
|
289
|
+
if (ranAlready(action)) return;
|
|
262
290
|
event.preventDefault();
|
|
263
291
|
event.stopPropagation();
|
|
264
292
|
pluginRegistry.showPane("help");
|
|
@@ -266,13 +294,16 @@ export function useAppGlobalShortcuts({
|
|
|
266
294
|
}
|
|
267
295
|
|
|
268
296
|
if (!isDetachedWindow && action === "quit") {
|
|
297
|
+
if (ranAlready(action, false)) return;
|
|
269
298
|
if (uiKind === "opentui") rendererHost.requestExit();
|
|
270
299
|
} else if (action === "refresh-ticker") {
|
|
300
|
+
if (ranAlready(action, false)) return;
|
|
271
301
|
if (focusedTickerSymbol) {
|
|
272
302
|
const ticker = state.tickers.get(focusedTickerSymbol);
|
|
273
303
|
if (ticker) refreshTicker(ticker.metadata.ticker, ticker.metadata.exchange, ticker, 0);
|
|
274
304
|
}
|
|
275
305
|
} else if (action === "refresh-all") {
|
|
306
|
+
if (ranAlready(action, false)) return;
|
|
276
307
|
for (const ticker of state.tickers.values()) {
|
|
277
308
|
refreshTicker(ticker.metadata.ticker, ticker.metadata.exchange, ticker, 1);
|
|
278
309
|
}
|
|
@@ -280,10 +311,12 @@ export function useAppGlobalShortcuts({
|
|
|
280
311
|
// A release that can install itself downloads on its own, so the key is
|
|
281
312
|
// for the one that waits for a restart and for the one that failed.
|
|
282
313
|
if (!isDetachedWindow && canRestartToApply(state.updateProgress)) {
|
|
314
|
+
if (ranAlready(action)) return;
|
|
283
315
|
event.preventDefault();
|
|
284
316
|
event.stopPropagation();
|
|
285
317
|
restartToApplyUpdate();
|
|
286
318
|
} else if (canRetryUpdate(state)) {
|
|
319
|
+
if (ranAlready(action)) return;
|
|
287
320
|
event.preventDefault();
|
|
288
321
|
event.stopPropagation();
|
|
289
322
|
startUpdate(state.updateAvailable!);
|
|
@@ -296,6 +329,7 @@ export function useAppGlobalShortcuts({
|
|
|
296
329
|
if (ownerId && disabledPlugins.has(ownerId)) continue;
|
|
297
330
|
const chords = resolvePluginShortcutChords(keybindingsConfig, shortcut);
|
|
298
331
|
if (chords.some((chord) => matchesKeyChord(chord, event))) {
|
|
332
|
+
if (ranAlready(`plugin:${shortcut.id}`, false)) return;
|
|
299
333
|
shortcut.execute();
|
|
300
334
|
break;
|
|
301
335
|
}
|
|
@@ -28,6 +28,7 @@ export type CoreKeybindingActionId =
|
|
|
28
28
|
| "pane-screenshot"
|
|
29
29
|
| "pane-export-csv"
|
|
30
30
|
| "pane-share"
|
|
31
|
+
| "pane-ask"
|
|
31
32
|
| "layout-gallery"
|
|
32
33
|
| "tidy-windows"
|
|
33
34
|
| "window-move-mode"
|
|
@@ -59,6 +60,7 @@ export const PANE_ACTION_IDS = new Set<CoreKeybindingActionId>([
|
|
|
59
60
|
"pane-screenshot",
|
|
60
61
|
"pane-export-csv",
|
|
61
62
|
"pane-share",
|
|
63
|
+
"pane-ask",
|
|
62
64
|
"layout-gallery",
|
|
63
65
|
"tidy-windows",
|
|
64
66
|
"window-move-mode",
|
|
@@ -225,9 +227,18 @@ export const KEYBINDING_ACTIONS: readonly KeybindingActionDef[] = [
|
|
|
225
227
|
{
|
|
226
228
|
id: "pane-share",
|
|
227
229
|
category: "Pane Management",
|
|
228
|
-
description: "Share the focused pane.",
|
|
230
|
+
description: "Share the focused pane: post a picture to chat or copy its link.",
|
|
229
231
|
defaults: ["CmdOrCtrl+Shift+S"],
|
|
230
232
|
},
|
|
233
|
+
{
|
|
234
|
+
id: "pane-ask",
|
|
235
|
+
category: "Pane Management",
|
|
236
|
+
description: "Ask Gloom about the focused pane, in a new conversation with the pane attached.",
|
|
237
|
+
// A for ask. Alt+A first, because it reaches most terminals, where
|
|
238
|
+
// Ctrl+Shift+A is often the terminal's own select all; the desktop app
|
|
239
|
+
// advertises the chord on its platform modifier.
|
|
240
|
+
defaults: ["Alt+A", "CmdOrCtrl+Shift+A"],
|
|
241
|
+
},
|
|
231
242
|
{
|
|
232
243
|
id: "layout-gallery",
|
|
233
244
|
category: "Pane Management",
|
|
@@ -16,8 +16,8 @@ import {
|
|
|
16
16
|
} from "../../components/layout/shell/visible-layout";
|
|
17
17
|
import { applyPluginToggles } from "../../plugins/ownership";
|
|
18
18
|
import { setLayoutManagerDispatch } from "../../plugins/builtin/layout-manager";
|
|
19
|
-
import { setMarketplaceHost } from "../../plugins/
|
|
20
|
-
import type { InstalledPlugin } from "../../plugins/
|
|
19
|
+
import { setMarketplaceHost } from "../../plugins/marketplace/store";
|
|
20
|
+
import type { InstalledPlugin } from "../../plugins/marketplace/model";
|
|
21
21
|
import {
|
|
22
22
|
listExternalPlugins,
|
|
23
23
|
removeExternalPlugin,
|