gloomberb 0.16.4 → 0.16.6
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +14 -91
- package/package.json +5 -1
- package/src/{plugins/builtin/cloud → account}/auth-form.tsx +9 -9
- package/src/{plugins/builtin/cloud → account}/auth-model.ts +4 -4
- package/src/account/billing.ts +57 -0
- package/src/{plugins/builtin/cloud → account}/device-signin-dialog.tsx +18 -12
- package/src/{plugins/builtin/cloud → account}/device-signin.ts +2 -2
- package/src/{plugins/builtin/cloud → account}/email-auth-attempt.ts +2 -2
- package/src/account/session.ts +16 -0
- package/src/{plugins/builtin/cloud → account}/upgrade-dialog.tsx +16 -15
- package/src/{plugins/builtin/cloud → account}/upgrade-personalization.ts +7 -7
- package/src/{plugins/builtin/cloud → account}/upgrade-tickers.ts +6 -6
- package/src/{plugins/builtin/cloud → account}/verification-panel.tsx +6 -6
- package/src/api-client/central-bank-rates.ts +6 -1
- package/src/api-client/chat.ts +26 -0
- package/src/api-client/credit-boards.ts +2 -0
- package/src/api-client/data.ts +73 -3
- package/src/api-client/earnings.ts +6 -0
- package/src/api-client/europe-energy.ts +106 -0
- package/src/api-client/futures-curve.ts +56 -0
- package/src/api-client/index.ts +13 -1
- package/src/api-client/market-discovery.ts +13 -1
- package/src/api-client/normalizers.ts +32 -0
- package/src/api-client/paths.ts +7 -0
- package/src/api-client/perps.ts +8 -0
- package/src/api-client/request.ts +9 -2
- package/src/api-client/research-activity.ts +15 -10
- package/src/api-client/socket.ts +29 -0
- package/src/api-client/themes.ts +22 -1
- package/src/api-client/types.ts +78 -2
- package/src/api-client/yield-curves.ts +8 -0
- package/src/app/global-shortcuts.ts +50 -2
- 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 +16 -6
- package/src/app/runtime/desktop-deeplink.ts +10 -5
- package/src/app/runtime/startup.ts +1 -1
- package/src/app.tsx +6 -0
- package/src/architecture/core-builtin-allowlist.json +8 -26
- package/src/ask-gloom/pane-context.ts +114 -0
- package/src/ask-gloom/pane-request.ts +70 -0
- package/src/ask-gloom/pane-text.ts +201 -0
- package/src/brokers/signed-in/sign-in-dialog.tsx +11 -5
- package/src/capabilities/chart-series.ts +19 -2
- 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 +35 -2
- package/src/cli/commands/fred-series.ts +146 -0
- package/src/cli/commands/market.ts +501 -115
- package/src/cli/commands/news-hints.ts +62 -0
- package/src/cli/commands/news-search.ts +53 -0
- package/src/cli/commands/options-leaps.ts +5 -2
- package/src/cli/commands/overview.ts +132 -26
- package/src/cli/commands/remote.ts +2 -1
- package/src/cli/commands/search.ts +317 -13
- package/src/cli/commands/system.ts +55 -8
- package/src/cli/commands/ticker.ts +155 -18
- package/src/cli/context.ts +45 -14
- package/src/cli/desktop-pane-shot.ts +76 -7
- package/src/cli/earnings-calendar.ts +71 -0
- package/src/cli/errors.ts +7 -5
- package/src/cli/exit-codes.ts +8 -0
- package/src/cli/export-source.ts +58 -0
- package/src/cli/freshness.ts +18 -7
- package/src/cli/glossary.ts +483 -0
- package/src/cli/help.ts +10 -0
- package/src/cli/helpers.ts +2 -5
- package/src/cli/history-rows.ts +118 -7
- package/src/cli/index-roots.ts +7 -0
- package/src/cli/index.ts +29 -9
- package/src/cli/known-gaps.ts +84 -0
- package/src/cli/listing-arg.ts +551 -97
- package/src/cli/not-a-ticker.ts +24 -9
- package/src/cli/pane-functions/access-gate.ts +13 -2
- package/src/cli/pane-functions/capabilities.ts +4 -3
- package/src/cli/pane-functions/catalog.ts +214 -40
- package/src/cli/pane-functions/data.ts +42 -8
- package/src/cli/pane-functions/discovery.ts +1 -0
- package/src/cli/pane-functions/dom.ts +37 -8
- package/src/cli/pane-functions/freshness.ts +393 -49
- package/src/cli/pane-functions/function-help.ts +31 -15
- package/src/cli/pane-functions/headless.ts +98 -30
- package/src/cli/pane-functions/index.ts +101 -19
- package/src/cli/pane-functions/market-session.ts +22 -8
- package/src/cli/pane-functions/options.ts +71 -22
- package/src/cli/pane-functions/report-notices.ts +25 -7
- package/src/cli/pane-functions/report.ts +15 -8
- package/src/cli/pane-functions/resolver.ts +74 -19
- package/src/cli/pane-functions/screenshot.ts +250 -27
- package/src/cli/perpetual-contract.ts +60 -0
- package/src/cli/registry.ts +3 -1
- package/src/cli/report-tables.ts +26 -7
- package/src/cli/result.ts +45 -11
- package/src/cli/series-search.ts +111 -0
- package/src/cli/staged-tickers.ts +52 -0
- package/src/cli/symbol-args.ts +27 -0
- package/src/cli/symbol-list.ts +154 -0
- package/src/cli/symbol-rows.ts +154 -0
- package/src/cli/ticker-resolution.ts +311 -27
- package/src/cli/types.ts +5 -0
- package/src/components/chart/composite/axis-overlays.tsx +14 -3
- package/src/components/chart/composite/composite-chart.tsx +71 -11
- package/src/components/chart/composite/crosshair-readout.tsx +150 -0
- 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 +100 -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 +46 -21
- package/src/components/chart/composite/price-axis-labels.tsx +3 -1
- 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/panel/index.tsx +11 -3
- package/src/components/command-bar/panel/runtime.ts +3 -0
- package/src/components/command-bar/panel/types.ts +2 -0
- package/src/components/command-bar/routes/root/plugin-install.ts +4 -4
- package/src/components/command-bar/routes/root/provider-search.ts +4 -3
- package/src/components/command-bar/routes/ticker-search/results.ts +12 -11
- package/src/components/command-bar/routes/ticker-search/route.ts +4 -3
- package/src/components/command-bar/routing/actions.ts +1 -1
- package/src/components/command-bar/workflow/tickers.ts +42 -17
- package/src/components/layout/detached-pane-shell.tsx +68 -39
- package/src/components/layout/floating-pane.tsx +10 -1
- package/src/components/layout/header.tsx +25 -5
- package/src/components/layout/missing-pane.tsx +3 -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/content.tsx +7 -13
- package/src/components/layout/pane/footer/index.tsx +6 -2
- package/src/components/layout/pane/footer/keyboard.ts +3 -0
- package/src/components/layout/pane/footer/model.ts +41 -1
- package/src/components/layout/pane/header.tsx +50 -1
- package/src/components/layout/pane/index.tsx +21 -3
- package/src/components/layout/pane/sidebar.tsx +88 -21
- package/src/components/layout/shell/active-drag.ts +21 -5
- package/src/components/layout/shell/cursor-occlusion.ts +2 -1
- package/src/components/layout/shell/drag/index.ts +39 -9
- package/src/components/layout/shell/drag/live.ts +61 -51
- package/src/components/layout/shell/drag/runtime.ts +54 -12
- package/src/components/layout/shell/index.tsx +84 -65
- package/src/components/layout/shell/menu.ts +14 -1
- package/src/components/layout/shell/native/pointer-runtime.ts +3 -1
- package/src/components/layout/shell/pane/actions.ts +32 -10
- package/src/components/layout/shell/pane/ask.ts +131 -0
- package/src/components/layout/shell/pane/capture.ts +162 -0
- package/src/components/layout/shell/pane/layers.tsx +218 -50
- package/src/components/layout/shell/pane/management-shortcuts.ts +46 -1
- package/src/components/layout/shell/shortcuts.ts +21 -4
- package/src/components/layout/shell/terminal-pointer-runtime.ts +24 -0
- package/src/components/markdown-text.tsx +62 -20
- package/src/components/metric-treemap/heat-surface.tsx +8 -1
- package/src/components/onboarding/account-step/form-panel.tsx +1 -1
- package/src/components/onboarding/account-step/index.tsx +1 -1
- package/src/components/onboarding/account-step/qr-panel.tsx +1 -1
- package/src/components/onboarding/account-step/signed-in-panel.tsx +1 -1
- package/src/components/onboarding/onboarding-keyboard.ts +1 -1
- package/src/components/onboarding/onboarding-wizard.tsx +2 -2
- package/src/components/onboarding/use-onboarding-upgrade.ts +3 -3
- package/src/components/onboarding/wizard-account.ts +2 -2
- package/src/components/pane-template-wizard.tsx +9 -1
- package/src/components/price-selector-dialog.tsx +11 -2
- package/src/components/reader/article-reader.tsx +642 -0
- package/src/components/reader/article-text.ts +527 -0
- package/src/components/sign-in-gate.tsx +3 -3
- package/src/components/ticker/list-table-view.tsx +43 -2
- package/src/components/ui/action-row.tsx +2 -1
- package/src/components/ui/button.tsx +7 -1
- package/src/components/ui/choice-dialog.tsx +6 -4
- package/src/components/ui/confirm-dialog.tsx +28 -18
- package/src/components/ui/data-table/index.tsx +18 -6
- package/src/components/ui/data-table/opentui/index.tsx +37 -6
- package/src/components/ui/data-table/types.ts +12 -0
- package/src/components/ui/dialog-actions.tsx +64 -0
- package/src/components/ui/display.tsx +17 -3
- package/src/components/ui/frame.tsx +35 -2
- package/src/components/ui/icon.tsx +6 -1
- package/src/components/ui/query-bar.tsx +10 -1
- package/src/components/ui/text-prompt-dialog.tsx +11 -9
- package/src/data/cached-query.ts +2 -0
- package/src/data/config/store/migrations.ts +7 -0
- package/src/data/config/store/normalize.ts +7 -2
- package/src/data/config/store/portfolio-as-of-column.ts +57 -0
- package/src/data/ticker-repository.ts +5 -0
- package/src/data/ticker-store.ts +15 -0
- package/src/docs/content.ts +215 -0
- package/src/docs/load.ts +139 -0
- package/src/docs/requests.ts +39 -0
- package/src/docs/snapshot.chunk.ts +8 -0
- package/src/docs/snapshot.json +7555 -0
- package/src/docs/topics.ts +216 -0
- package/src/i18n/es.ts +65 -5
- package/src/i18n/ja.ts +65 -5
- package/src/i18n/ko.ts +65 -5
- package/src/i18n/zh-cn.ts +65 -5
- package/src/i18n/zh-tw.ts +65 -5
- package/src/layout/desks.ts +1 -1
- package/src/layout/pane-manager/dock-tree.ts +18 -0
- package/src/layout/pane-manager/index.ts +1 -0
- package/src/layout-marketplace/gallery.tsx +1 -1
- package/src/market-data/coordinator/chart.ts +10 -4
- package/src/market-data/coordinator/index.ts +6 -3
- package/src/{plugins/builtin/futures/contracts.ts → market-data/futures-board.ts} +81 -28
- package/src/market-data/futures-contract.ts +151 -0
- package/src/market-data/hooks.tsx +10 -2
- package/src/market-data/market/format.ts +39 -21
- package/src/market-data/market/freshness.ts +84 -20
- package/src/market-data/market/session-close-note.ts +3 -2
- package/src/market-data/market/status.ts +19 -23
- package/src/market-data/published-apac-sessions.ts +23 -1
- package/src/market-data/quotes/contributions.ts +5 -0
- package/src/market-data/quotes/metadata.ts +19 -24
- package/src/market-data/quotes/resolution.ts +5 -0
- package/src/market-data/quotes/screener-live-quotes.ts +5 -4
- package/src/market-data/result-types.ts +2 -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/index.tsx +1 -0
- package/src/plugins/builtin/account-management/model.ts +1 -56
- package/src/plugins/builtin/account-management/pane.tsx +6 -4
- package/src/plugins/builtin/account-management/password-dialog.tsx +1 -1
- package/src/plugins/builtin/alerts/catalysts.ts +1 -1
- package/src/plugins/builtin/alerts/cli.ts +313 -47
- package/src/plugins/builtin/alerts/events-pane.tsx +45 -7
- package/src/plugins/builtin/alerts/events.ts +23 -2
- package/src/plugins/builtin/alerts/focus.ts +27 -0
- package/src/plugins/builtin/alerts/history-pane.tsx +7 -2
- package/src/plugins/builtin/alerts/history.ts +2 -0
- package/src/plugins/builtin/alerts/index.tsx +47 -11
- package/src/plugins/builtin/alerts/pane.tsx +27 -1
- package/src/plugins/builtin/alerts/research-builder.ts +8 -3
- package/src/plugins/builtin/alerts/research-rules.ts +18 -2
- package/src/plugins/builtin/alerts/scheduled-check.ts +122 -0
- package/src/plugins/builtin/alerts/scheduled-sources.ts +25 -0
- package/src/plugins/builtin/alerts/scheduled.ts +254 -0
- package/src/plugins/builtin/alerts/targets.ts +92 -0
- package/src/plugins/builtin/analytics/index.tsx +8 -3
- package/src/plugins/builtin/analytics/risk-headless.ts +60 -27
- package/src/plugins/builtin/analytics/risk-math.ts +91 -27
- package/src/plugins/builtin/analytics/risk-model.ts +35 -5
- package/src/plugins/builtin/analytics/risk-pane.tsx +15 -8
- package/src/plugins/builtin/attention/headless.ts +1 -1
- package/src/plugins/builtin/attention/index.tsx +2 -0
- package/src/plugins/builtin/attention/pane.tsx +3 -1
- package/src/plugins/builtin/attention/series.ts +26 -0
- package/src/plugins/builtin/awards/headless.ts +88 -18
- package/src/plugins/builtin/awards/index.tsx +2 -0
- package/src/plugins/builtin/awards/model.ts +41 -1
- package/src/plugins/builtin/awards/pane.tsx +22 -13
- package/src/plugins/builtin/awards/series.ts +29 -0
- package/src/plugins/builtin/backtest/headless.ts +2 -2
- package/src/plugins/builtin/bond-calculator/model.ts +2 -1
- package/src/plugins/builtin/broker-manager/index.tsx +1 -0
- package/src/plugins/builtin/catalysts/headless.ts +1 -1
- package/src/plugins/builtin/catalysts/pane.tsx +3 -1
- package/src/plugins/builtin/cds/client.ts +49 -12
- package/src/plugins/builtin/cds/headless.ts +119 -19
- package/src/plugins/builtin/cds/index.tsx +3 -1
- package/src/plugins/builtin/cds/model.ts +214 -32
- package/src/plugins/builtin/cds/pane.tsx +58 -14
- package/src/plugins/builtin/cds/series.ts +19 -0
- 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 +3 -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 +36 -0
- package/src/plugins/builtin/chart-composer/catalog-inventory.ts +193 -255
- package/src/plugins/builtin/chart-composer/data-catalog-pane.tsx +84 -46
- package/src/plugins/builtin/chart-composer/editor.tsx +5 -4
- package/src/plugins/builtin/chart-composer/field-series.ts +40 -0
- package/src/plugins/builtin/chart-composer/headless-schema.ts +1 -1
- package/src/plugins/builtin/chart-composer/headless.ts +70 -5
- package/src/plugins/builtin/chart-composer/index.tsx +15 -3
- package/src/plugins/builtin/chart-composer/pane.tsx +81 -38
- package/src/plugins/builtin/chart-composer/series-catalog.ts +58 -50
- package/src/plugins/builtin/chart-composer/series-expression.ts +18 -10
- package/src/plugins/builtin/chart-composer/use-series-catalog.ts +59 -3
- package/src/plugins/builtin/chart-composer/user-series.ts +84 -0
- package/src/plugins/builtin/chat/content/composer-runtime.ts +6 -1
- package/src/plugins/builtin/chat/content/composer.tsx +5 -1
- package/src/plugins/builtin/chat/content/footer.tsx +12 -0
- package/src/plugins/builtin/chat/content/index.tsx +89 -5
- package/src/plugins/builtin/chat/content/new-dm-dialog.tsx +10 -2
- package/src/plugins/builtin/chat/content/new-messages.tsx +89 -0
- package/src/plugins/builtin/chat/content/row-activity.ts +132 -0
- package/src/plugins/builtin/chat/content/scroll.ts +127 -27
- package/src/plugins/builtin/chat/content/shortcuts.ts +2 -2
- package/src/plugins/builtin/chat/content/transcript.tsx +145 -78
- 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 +123 -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/index.tsx +23 -5
- package/src/plugins/builtin/chat/layout.ts +78 -5
- package/src/plugins/builtin/chat/message/ai-badge.tsx +18 -0
- package/src/plugins/builtin/chat/message/desktop.tsx +55 -6
- package/src/plugins/builtin/chat/message/header.tsx +16 -4
- package/src/plugins/builtin/chat/message/profile-popover.tsx +5 -1
- package/src/plugins/builtin/chat/message/reactions.tsx +210 -0
- package/src/plugins/builtin/chat/message/render-state.ts +18 -2
- package/src/plugins/builtin/chat/message/terminal.tsx +43 -4
- package/src/plugins/builtin/chat/message/types.ts +12 -0
- 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 +6 -3
- package/src/plugins/builtin/chat/unread-inbox-pane.tsx +148 -27
- package/src/plugins/builtin/chat/unread-inbox.ts +22 -0
- package/src/plugins/builtin/cloud/askg/attached-pane.tsx +69 -0
- package/src/plugins/builtin/cloud/askg/controller.ts +111 -19
- package/src/plugins/builtin/cloud/askg/executor.ts +57 -3
- package/src/plugins/builtin/cloud/askg/manifest.ts +32 -7
- package/src/plugins/builtin/cloud/askg/model.ts +27 -8
- 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/askg/protocol.ts +10 -1
- package/src/plugins/builtin/cloud/askg/tool-display.ts +3 -0
- package/src/plugins/builtin/cloud/askg/undo.ts +2 -0
- package/src/plugins/builtin/cloud/auth-actions.tsx +1 -1
- package/src/plugins/builtin/cloud/auth-commands.ts +1 -1
- package/src/plugins/builtin/cloud/auth-dialog.tsx +3 -3
- package/src/plugins/builtin/cloud/company-picker.tsx +1 -1
- package/src/plugins/builtin/cloud/mcp-connect/dialog.tsx +3 -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/terminal-relay/engine.ts +77 -9
- package/src/plugins/builtin/cloud/terminal-relay/manifest.ts +6 -1
- package/src/plugins/builtin/cloud/terminal-relay/policy.ts +9 -0
- package/src/plugins/builtin/cloud/terminal-relay/prompts.tsx +35 -11
- package/src/plugins/builtin/cloud/thesis/exposure.ts +1 -1
- package/src/plugins/builtin/cloud/thesis/module.tsx +1 -0
- package/src/plugins/builtin/cloud/thesis/prompts.tsx +2 -1
- package/src/plugins/builtin/company-attention/app-rank.tsx +1 -1
- package/src/plugins/builtin/company-attention/headless.ts +21 -7
- package/src/plugins/builtin/company-attention/index.tsx +2 -0
- package/src/plugins/builtin/company-attention/model.ts +26 -7
- package/src/plugins/builtin/company-attention/pane.tsx +12 -9
- package/src/plugins/builtin/company-attention/series.ts +52 -0
- 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 +17 -16
- package/src/plugins/builtin/composite-plugins.ts +19 -13
- package/src/plugins/builtin/connections/index.ts +1 -0
- package/src/plugins/builtin/cot/headless.ts +1 -1
- package/src/plugins/builtin/cot/index.tsx +3 -1
- package/src/plugins/builtin/cot/model.ts +40 -11
- package/src/plugins/builtin/cot/series.ts +27 -0
- 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 +2 -0
- package/src/plugins/builtin/credit-boards/model.ts +11 -1
- package/src/plugins/builtin/credit-boards/series.ts +66 -0
- 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 +18 -9
- package/src/plugins/builtin/credit-conditions/model.ts +19 -11
- package/src/plugins/builtin/credit-conditions/series.ts +16 -0
- package/src/plugins/builtin/credit-documents/headless.ts +33 -3
- package/src/plugins/builtin/credit-documents/pane.tsx +3 -1
- package/src/plugins/builtin/crypto-board/headless.ts +2 -3
- package/src/plugins/builtin/crypto-board/index.tsx +2 -0
- package/src/plugins/builtin/crypto-board/model.ts +12 -0
- package/src/plugins/builtin/crypto-board/pane.tsx +19 -12
- package/src/plugins/builtin/crypto-board/series.ts +48 -0
- package/src/plugins/builtin/custom-view/live-quotes.ts +2 -2
- package/src/plugins/builtin/debt-maturities/headless.ts +17 -11
- package/src/plugins/builtin/debt-maturities/index.tsx +2 -0
- package/src/plugins/builtin/debt-maturities/series.ts +45 -0
- package/src/plugins/builtin/dividend-yield/client.ts +3 -0
- package/src/plugins/builtin/dividend-yield/headless.ts +7 -4
- package/src/plugins/builtin/dividend-yield/index.tsx +3 -1
- package/src/plugins/builtin/dividend-yield/pane.tsx +3 -1
- package/src/plugins/builtin/dividend-yield/series.ts +20 -0
- package/src/plugins/builtin/dividend-yield/types.ts +2 -0
- package/src/plugins/builtin/docs/blocks.tsx +181 -0
- package/src/plugins/builtin/docs/index.tsx +68 -0
- package/src/plugins/builtin/docs/pane.tsx +426 -0
- package/src/plugins/builtin/docs/targets.ts +72 -0
- package/src/plugins/builtin/docs/use-docs.ts +60 -0
- package/src/plugins/builtin/doe/headless.ts +12 -8
- package/src/plugins/builtin/doe/index.tsx +2 -0
- package/src/plugins/builtin/doe/series.ts +62 -0
- package/src/plugins/builtin/earnings/client.ts +3 -2
- package/src/plugins/builtin/earnings/format.ts +1 -5
- package/src/plugins/builtin/earnings/headless.ts +58 -6
- package/src/plugins/builtin/earnings/history-model.ts +15 -1
- package/src/plugins/builtin/earnings/history-table.ts +13 -2
- package/src/plugins/builtin/earnings/history.tsx +7 -3
- package/src/plugins/builtin/earnings/index.tsx +9 -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-ripple/index.tsx +2 -0
- package/src/plugins/builtin/econ/fred-catalog.ts +198 -0
- package/src/plugins/builtin/econ/fred-series-map.ts +0 -46
- package/src/plugins/builtin/econ/index.tsx +2 -0
- package/src/plugins/builtin/econ-statistics/defs.ts +5 -0
- package/src/plugins/builtin/econ-statistics/headless.ts +19 -4
- package/src/plugins/builtin/econ-statistics/stats.ts +1 -0
- package/src/plugins/builtin/equity-screener/headless.ts +3 -3
- package/src/plugins/builtin/equity-screener/pane.tsx +4 -11
- package/src/plugins/builtin/estimate-revisions/headless.ts +3 -3
- package/src/plugins/builtin/exposure/drivers.ts +13 -0
- package/src/plugins/builtin/exposure/headless.ts +205 -13
- package/src/plugins/builtin/exposure/holdings.ts +1 -1
- 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 +14 -12
- package/src/plugins/builtin/fear-greed/index.tsx +18 -10
- package/src/plugins/builtin/fear-greed/series.ts +52 -0
- package/src/plugins/builtin/futures/index.tsx +43 -3
- package/src/plugins/builtin/futures/model.ts +1 -1
- package/src/plugins/builtin/futures/returns.ts +1 -1
- package/src/plugins/builtin/futures/series.ts +13 -0
- package/src/plugins/builtin/futures/table.tsx +1 -1
- package/src/plugins/builtin/futures/use-front-returns.ts +1 -1
- package/src/plugins/builtin/futures-curve/client.ts +12 -3
- package/src/plugins/builtin/futures-curve/headless.ts +71 -10
- package/src/plugins/builtin/futures-curve/index.tsx +1 -1
- package/src/plugins/builtin/futures-curve/model.ts +66 -11
- package/src/plugins/builtin/futures-curve/pane.tsx +52 -18
- 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 +4 -4
- package/src/plugins/builtin/gpu/board.tsx +13 -10
- package/src/plugins/builtin/gpu/changes.tsx +4 -4
- package/src/plugins/builtin/gpu/client.ts +19 -1
- package/src/plugins/builtin/gpu/equities.tsx +14 -10
- package/src/plugins/builtin/gpu/headless.ts +58 -27
- package/src/plugins/builtin/gpu/history.tsx +3 -3
- package/src/plugins/builtin/gpu/index.tsx +2 -0
- package/src/plugins/builtin/gpu/model.ts +101 -16
- package/src/plugins/builtin/gpu/pane.tsx +28 -12
- package/src/plugins/builtin/gpu/series.ts +38 -0
- package/src/plugins/builtin/help/function-card.tsx +25 -6
- package/src/plugins/builtin/help/function-index.ts +2 -0
- package/src/plugins/builtin/help/index.tsx +31 -9
- package/src/plugins/builtin/holders/beneficial-model.ts +90 -3
- package/src/plugins/builtin/holders/beneficial-report.ts +57 -5
- package/src/plugins/builtin/holders/beneficial-view.tsx +55 -11
- package/src/plugins/builtin/holders/client.ts +22 -3
- package/src/plugins/builtin/holders/format.ts +18 -3
- package/src/plugins/builtin/holders/headless.ts +36 -133
- package/src/plugins/builtin/holders/pane.tsx +11 -4
- package/src/plugins/builtin/holders/report-header.ts +40 -5
- package/src/plugins/builtin/holders/report-rows.ts +240 -0
- package/src/plugins/builtin/insider/client.ts +35 -20
- package/src/plugins/builtin/insider/headless.ts +41 -11
- package/src/plugins/builtin/insider/index.tsx +26 -9
- package/src/plugins/builtin/insider/insider-data.ts +10 -0
- package/src/plugins/builtin/insider/issuer.ts +49 -0
- package/src/plugins/builtin/insider/model.ts +3 -0
- package/src/plugins/builtin/ipo-calendar/headless.ts +1 -1
- package/src/plugins/builtin/iv-history/client.ts +20 -6
- package/src/plugins/builtin/iv-history/format.ts +9 -0
- package/src/plugins/builtin/iv-history/headless.ts +56 -21
- package/src/plugins/builtin/iv-history/index.tsx +2 -0
- package/src/plugins/builtin/iv-history/model.ts +143 -8
- package/src/plugins/builtin/iv-history/screen-pane.tsx +5 -9
- package/src/plugins/builtin/iv-history/series.ts +29 -0
- package/src/plugins/builtin/jobs/headless.ts +26 -3
- package/src/plugins/builtin/jobs/index.tsx +3 -1
- package/src/plugins/builtin/jobs/series.ts +19 -0
- package/src/plugins/builtin/kelly-sizer/index.tsx +2 -0
- package/src/plugins/builtin/kelly-sizer/pane.tsx +2 -1
- package/src/plugins/builtin/kelly-sizer/portfolio.ts +0 -39
- package/src/plugins/builtin/macro-day/client.ts +44 -3
- package/src/plugins/builtin/macro-day/headless.ts +13 -10
- package/src/plugins/builtin/macro-day/model.ts +56 -10
- package/src/plugins/builtin/macro-day/pane.tsx +30 -20
- package/src/plugins/builtin/market-heatmap/headless.ts +20 -5
- package/src/plugins/builtin/market-heatmap/index.tsx +6 -0
- package/src/plugins/builtin/market-heatmap/model.ts +19 -11
- package/src/plugins/builtin/market-heatmap/portfolio.ts +2 -2
- package/src/plugins/builtin/market-movers/client.ts +7 -5
- package/src/plugins/builtin/market-movers/index.tsx +3 -2
- package/src/plugins/builtin/market-movers/model.ts +30 -0
- package/src/plugins/builtin/market-movers/screener.ts +31 -0
- package/src/plugins/builtin/market-valuation/chart-series.ts +29 -69
- package/src/plugins/builtin/market-valuation/index.tsx +3 -3
- package/src/plugins/builtin/market-valuation/indicators.ts +0 -5
- package/src/plugins/builtin/members/headless.ts +8 -3
- package/src/plugins/builtin/members/model.ts +31 -3
- package/src/plugins/builtin/members/pane.tsx +6 -8
- package/src/plugins/builtin/mna/distress/headless.ts +4 -4
- package/src/plugins/builtin/mna/headless.ts +18 -6
- package/src/plugins/builtin/money-markets/headless.ts +5 -4
- package/src/plugins/builtin/money-markets/index.tsx +2 -0
- package/src/plugins/builtin/money-markets/series.ts +41 -0
- package/src/plugins/builtin/news/index.tsx +0 -2
- 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/notes/cli.ts +12 -7
- package/src/plugins/builtin/notes/index.tsx +1 -0
- package/src/plugins/builtin/options/index.tsx +3 -0
- package/src/plugins/builtin/options/view.tsx +1 -1
- package/src/plugins/builtin/options-calculator/inputs.ts +2 -1
- package/src/plugins/builtin/options-positioning/client.ts +7 -3
- package/src/plugins/builtin/options-positioning/headless.ts +4 -3
- package/src/plugins/builtin/options-positioning/pane.tsx +2 -2
- package/src/plugins/builtin/options-scenario/client.ts +2 -1
- package/src/plugins/builtin/options-scenario/headless.ts +1 -0
- package/src/plugins/builtin/options-scenario/hedge.ts +2 -1
- package/src/plugins/builtin/perps/client.ts +90 -16
- package/src/plugins/builtin/perps/equity-row.tsx +52 -17
- package/src/plugins/builtin/perps/freshness.ts +66 -0
- package/src/plugins/builtin/perps/headless.ts +47 -32
- package/src/plugins/builtin/perps/index.tsx +23 -4
- package/src/plugins/builtin/perps/list-perpetuals.ts +118 -0
- package/src/plugins/builtin/perps/model.ts +20 -5
- package/src/plugins/builtin/perps/open-market.ts +15 -0
- package/src/plugins/builtin/perps/pane.tsx +76 -20
- package/src/plugins/builtin/perps/series.ts +76 -0
- package/src/plugins/builtin/plugin-marketplace/index.tsx +1 -1
- package/src/plugins/builtin/plugin-marketplace/pane.tsx +73 -67
- package/src/plugins/builtin/plugin-module.ts +3 -0
- package/src/plugins/builtin/portfolio-list/account-metrics.ts +1 -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 +161 -0
- package/src/plugins/builtin/portfolio-list/cli/import-13f.ts +109 -0
- package/src/plugins/builtin/portfolio-list/cli/portfolio-command.ts +384 -74
- package/src/plugins/builtin/portfolio-list/cli/render.ts +437 -71
- package/src/plugins/builtin/portfolio-list/cli/shared.ts +21 -4
- package/src/plugins/builtin/portfolio-list/cli/watchlist-command.ts +121 -47
- package/src/plugins/builtin/portfolio-list/column-values.ts +104 -26
- package/src/plugins/builtin/portfolio-list/grid.tsx +1 -1
- package/src/plugins/builtin/portfolio-list/headless.ts +84 -18
- package/src/plugins/builtin/portfolio-list/imported-from.ts +8 -0
- package/src/plugins/builtin/portfolio-list/index.tsx +5 -1
- package/src/plugins/builtin/portfolio-list/live-valuation.ts +6 -2
- 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 +52 -9
- package/src/plugins/builtin/portfolio-list/quick-add/index.tsx +33 -11
- 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 +9 -4
- package/src/plugins/builtin/portfolio-list/table.tsx +37 -7
- package/src/plugins/builtin/power/client.ts +16 -0
- package/src/plugins/builtin/power/evidence.ts +63 -10
- package/src/plugins/builtin/power/headless.ts +77 -9
- package/src/plugins/builtin/power/index.tsx +28 -3
- package/src/plugins/builtin/power/model.ts +73 -2
- package/src/plugins/builtin/power/pane.tsx +37 -9
- package/src/plugins/builtin/power/prices-client.ts +139 -0
- package/src/plugins/builtin/power/prices-headless.ts +137 -0
- package/src/plugins/builtin/power/prices-model.ts +103 -0
- package/src/plugins/builtin/power/prices.tsx +179 -0
- package/src/plugins/builtin/rate-path/headless.ts +46 -18
- package/src/plugins/builtin/realized-vol/headless.ts +5 -0
- package/src/plugins/builtin/relative-rotation/headless.ts +3 -3
- package/src/plugins/builtin/research/corporate-actions-pane.tsx +5 -2
- package/src/plugins/builtin/research/event-model.ts +68 -24
- package/src/plugins/builtin/research/events-headless.ts +2 -1
- package/src/plugins/builtin/research/headless.ts +2 -1
- package/src/plugins/builtin/research/index.tsx +2 -0
- 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/seasonality/client.ts +15 -7
- package/src/plugins/builtin/seasonality/headless.ts +36 -12
- package/src/plugins/builtin/seasonality/index.tsx +2 -2
- package/src/plugins/builtin/seasonality/model.ts +119 -0
- package/src/plugins/builtin/seasonality/pane.tsx +108 -37
- package/src/plugins/builtin/sec/headless.ts +25 -3
- package/src/plugins/builtin/sec/index.tsx +2 -1
- package/src/plugins/builtin/series-inventory.ts +93 -0
- package/src/plugins/builtin/shared/cloud-denied.ts +15 -0
- package/src/plugins/builtin/shared/cloud-upgrade.ts +1 -1
- package/src/plugins/builtin/shared/command-tab.ts +30 -12
- package/src/plugins/builtin/shared/earnings-report.ts +55 -0
- package/src/plugins/builtin/shared/fred-points.ts +20 -0
- package/src/plugins/builtin/shared/free-preview.ts +47 -0
- package/src/plugins/builtin/shared/fx-rate-freshness.ts +101 -0
- package/src/plugins/builtin/shared/open-description.ts +29 -0
- package/src/plugins/builtin/shared/report-freshness.ts +12 -1
- package/src/plugins/builtin/shared/series-warning.ts +5 -0
- package/src/plugins/builtin/shared/volatility/options.ts +4 -1
- package/src/plugins/builtin/short-interest/headless.ts +1 -0
- package/src/plugins/builtin/short-interest/index.tsx +2 -0
- package/src/plugins/builtin/short-interest/series.ts +36 -0
- package/src/plugins/builtin/short-interest/watch-headless.ts +3 -2
- package/src/plugins/builtin/short-interest/watch-model.ts +9 -5
- package/src/plugins/builtin/short-volume/headless.ts +2 -1
- package/src/plugins/builtin/short-volume/index.tsx +2 -0
- package/src/plugins/builtin/short-volume/series.ts +23 -0
- package/src/plugins/builtin/social-mentions/headless.ts +1 -1
- package/src/plugins/builtin/social-mentions/index.tsx +2 -0
- package/src/plugins/builtin/social-mentions/series.ts +23 -0
- package/src/plugins/builtin/supply-chain/graph-pane.tsx +3 -2
- 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 +8 -6
- 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/thirteenf/api.ts +1 -0
- package/src/plugins/builtin/thirteenf/data.ts +6 -4
- package/src/plugins/builtin/thirteenf/headless.ts +217 -36
- package/src/plugins/builtin/thirteenf/model.ts +39 -1
- package/src/plugins/builtin/thirteenf/overlap.ts +75 -0
- package/src/plugins/builtin/thirteenf/pane.tsx +10 -1
- package/src/plugins/builtin/thirteenf/report-notes.ts +103 -1
- package/src/plugins/builtin/thirteenf/types.ts +2 -0
- 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/headless-schema.ts +30 -0
- package/src/plugins/builtin/ticker-detail/headless.ts +86 -0
- package/src/plugins/builtin/ticker-detail/index.tsx +26 -11
- package/src/plugins/builtin/ticker-detail/overview/components.tsx +1 -1
- package/src/plugins/builtin/ticker-detail/overview/futures-contract.ts +31 -0
- package/src/plugins/builtin/ticker-detail/overview/model.ts +3 -3
- package/src/plugins/builtin/ticker-detail/overview/pane.tsx +2 -1
- package/src/plugins/builtin/ticker-detail/overview-tab.tsx +49 -5
- package/src/plugins/builtin/ticker-detail/quote-monitor/index.tsx +13 -3
- package/src/plugins/builtin/time-sales/headless.ts +2 -1
- package/src/plugins/builtin/time-sales/index.tsx +2 -1
- package/src/plugins/builtin/treasury-auctions/headless.ts +16 -2
- package/src/plugins/builtin/treasury-auctions/index.tsx +1 -0
- package/src/plugins/builtin/treasury-auctions/model.ts +8 -0
- package/src/plugins/builtin/vol-surface/evidence.ts +7 -1
- package/src/plugins/builtin/vol-surface/headless.ts +51 -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/volatility/index.tsx +2 -0
- package/src/plugins/builtin/volatility/series.ts +84 -0
- 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/geo-draw.tsx +2 -1
- package/src/plugins/builtin/world-venue-map/geo-series.ts +26 -1
- package/src/plugins/builtin/world-venue-map/geo-svg.tsx +6 -6
- package/src/plugins/builtin/world-venue-map/headless.ts +4 -1
- package/src/plugins/builtin/world-venue-map/index.ts +2 -1
- package/src/plugins/builtin/world-venue-map/layered-pane.tsx +24 -13
- package/src/plugins/builtin/world-venue-map/layers.ts +29 -0
- package/src/plugins/builtin/world-venue-map/map.tsx +144 -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/chart.ts +2 -2
- package/src/plugins/builtin/yield-curve/curves.ts +21 -8
- package/src/plugins/builtin/yield-curve/headless.ts +71 -18
- package/src/plugins/builtin/yield-curve/index.tsx +4 -2
- package/src/plugins/builtin/yield-curve/series.ts +86 -0
- package/src/plugins/catalog-browser.ts +2 -1
- 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 +6 -6
- package/src/plugins/{builtin/plugin-marketplace → marketplace}/store.ts +1 -1
- package/src/plugins/registry/host-actions.ts +11 -0
- package/src/plugins/registry/index.ts +89 -4
- package/src/portfolio/collection-name.ts +31 -0
- package/src/{plugins/builtin/portfolio-list → portfolio}/position-metrics.ts +6 -6
- package/src/portfolio/position-value.ts +40 -0
- package/src/portfolio/valuation-basis.ts +79 -0
- package/src/public/__snapshots__/public-api.test.ts.snap +7 -0
- package/src/public/time-series.ts +17 -0
- package/src/react/auto-refresh.ts +13 -3
- package/src/react/input.ts +33 -1
- package/src/react/key-repeat.ts +86 -0
- package/src/remote/app-host.tsx +20 -4
- package/src/remote/confirm-change.tsx +85 -0
- package/src/remote/controller-utils.ts +8 -1
- package/src/remote/controller.ts +144 -7
- package/src/remote/pane-screenshot.ts +47 -0
- package/src/remote/schema.ts +65 -2
- package/src/remote/types.ts +30 -0
- package/src/remote/watchlist.ts +306 -0
- package/src/renderers/browser/main.tsx +4 -3
- package/src/renderers/browser/research-entry.ts +4 -2
- package/src/renderers/cloudflare/worker.ts +1 -1
- package/src/renderers/dom/data-table/frozen-column.ts +3 -1
- package/src/renderers/dom/data-table/index.tsx +33 -6
- package/src/renderers/dom/data-table/row.tsx +30 -1
- package/src/renderers/dom/desktop/control-styles.ts +63 -1
- package/src/renderers/dom/desktop/controls.tsx +30 -23
- package/src/renderers/dom/desktop/dialog-actions.tsx +170 -0
- package/src/renderers/dom/desktop/icons.tsx +16 -0
- package/src/renderers/dom/dom-ui-host.tsx +3 -0
- package/src/renderers/dom/host/block-glyph-canvas.tsx +6 -3
- package/src/renderers/dom/host/box.tsx +8 -0
- package/src/renderers/dom/host/chart-surface.tsx +33 -2
- package/src/renderers/dom/host/live-frame.ts +6 -2
- package/src/renderers/dom/host/overflow-fade.ts +14 -1
- package/src/renderers/dom/host/scroll-box.tsx +32 -0
- package/src/renderers/dom/host/size-observer.ts +41 -0
- package/src/renderers/dom/host/sticky-scroll.ts +128 -0
- package/src/renderers/dom/host/style.ts +1 -1
- package/src/renderers/dom/host/surface-3d.tsx +19 -7
- package/src/renderers/dom/host/surface-fit.ts +406 -0
- package/src/renderers/dom/host/text.tsx +1 -1
- package/src/renderers/dom/input-host.tsx +1 -0
- package/src/renderers/dom/styles.css +102 -5
- package/src/renderers/electrobun/bun/application-menu/click.ts +18 -0
- package/src/renderers/electrobun/bun/index.ts +3 -2
- package/src/renderers/electrobun/shared/protocol.ts +1 -1
- package/src/renderers/electrobun/view/cli-pane-shot-entry.tsx +29 -2
- package/src/renderers/electrobun/view/cli-pane-shot-frame.tsx +63 -20
- package/src/renderers/electrobun/view/cli-pane-shot-health.ts +10 -26
- package/src/renderers/electrobun/view/main.tsx +5 -3
- package/src/renderers/electrobun/view/remote/asset-data-client.ts +2 -0
- 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/capability.ts +75 -0
- package/src/series/csv.ts +160 -0
- package/src/series/files.ts +107 -0
- package/src/series/registry.ts +198 -0
- package/src/series/resolve.ts +108 -0
- package/src/series/standalone.ts +48 -0
- package/src/series/types.ts +153 -0
- package/src/series/validate.ts +171 -0
- 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/pane-image.ts +152 -0
- package/src/shares/personal-pane.ts +64 -0
- package/src/shares/portable-layout.ts +4 -2
- package/src/shares/prepare.ts +20 -0
- package/src/sources/gloomberb-cloud/index.ts +109 -10
- package/src/sources/gloomberb-cloud/normalizers.ts +3 -0
- package/src/sources/gloomberb-cloud/perpetuals.ts +249 -0
- package/src/sources/history-result.ts +1 -0
- package/src/sources/history-retention.ts +11 -0
- package/src/sources/listing-symbols.ts +4 -1
- package/src/sources/listing-target.ts +4 -0
- package/src/sources/provider-router/batches.ts +4 -1
- package/src/sources/provider-router/cache.ts +4 -2
- package/src/sources/provider-router/cached-routes.ts +1 -1
- package/src/sources/provider-router/financial-routes.ts +1 -0
- package/src/sources/provider-router/financials.ts +13 -0
- package/src/sources/provider-router/history.ts +43 -25
- package/src/sources/provider-router/index.ts +14 -0
- package/src/sources/provider-router/search.ts +1 -0
- package/src/state/hooks/inline-tickers.ts +49 -11
- package/src/sync/core-contributors.ts +1 -0
- package/src/test-support/shell-pane-keys.tsx +1 -0
- package/src/theme/theme-context.tsx +15 -1
- package/src/tickers/company-name.ts +75 -0
- package/src/tickers/instrument-kind.ts +34 -1
- package/src/tickers/listing-name.ts +34 -0
- package/src/tickers/listing-venues.ts +132 -0
- package/src/tickers/open-target.ts +13 -4
- package/src/tickers/perpetual-listing.ts +151 -0
- package/src/tickers/prediction-listing.ts +26 -0
- package/src/tickers/search/index.ts +72 -11
- package/src/tickers/search/ranking.ts +98 -20
- package/src/tickers/search/types.ts +7 -1
- package/src/tickers/ticker-changes.ts +213 -0
- package/src/tickers/us-listing.ts +34 -0
- package/src/time-series/economic.ts +2 -6
- package/src/time-series/hooks.ts +9 -0
- package/src/time-series/ice-credit.ts +39 -0
- package/src/time-series/resolve.ts +211 -29
- package/src/time-series/studies.ts +1 -0
- package/src/time-series/types.ts +12 -2
- package/src/time-series/use-chart-resolution.ts +32 -0
- package/src/types/config.ts +10 -2
- package/src/types/data-provider.ts +11 -0
- package/src/types/financials.ts +62 -1
- package/src/types/headless.ts +113 -0
- package/src/types/instrument.ts +4 -0
- package/src/types/plugin.ts +52 -2
- package/src/types/price-history.ts +7 -0
- package/src/types/ticker-changes.ts +26 -0
- package/src/types/ticker.ts +14 -0
- package/src/ui/context-menu.tsx +13 -1
- package/src/ui/host.tsx +57 -3
- package/src/ui/live-resize.ts +91 -0
- package/src/ui/live-stretch.ts +153 -0
- package/src/ui/measured-cells.ts +58 -0
- package/src/ui/sticky-scroll.ts +7 -0
- package/src/utils/basis-points.ts +17 -0
- package/src/utils/central-banks.ts +76 -0
- package/src/utils/cli-output.ts +131 -15
- package/src/utils/concurrency.ts +25 -0
- package/src/utils/crypto-pair.ts +20 -0
- package/src/utils/currency-pair.ts +19 -0
- package/src/utils/currency-units.ts +11 -0
- package/src/utils/datetime-format.ts +27 -6
- package/src/utils/decimal-comma.ts +19 -0
- package/src/utils/dom-screenshot-css.ts +265 -0
- package/src/utils/dom-screenshot-rasters.ts +276 -0
- package/src/utils/dom-screenshot.ts +439 -52
- package/src/utils/double-escape-close.ts +15 -1
- package/src/utils/exchange-rate-snapshot.ts +6 -2
- package/src/utils/exchanges.ts +143 -1
- package/src/utils/format.ts +35 -5
- package/src/utils/forward-dividend.ts +14 -0
- package/src/utils/fundamentals.ts +66 -0
- package/src/utils/futures-generic.ts +6 -12
- package/src/utils/fx-market-hours.ts +15 -5
- package/src/utils/fx-status.ts +6 -1
- package/src/utils/inline-content-tokenizer.ts +22 -3
- 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/price-history.ts +99 -42
- package/src/utils/sec-eps-basis.ts +24 -11
- package/src/utils/sec.ts +61 -7
- package/src/utils/utc-time.ts +63 -4
- package/src/plugins/builtin/fx-matrix/freshness.ts +0 -65
- /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
- /package/src/{plugins/builtin/cloud → tickers}/starter-symbols.ts +0 -0
|
@@ -23,11 +23,13 @@ import {
|
|
|
23
23
|
} from "../../../components";
|
|
24
24
|
import { loadingErrorFooterInfo } from "../../../components/data-table/table-pane";
|
|
25
25
|
import { colors } from "../../../theme/colors";
|
|
26
|
+
import { t, tf } from "../../../i18n";
|
|
26
27
|
import type { PaneProps } from "../../../types/plugin";
|
|
27
28
|
import { Box, ScrollBox, Text, TextAttributes, useUiCapabilities, type ScrollBoxRenderable } from "../../../ui";
|
|
28
29
|
import { useDialog, type PromptContext } from "../../../ui/dialog";
|
|
29
30
|
import { isPlainKeyboardEvent } from "../../../utils/keyboard";
|
|
30
31
|
import { formatRelativeAge } from "../../../utils/datetime-format";
|
|
32
|
+
import { displayWidth } from "../../../utils/format";
|
|
31
33
|
import { requiredGloomberb } from "../../../utils/semver";
|
|
32
34
|
import { VERSION } from "../../../version";
|
|
33
35
|
import { getCurrentPluginTarget, runsExternalPlugins } from "../../current-target";
|
|
@@ -36,7 +38,7 @@ import { useAppSelector } from "../../../state/app/context";
|
|
|
36
38
|
import { BUILTIN_EDITORIAL } from "../../builtin-editorial";
|
|
37
39
|
import { usePluginAppActions, usePluginPaneState } from "../../runtime";
|
|
38
40
|
import { DEBUG_LOG_TEMPLATE_ID } from "../debug/template";
|
|
39
|
-
import { loadRegistry, registryPluginUrl } from "
|
|
41
|
+
import { loadRegistry, registryPluginUrl } from "../../marketplace/feed";
|
|
40
42
|
import { highlightedCodes, pluginFunctions, proFunctionCount, type PluginFunction } from "../../plugin-functions";
|
|
41
43
|
import {
|
|
42
44
|
matchingPack,
|
|
@@ -46,7 +48,7 @@ import {
|
|
|
46
48
|
STARTER_PACKS,
|
|
47
49
|
type PackChange,
|
|
48
50
|
type StarterPack,
|
|
49
|
-
} from "
|
|
51
|
+
} from "../../marketplace/packs";
|
|
50
52
|
import {
|
|
51
53
|
buildRows,
|
|
52
54
|
collectCategories,
|
|
@@ -67,11 +69,11 @@ import {
|
|
|
67
69
|
type MarketplaceRow,
|
|
68
70
|
type MarketplaceStatusKind,
|
|
69
71
|
type RegistryPlugin,
|
|
70
|
-
} from "
|
|
71
|
-
import { activateInstall, activateInstalledPlugin } from "
|
|
72
|
-
import { getMarketplaceHost, getPluginManager, type MarketplaceHost } from "
|
|
72
|
+
} from "../../marketplace/model";
|
|
73
|
+
import { activateInstall, activateInstalledPlugin } from "../../marketplace/activation";
|
|
74
|
+
import { getMarketplaceHost, getPluginManager, type MarketplaceHost } from "../../marketplace/store";
|
|
73
75
|
|
|
74
|
-
import { PLUGIN_MARKETPLACE_PANE_ID } from "
|
|
76
|
+
import { PLUGIN_MARKETPLACE_PANE_ID } from "../../marketplace/ids";
|
|
75
77
|
|
|
76
78
|
type Column = DataTableColumn & { id: "name" | "tagline" | "panes" | "functions" | "pro" | "status" };
|
|
77
79
|
|
|
@@ -158,12 +160,6 @@ function rowKey(row: MarketplaceRow): string {
|
|
|
158
160
|
|
|
159
161
|
const isEntryRow = (row: MarketplaceRow) => row.type === "entry";
|
|
160
162
|
|
|
161
|
-
function renderRowSectionHeader(row: MarketplaceRow) {
|
|
162
|
-
return row.type === "header"
|
|
163
|
-
? { text: `${SECTION_LABELS[row.section]} (${row.count})` }
|
|
164
|
-
: null;
|
|
165
|
-
}
|
|
166
|
-
|
|
167
163
|
function renderCell(
|
|
168
164
|
row: MarketplaceRow,
|
|
169
165
|
column: Column,
|
|
@@ -356,31 +352,38 @@ function BuiltinDetail({ entry, width, facts, scrollRef }: {
|
|
|
356
352
|
);
|
|
357
353
|
}
|
|
358
354
|
|
|
359
|
-
/**
|
|
360
|
-
|
|
361
|
-
|
|
362
|
-
|
|
363
|
-
|
|
364
|
-
"
|
|
365
|
-
|
|
366
|
-
|
|
367
|
-
|
|
368
|
-
|
|
369
|
-
|
|
355
|
+
/**
|
|
356
|
+
* What the research heading says the plugins on are: the pack they match, or
|
|
357
|
+
* a custom set once someone switched one by hand.
|
|
358
|
+
*/
|
|
359
|
+
function packStateLabel(pack: StarterPack | null): string {
|
|
360
|
+
return pack ? tf("{name} pack", { name: pack.name }) : t("Custom set");
|
|
361
|
+
}
|
|
362
|
+
|
|
363
|
+
/** What choosing a pack would switch from here, for its row in the chooser. */
|
|
364
|
+
function packChangeSummary(change: PackChange): string {
|
|
365
|
+
if (change.turnOff.length === 0 && change.turnOn.length === 0) return t("current");
|
|
366
|
+
return [
|
|
367
|
+
...(change.turnOn.length > 0 ? [tf("{count} on", { count: change.turnOn.length })] : []),
|
|
368
|
+
...(change.turnOff.length > 0 ? [tf("{count} off", { count: change.turnOff.length })] : []),
|
|
369
|
+
].join(", ");
|
|
370
|
+
}
|
|
370
371
|
|
|
371
|
-
/** One line per kind of change, with the plugins it names. */
|
|
372
|
-
function PackChangeBody({ change, name
|
|
372
|
+
/** One line per kind of change, with the plugins it names; as wide as the dialog it sits in. */
|
|
373
|
+
function PackChangeBody({ change, name }: { change: PackChange; name: (id: string) => string }) {
|
|
373
374
|
const lines = [
|
|
374
|
-
{ label: "Turn off", ids: change.turnOff },
|
|
375
|
-
{ label: "Turn on", ids: change.turnOn },
|
|
376
|
-
{ label: "Keep", ids: change.keep },
|
|
377
|
-
].filter((line) => line.ids.length > 0);
|
|
375
|
+
{ label: t("Turn off"), ids: change.turnOff },
|
|
376
|
+
{ label: t("Turn on"), ids: change.turnOn },
|
|
377
|
+
{ label: t("Keep"), ids: change.keep },
|
|
378
|
+
].filter((line) => line.ids.length > 0).map((line) => ({ ...line, heading: `${line.label} ${line.ids.length}` }));
|
|
379
|
+
// Wide enough for the longest heading in any language, plus a gap.
|
|
380
|
+
const headingWidth = Math.max(12, ...lines.map((line) => displayWidth(line.heading) + 2));
|
|
378
381
|
return (
|
|
379
|
-
<Box flexDirection="column" width=
|
|
382
|
+
<Box flexDirection="column" width="100%" gap={1}>
|
|
380
383
|
{lines.map((line) => (
|
|
381
|
-
<Box key={line.label} flexDirection="row" width=
|
|
382
|
-
<Box width={
|
|
383
|
-
<Text fg={colors.textBright} attributes={TextAttributes.BOLD}>{
|
|
384
|
+
<Box key={line.label} flexDirection="row" width="100%">
|
|
385
|
+
<Box width={headingWidth} flexShrink={0}>
|
|
386
|
+
<Text fg={colors.textBright} attributes={TextAttributes.BOLD}>{line.heading}</Text>
|
|
384
387
|
</Box>
|
|
385
388
|
<Box flexGrow={1} flexShrink={1} minWidth={0}>
|
|
386
389
|
<Text fg={colors.text} wrapText>{line.ids.map(name).join(", ")}</Text>
|
|
@@ -388,7 +391,7 @@ function PackChangeBody({ change, name, width }: { change: PackChange; name: (id
|
|
|
388
391
|
</Box>
|
|
389
392
|
))}
|
|
390
393
|
{change.turnOff.length > 0 ? (
|
|
391
|
-
<Text fg={colors.textDim} wrapText>Panes are hidden, not closed. Undo brings them back
|
|
394
|
+
<Text fg={colors.textDim} wrapText>{t("Panes are hidden, not closed. Undo brings them back.")}</Text>
|
|
392
395
|
) : null}
|
|
393
396
|
</Box>
|
|
394
397
|
);
|
|
@@ -678,13 +681,13 @@ export function PluginMarketplacePane({ focused, width, height }: PaneProps) {
|
|
|
678
681
|
const change = packChange(previous, pack);
|
|
679
682
|
const toggles = packToggles(change);
|
|
680
683
|
if (Object.keys(toggles).length === 0) {
|
|
681
|
-
notify({ body:
|
|
684
|
+
notify({ body: tf("{name} is already what you have on.", { name: pack.name }), type: "info" });
|
|
682
685
|
return;
|
|
683
686
|
}
|
|
684
687
|
const confirmed = await confirmDialog(dialog, {
|
|
685
|
-
title:
|
|
686
|
-
body: <PackChangeBody change={change} name={pluginName}
|
|
687
|
-
confirmLabel: "
|
|
688
|
+
title: tf("Apply {name}?", { name: pack.name }),
|
|
689
|
+
body: <PackChangeBody change={change} name={pluginName} />,
|
|
690
|
+
confirmLabel: "Apply",
|
|
688
691
|
confirmVariant: "primary",
|
|
689
692
|
width: confirmWidth,
|
|
690
693
|
});
|
|
@@ -692,16 +695,16 @@ export function PluginMarketplacePane({ focused, width, height }: PaneProps) {
|
|
|
692
695
|
host.setPluginsEnabled(toggles);
|
|
693
696
|
bump();
|
|
694
697
|
const parts = [
|
|
695
|
-
...(change.turnOff.length > 0 ? [
|
|
696
|
-
...(change.turnOn.length > 0 ? [
|
|
698
|
+
...(change.turnOff.length > 0 ? [tf("{count} off", { count: change.turnOff.length })] : []),
|
|
699
|
+
...(change.turnOn.length > 0 ? [tf("{count} back on", { count: change.turnOn.length })] : []),
|
|
697
700
|
];
|
|
698
701
|
notify({
|
|
699
|
-
body:
|
|
702
|
+
body: tf("{name} applied: {changes}.", { name: pack.name, changes: parts.join(", ") }),
|
|
700
703
|
type: "success",
|
|
701
704
|
// Long enough to reach for Undo after looking at the list.
|
|
702
705
|
duration: 12_000,
|
|
703
706
|
action: {
|
|
704
|
-
label: "Undo",
|
|
707
|
+
label: t("Undo"),
|
|
705
708
|
onClick: () => {
|
|
706
709
|
host.setPluginsEnabled(restoreToggles(previous));
|
|
707
710
|
bump();
|
|
@@ -710,21 +713,44 @@ export function PluginMarketplacePane({ focused, width, height }: PaneProps) {
|
|
|
710
713
|
});
|
|
711
714
|
}, [bump, confirmWidth, dialog, disabledPlugins, host, notify, pluginName]);
|
|
712
715
|
|
|
716
|
+
/**
|
|
717
|
+
* The packs as templates to apply: each with its tagline and what it would
|
|
718
|
+
* switch from the plugins on now. Picking one goes to the confirmation that
|
|
719
|
+
* names those plugins.
|
|
720
|
+
*/
|
|
713
721
|
const choosePack = useCallback(async () => {
|
|
722
|
+
if (!host) return;
|
|
714
723
|
const id = await dialog.prompt<string>({
|
|
715
724
|
closeOnClickOutside: true,
|
|
716
725
|
content: (context: PromptContext<string>) => (
|
|
717
726
|
<ChoiceDialog
|
|
718
727
|
{...context}
|
|
719
|
-
title="
|
|
728
|
+
title="Apply a starter pack"
|
|
720
729
|
selectedChoiceId={currentPack?.id}
|
|
721
|
-
choices={STARTER_PACKS.map((pack) => ({
|
|
730
|
+
choices={STARTER_PACKS.map((pack) => ({
|
|
731
|
+
id: pack.id,
|
|
732
|
+
label: pack.name,
|
|
733
|
+
description: pack.tagline,
|
|
734
|
+
detail: packChangeSummary(packChange(disabledPlugins, pack)),
|
|
735
|
+
}))}
|
|
722
736
|
/>
|
|
723
737
|
),
|
|
724
738
|
}).catch(() => null);
|
|
725
739
|
const pack = STARTER_PACKS.find((candidate) => candidate.id === id);
|
|
726
740
|
if (pack) await applyPack(pack);
|
|
727
|
-
}, [applyPack, currentPack, dialog]);
|
|
741
|
+
}, [applyPack, currentPack, dialog, disabledPlugins, host]);
|
|
742
|
+
|
|
743
|
+
// The pack reaches exactly the research section, so its heading says which
|
|
744
|
+
// one the plugins on match and applies another.
|
|
745
|
+
const renderSectionHeader = useCallback((row: MarketplaceRow) => {
|
|
746
|
+
if (row.type !== "header") return null;
|
|
747
|
+
const text = `${SECTION_LABELS[row.section]} (${row.count})`;
|
|
748
|
+
if (row.section !== "research" || !host) return { text };
|
|
749
|
+
return {
|
|
750
|
+
text,
|
|
751
|
+
action: { label: packStateLabel(currentPack), title: t("Apply a starter pack"), onPress: () => { void choosePack(); } },
|
|
752
|
+
};
|
|
753
|
+
}, [choosePack, currentPack, host]);
|
|
728
754
|
|
|
729
755
|
const setupSelected = useCallback(() => {
|
|
730
756
|
if (!selected || !selected.installed || !selected.hasSetup || !selected.enabled) return;
|
|
@@ -826,7 +852,7 @@ export function PluginMarketplacePane({ focused, width, height }: PaneProps) {
|
|
|
826
852
|
if (canOpen) hints.push({ id: "open-pane", key: "p", label: "ane", onPress: openSelected });
|
|
827
853
|
if (canLog) hints.push({ id: "log", key: "d", label: "ebug log", onPress: openLog });
|
|
828
854
|
if (canRemove) hints.push({ id: "remove", key: "x", label: " remove", onPress: () => { void removeSelected(); } });
|
|
829
|
-
if (host) hints.push({ id: "packs", key: "a", label: "
|
|
855
|
+
if (host) hints.push({ id: "packs", key: "a", label: "pply pack", title: "Apply a starter pack", onPress: () => { void choosePack(); } });
|
|
830
856
|
// A built-in has no repository; its page on gloom.sh shows it at work.
|
|
831
857
|
const seeItUrl = selected?.bundled ? registryPluginUrl(selected.id) : null;
|
|
832
858
|
if (seeItUrl) hints.push({ id: "see-it", key: "o", label: " see it", title: "See it on gloom.sh", onPress: () => openUrl(seeItUrl) });
|
|
@@ -845,10 +871,6 @@ export function PluginMarketplacePane({ focused, width, height }: PaneProps) {
|
|
|
845
871
|
status: Math.min(14, Math.max(7, ...visible.map((entry) => statusOf(entry).text.length))),
|
|
846
872
|
}), [factsFor, visible]);
|
|
847
873
|
const columns = useMemo(() => buildColumns(width, fit), [fit, width]);
|
|
848
|
-
const packOptions = useMemo(() => [
|
|
849
|
-
...STARTER_PACKS.map((pack) => ({ value: pack.id, label: pack.name, short: PACK_SHORT_LABELS[pack.id], description: pack.tagline })),
|
|
850
|
-
...(currentPack ? [] : [{ value: CUSTOM_PACK, label: "Custom", description: "Your own set of plugins.", disabled: true }]),
|
|
851
|
-
], [currentPack]);
|
|
852
874
|
// The pick is saved with the pane, so keep it listed (and resettable) even
|
|
853
875
|
// when the catalog no longer has plugins in it.
|
|
854
876
|
const categoryOptions = useMemo(
|
|
@@ -899,21 +921,6 @@ export function PluginMarketplacePane({ focused, width, height }: PaneProps) {
|
|
|
899
921
|
: null}
|
|
900
922
|
detailTitle={selected?.name}
|
|
901
923
|
rootBefore={(
|
|
902
|
-
<Box flexDirection="column" flexShrink={0}>
|
|
903
|
-
<QueryBar
|
|
904
|
-
width={width}
|
|
905
|
-
filters={[{
|
|
906
|
-
id: "pack",
|
|
907
|
-
label: "Starter pack",
|
|
908
|
-
inline: true,
|
|
909
|
-
value: currentPack?.id ?? CUSTOM_PACK,
|
|
910
|
-
options: packOptions,
|
|
911
|
-
onChange: (value: string) => {
|
|
912
|
-
const pack = STARTER_PACKS.find((candidate) => candidate.id === value);
|
|
913
|
-
if (pack) void applyPack(pack);
|
|
914
|
-
},
|
|
915
|
-
}]}
|
|
916
|
-
/>
|
|
917
924
|
<QueryBar
|
|
918
925
|
width={width}
|
|
919
926
|
search={{
|
|
@@ -935,7 +942,6 @@ export function PluginMarketplacePane({ focused, width, height }: PaneProps) {
|
|
|
935
942
|
{ kind: "toggle" as const, id: "builtin", label: "Built in", value: showBuiltin, defaultValue: true, onChange: setShowBuiltin },
|
|
936
943
|
]}
|
|
937
944
|
/>
|
|
938
|
-
</Box>
|
|
939
945
|
)}
|
|
940
946
|
selection={{
|
|
941
947
|
kind: "id",
|
|
@@ -958,7 +964,7 @@ export function PluginMarketplacePane({ focused, width, height }: PaneProps) {
|
|
|
958
964
|
getItemKey={rowKey}
|
|
959
965
|
sortColumnId={null}
|
|
960
966
|
sortDirection="asc"
|
|
961
|
-
renderSectionHeader={
|
|
967
|
+
renderSectionHeader={renderSectionHeader}
|
|
962
968
|
renderCell={renderRow}
|
|
963
969
|
emptyContent={<Box width="100%" paddingX={1} paddingY={1}>{emptyState}</Box>}
|
|
964
970
|
emptyStateTitle={status === "error" ? "Plugin catalog unavailable." : query || category ? "No plugins match." : "Nothing installed yet."}
|
|
@@ -46,6 +46,7 @@ const HANDLED_MODULE_KEYS = [
|
|
|
46
46
|
"panes",
|
|
47
47
|
"paneTemplates",
|
|
48
48
|
"capabilities",
|
|
49
|
+
"series",
|
|
49
50
|
"slots",
|
|
50
51
|
] as const satisfies readonly (keyof PluginModule)[];
|
|
51
52
|
|
|
@@ -140,6 +141,7 @@ export function composeBuiltinPlugin(options: CompositePluginOptions): GloomPlug
|
|
|
140
141
|
const panes = modules.flatMap((module) => module.panes ?? []);
|
|
141
142
|
const paneTemplates = modules.flatMap((module) => module.paneTemplates ?? []);
|
|
142
143
|
const capabilities = modules.flatMap((module) => module.capabilities ?? []);
|
|
144
|
+
const series = modules.flatMap((module) => module.series ?? []);
|
|
143
145
|
const slots = composeSlots(modules);
|
|
144
146
|
let startedModules: PluginModule[] = [];
|
|
145
147
|
|
|
@@ -149,6 +151,7 @@ export function composeBuiltinPlugin(options: CompositePluginOptions): GloomPlug
|
|
|
149
151
|
...(panes.length > 0 ? { panes } : {}),
|
|
150
152
|
...(paneTemplates.length > 0 ? { paneTemplates } : {}),
|
|
151
153
|
...(capabilities.length > 0 ? { capabilities } : {}),
|
|
154
|
+
...(series.length > 0 ? { series } : {}),
|
|
152
155
|
...(slots ? { slots } : {}),
|
|
153
156
|
|
|
154
157
|
async setup(ctx: GloomPluginContext) {
|
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
import type { BrokerAccount } from "../../../types/trading";
|
|
2
2
|
import { isTimestampStaleForExchangeSession } from "../../../market-data/market/freshness";
|
|
3
3
|
import type { PortfolioSummaryTotals } from "./metrics";
|
|
4
|
-
import { portfolioPnlPercent } from "
|
|
4
|
+
import { portfolioPnlPercent } from "../../../portfolio/position-metrics";
|
|
5
5
|
import { isFiniteNumber } from "../../../utils/guards";
|
|
6
6
|
|
|
7
7
|
export interface PortfolioAccountMetrics {
|
|
@@ -211,9 +211,10 @@ export function formatAllocationDrift(value: number | null | undefined): string
|
|
|
211
211
|
}
|
|
212
212
|
|
|
213
213
|
/**
|
|
214
|
-
* Units to trade, signed
|
|
215
|
-
* rounded to the nearest; fractional
|
|
216
|
-
*
|
|
214
|
+
* Units to trade, signed, at display precision: a holding kept in whole units
|
|
215
|
+
* trades in whole units, rounded to the nearest; a fractional holding to at
|
|
216
|
+
* most two decimals and a coin to at most four, trailing zeros dropped. JSON,
|
|
217
|
+
* CSV and the pane's cell value keep the full-precision figure.
|
|
217
218
|
*/
|
|
218
219
|
export function formatTradeUnits(
|
|
219
220
|
value: number | null | undefined,
|
|
@@ -222,7 +223,7 @@ export function formatTradeUnits(
|
|
|
222
223
|
if (!finite(value)) return "—";
|
|
223
224
|
const kind = resolveAssetDisplayKind({ assetCategory });
|
|
224
225
|
const whole = kind !== "crypto" && kind !== "cash" && Number.isInteger(units);
|
|
225
|
-
const decimals = whole ? 0 : kind === "crypto" ?
|
|
226
|
+
const decimals = whole ? 0 : kind === "crypto" ? 4 : 2;
|
|
226
227
|
const rounded = Number(value.toFixed(decimals));
|
|
227
228
|
if (rounded === 0) return "0";
|
|
228
229
|
const body = new Intl.NumberFormat("en-US", { maximumFractionDigits: decimals }).format(Math.abs(rounded));
|
|
@@ -20,8 +20,13 @@ const FX_COLUMN_IDS = new Set([
|
|
|
20
20
|
]);
|
|
21
21
|
/** Columns that divide by the portfolio's total. */
|
|
22
22
|
const ALLOCATION_COLUMN_IDS = new Set(["weight", "drift", "trade", "trade_value"]);
|
|
23
|
+
/** Columns read at the price the pane values at: the latest print or the regular close. */
|
|
24
|
+
const VALUATION_COLUMN_IDS = new Set([
|
|
25
|
+
"mkt_value", "weight", "drift", "trade", "trade_value", "day_pnl", "pnl", "pnl_pct", "as_of",
|
|
26
|
+
]);
|
|
23
27
|
const SUPPLEMENTAL_COLUMN_IDS = new Set(["target", "target_pct", "rating", "ex_div", "next_earn"]);
|
|
24
|
-
const DAY_CLOCK_COLUMN_IDS = new Set(["held", "ex_div", "next_earn"]);
|
|
28
|
+
const DAY_CLOCK_COLUMN_IDS = new Set(["held", "ex_div", "next_earn", "as_of"]);
|
|
29
|
+
export const PERPETUAL_COLUMN_IDS: ReadonlySet<string> = new Set(["perp_premium", "perp_funding"]);
|
|
25
30
|
|
|
26
31
|
const exchangeRateVersions = new WeakMap<ReadonlyMap<string, number>, string>();
|
|
27
32
|
|
|
@@ -53,8 +58,10 @@ export function columnContextVersion(columnId: string, ctx: ColumnContext): stri
|
|
|
53
58
|
let version = `${ctx.activeTab ?? ""}|${ctx.baseCurrency}`;
|
|
54
59
|
if (FX_COLUMN_IDS.has(columnId)) version += `|${exchangeRatesVersion(ctx.exchangeRates)}`;
|
|
55
60
|
if (ALLOCATION_COLUMN_IDS.has(columnId)) version += `|${ctx.portfolioTotalMarketValue ?? 0}`;
|
|
61
|
+
if (VALUATION_COLUMN_IDS.has(columnId)) version += `|${ctx.valuationBasis ?? "latest-print"}`;
|
|
56
62
|
if (ALLOCATION_COLUMN_IDS.has(columnId) || columnId === "target_weight") version += `|${targetsVersion(ctx.portfolioTargets)}`;
|
|
57
63
|
if (SUPPLEMENTAL_COLUMN_IDS.has(columnId)) version += `|${ctx.supplementalVersion ?? 0}`;
|
|
64
|
+
if (PERPETUAL_COLUMN_IDS.has(columnId)) version += `|${ctx.perpetualsVersion ?? 0}`;
|
|
58
65
|
if (columnId === "latency") version += `|${ctx.now}`;
|
|
59
66
|
if (DAY_CLOCK_COLUMN_IDS.has(columnId)) version += `|${Math.floor(ctx.now / DAY_MS)}`;
|
|
60
67
|
return version;
|
|
@@ -0,0 +1,161 @@
|
|
|
1
|
+
import type { CliCommandContext } from "../../../../types/plugin";
|
|
2
|
+
import type { TickerRecord } from "../../../../types/ticker";
|
|
3
|
+
import { loadSavedListing, parseListingArg } from "../../../../cli/listing-arg";
|
|
4
|
+
import { StagedTickerRepository } from "../../../../cli/staged-tickers";
|
|
5
|
+
import { splitSymbolArgs, symbolInputKey } from "../../../../cli/symbol-args";
|
|
6
|
+
import { readSymbolList, SymbolListError } from "../../../../cli/symbol-list";
|
|
7
|
+
import { cliStyles } from "../../../../utils/cli-output";
|
|
8
|
+
import {
|
|
9
|
+
addSymbols,
|
|
10
|
+
failedRow,
|
|
11
|
+
listingRow,
|
|
12
|
+
NO_MATCH,
|
|
13
|
+
reason,
|
|
14
|
+
settled,
|
|
15
|
+
summarizeSymbolRows,
|
|
16
|
+
type BulkSymbolsOptions,
|
|
17
|
+
type SymbolRow,
|
|
18
|
+
type SymbolStatus,
|
|
19
|
+
type Verb,
|
|
20
|
+
} from "../../../../cli/symbol-rows";
|
|
21
|
+
|
|
22
|
+
export { addSymbols };
|
|
23
|
+
|
|
24
|
+
/** The `--file` option of add and remove. */
|
|
25
|
+
export const FILE_OPTION = {
|
|
26
|
+
flags: "--file <path>",
|
|
27
|
+
description: "add, remove: read the symbols from a CSV or text file (- reads standard input)",
|
|
28
|
+
};
|
|
29
|
+
|
|
30
|
+
/** The help section on giving add and remove several symbols. */
|
|
31
|
+
export const SYMBOL_LIST_HELP = {
|
|
32
|
+
title: "Several symbols",
|
|
33
|
+
lines: [
|
|
34
|
+
"add and remove take any number of symbols split by spaces, commas or newlines, a --file, or piped input (or -). A CSV is read from its Symbol, Ticker or Code column, else its first. Quote a list name with spaces.",
|
|
35
|
+
"Each symbol gets a line, then a summary. Exit status 0 when at least one symbol was added (or removed) or already was, 1 when none resolved or the usage is wrong.",
|
|
36
|
+
],
|
|
37
|
+
};
|
|
38
|
+
|
|
39
|
+
/** A row's line, and under it the coin hint when a bare coin ticker was read as something else. */
|
|
40
|
+
function rowLines(row: SymbolRow, verb: Verb): string {
|
|
41
|
+
const line = rowLine(row, verb);
|
|
42
|
+
return row.hint ? `${line}\n ${cliStyles.warning(row.hint)}` : line;
|
|
43
|
+
}
|
|
44
|
+
|
|
45
|
+
function rowLine(row: SymbolRow, verb: Verb): string {
|
|
46
|
+
const typed = symbolInputKey(row.input);
|
|
47
|
+
const label = row.listing ? (row.name ? `${row.listing} (${row.name})` : row.listing) : typed;
|
|
48
|
+
// A listing that stopped trading is still added, and says so.
|
|
49
|
+
const aside = row.message && row.listing ? cliStyles.muted(` (${reason(row.message, label)})`) : "";
|
|
50
|
+
switch (row.status) {
|
|
51
|
+
case "added": return `${cliStyles.success(`Added ${label}`)}${aside}`;
|
|
52
|
+
case "already_listed": return `${cliStyles.warning(`Already in the list: ${label}`)}${aside}`;
|
|
53
|
+
case "removed": return cliStyles.success(`Removed ${label}`);
|
|
54
|
+
case "not_listed": return cliStyles.warning(`Not in the list: ${label}`);
|
|
55
|
+
case "not_found": return cliStyles.danger(`Not found: ${typed}${row.message && !NO_MATCH.test(row.message) ? ` (${reason(row.message, typed)})` : ""}`);
|
|
56
|
+
case "failed": return cliStyles.danger(`Not ${verb === "add" ? "added" : "removed"}: ${typed} (${reason(row.message ?? "", typed)})`);
|
|
57
|
+
}
|
|
58
|
+
}
|
|
59
|
+
|
|
60
|
+
interface CollectionRef {
|
|
61
|
+
kind: "watchlist" | "portfolio";
|
|
62
|
+
name: string;
|
|
63
|
+
}
|
|
64
|
+
|
|
65
|
+
/**
|
|
66
|
+
* One line per symbol and the summary under them; `--json` and `--csv` give
|
|
67
|
+
* the rows, with the summary in the JSON metadata and on standard error beside
|
|
68
|
+
* CSV. The command exits non-zero when no symbol ended up as asked.
|
|
69
|
+
*/
|
|
70
|
+
export function printSymbolRows(
|
|
71
|
+
ctx: CliCommandContext,
|
|
72
|
+
rows: SymbolRow[],
|
|
73
|
+
{ verb, collection, repeated }: { verb: Verb; collection: CollectionRef; repeated: number },
|
|
74
|
+
): void {
|
|
75
|
+
const summary = `${collection.kind === "watchlist" ? "Watchlist" : "Portfolio"} "${collection.name}": ${summarizeSymbolRows(rows, verb, repeated)}`;
|
|
76
|
+
const count = (status: SymbolStatus) => rows.filter((row) => row.status === status).length;
|
|
77
|
+
const counts = verb === "add"
|
|
78
|
+
? { added: count("added"), alreadyListed: count("already_listed"), notFound: count("not_found"), notAdded: count("failed") }
|
|
79
|
+
: { removed: count("removed"), notListed: count("not_listed"), notFound: count("not_found"), notRemoved: count("failed") };
|
|
80
|
+
ctx.printResult({
|
|
81
|
+
data: rows,
|
|
82
|
+
metadata: { [collection.kind]: collection.name, ...counts, repeated, summary },
|
|
83
|
+
}, {
|
|
84
|
+
text: () => [...rows.map((row) => rowLines(row, verb)), "", summary].join("\n"),
|
|
85
|
+
});
|
|
86
|
+
const { format, quiet } = ctx.cliOptions;
|
|
87
|
+
if ((format === "csv" || format === "ndjson") && !quiet) console.error(summary);
|
|
88
|
+
if (!rows.some((row) => settled(row, verb))) process.exitCode = 1;
|
|
89
|
+
}
|
|
90
|
+
|
|
91
|
+
/** A line on standard error while a long add waits to look symbols up again, so it never looks stuck. */
|
|
92
|
+
export function retryNotice(ctx: CliCommandContext): (count: number, waitMs: number) => void {
|
|
93
|
+
return (count, waitMs) => {
|
|
94
|
+
if (ctx.cliOptions.quiet) return;
|
|
95
|
+
console.error(cliStyles.muted(`Gloom Cloud refused some requests; looking ${count} symbol${count === 1 ? "" : "s"} up again in ${Math.round(waitMs / 1000)} s.`));
|
|
96
|
+
};
|
|
97
|
+
}
|
|
98
|
+
|
|
99
|
+
/** The symbols an add or remove was given, failing the command when there are none or the file cannot be read. */
|
|
100
|
+
export async function requireSymbolList(
|
|
101
|
+
ctx: CliCommandContext,
|
|
102
|
+
args: readonly string[],
|
|
103
|
+
file: string | undefined,
|
|
104
|
+
usage: string,
|
|
105
|
+
): Promise<{ symbols: string[]; repeated: number; single: string | null }> {
|
|
106
|
+
try {
|
|
107
|
+
const list = await readSymbolList({ args, file });
|
|
108
|
+
if (list.symbols.length === 0) ctx.fail(usage);
|
|
109
|
+
// One symbol typed alone keeps the single-symbol output and errors.
|
|
110
|
+
const typed = splitSymbolArgs(args);
|
|
111
|
+
const single = file == null && !args.includes("-") && typed.length === 1 ? typed[0]! : null;
|
|
112
|
+
return { ...list, single };
|
|
113
|
+
} catch (error) {
|
|
114
|
+
if (error instanceof SymbolListError) ctx.fail(error.message, usage);
|
|
115
|
+
throw error;
|
|
116
|
+
}
|
|
117
|
+
}
|
|
118
|
+
|
|
119
|
+
/**
|
|
120
|
+
* Removes each symbol's saved listing from a collection. A symbol names its
|
|
121
|
+
* listing as the single-symbol remove reads it (SAN:EPA, or `--exchange` for
|
|
122
|
+
* those without one); one that is not saved is not found. Every change is
|
|
123
|
+
* written once, at the end.
|
|
124
|
+
*/
|
|
125
|
+
export async function removeSymbols({
|
|
126
|
+
symbols,
|
|
127
|
+
exchange,
|
|
128
|
+
store,
|
|
129
|
+
reject,
|
|
130
|
+
remove,
|
|
131
|
+
}: BulkSymbolsOptions & {
|
|
132
|
+
reject?: (input: string) => Error | null;
|
|
133
|
+
remove: (ticker: TickerRecord) => { changed: boolean; ticker: TickerRecord; extra?: Record<string, unknown> };
|
|
134
|
+
}): Promise<SymbolRow[]> {
|
|
135
|
+
const staged = new StagedTickerRepository(store);
|
|
136
|
+
const rows: SymbolRow[] = [];
|
|
137
|
+
for (const input of symbols) {
|
|
138
|
+
const refusal = reject?.(input);
|
|
139
|
+
if (refusal) {
|
|
140
|
+
rows.push(failedRow(input, refusal));
|
|
141
|
+
continue;
|
|
142
|
+
}
|
|
143
|
+
let listing;
|
|
144
|
+
try {
|
|
145
|
+
listing = parseListingArg(input, exchange, { ownExchangeWins: true });
|
|
146
|
+
} catch (error) {
|
|
147
|
+
rows.push(failedRow(input, error instanceof Error ? error : new Error(String(error))));
|
|
148
|
+
continue;
|
|
149
|
+
}
|
|
150
|
+
const ticker = listing.symbol ? await loadSavedListing(staged, listing) : null;
|
|
151
|
+
if (!ticker) {
|
|
152
|
+
rows.push(failedRow(input, new Error(`Ticker "${listing.key}" was not found in your local data.`), "not_found"));
|
|
153
|
+
continue;
|
|
154
|
+
}
|
|
155
|
+
const result = remove(ticker);
|
|
156
|
+
if (result.changed) await staged.saveTicker(result.ticker);
|
|
157
|
+
rows.push(listingRow(input, result.changed ? "removed" : "not_listed", result.ticker, { extra: result.extra }));
|
|
158
|
+
}
|
|
159
|
+
await staged.commit();
|
|
160
|
+
return rows;
|
|
161
|
+
}
|
|
@@ -0,0 +1,109 @@
|
|
|
1
|
+
import type { HeadlessPaneRow } from "../../../../types/plugin";
|
|
2
|
+
import type { PortfolioImportSource } from "../../../../types/ticker";
|
|
3
|
+
|
|
4
|
+
/**
|
|
5
|
+
* A 13F line ranked by reported value, with why it cannot be a portfolio
|
|
6
|
+
* position when it cannot. Read from the rows `fn 13F <manager>` reports, so
|
|
7
|
+
* the import goes through the 13F function rather than the 13F plugin's code.
|
|
8
|
+
*/
|
|
9
|
+
export interface ThirteenFImportLine {
|
|
10
|
+
ticker: string;
|
|
11
|
+
issuer: string;
|
|
12
|
+
cusip: string;
|
|
13
|
+
/** Reported value, USD. */
|
|
14
|
+
value: number;
|
|
15
|
+
shares: number;
|
|
16
|
+
/** Null for a line that can be imported. */
|
|
17
|
+
skip: string | null;
|
|
18
|
+
}
|
|
19
|
+
|
|
20
|
+
export interface ThirteenFImportPosition {
|
|
21
|
+
ticker: string;
|
|
22
|
+
issuer: string;
|
|
23
|
+
/** Share of the imported lines' reported value. */
|
|
24
|
+
weight: number;
|
|
25
|
+
/** Share of the whole filing's reported value. */
|
|
26
|
+
filingWeight: number | null;
|
|
27
|
+
/** Reported shares scaled to the notional. */
|
|
28
|
+
shares: number;
|
|
29
|
+
/** Reported value per share: the quarter-end price the filing implies. */
|
|
30
|
+
avgCost: number;
|
|
31
|
+
}
|
|
32
|
+
|
|
33
|
+
const text = (value: unknown) => (typeof value === "string" ? value : "");
|
|
34
|
+
|
|
35
|
+
/** Title-of-class words for lines that are shares but not common stock ("6.375 PREF SER A", "*W EXP 06/30/202"). */
|
|
36
|
+
const NOT_COMMON: Array<[RegExp, string]> = [
|
|
37
|
+
[/\b(?:PFD|PREF|PREFERRED)\b/i, "preferred stock"],
|
|
38
|
+
[/\*W\b|\b(?:WTS?|WARRANTS?)\b/i, "warrant"],
|
|
39
|
+
[/\b(?:RTS?|RIGHTS?)\b/i, "right"],
|
|
40
|
+
[/\b(?:NOTES?|DBCV|DEBT|BONDS?)\b/i, "debt"],
|
|
41
|
+
];
|
|
42
|
+
const amount = (value: unknown) => (typeof value === "number" && Number.isFinite(value) ? value : null);
|
|
43
|
+
|
|
44
|
+
/**
|
|
45
|
+
* The manager's current 13F lines, largest reported value first. Common-stock
|
|
46
|
+
* lines with a ticker can become positions; options, principal amounts,
|
|
47
|
+
* preferred stock, warrants, rights and debt, and lines whose CUSIP has no
|
|
48
|
+
* ticker carry the reason they cannot. Two CUSIPs that map to one ticker are
|
|
49
|
+
* one line.
|
|
50
|
+
*/
|
|
51
|
+
export function rankThirteenFLines(rows: readonly HeadlessPaneRow[]): ThirteenFImportLine[] {
|
|
52
|
+
const lines = new Map<string, ThirteenFImportLine>();
|
|
53
|
+
for (const [index, row] of rows.entries()) {
|
|
54
|
+
const value = amount(row.value);
|
|
55
|
+
if (row.action === "exit" || value == null || value <= 0) continue;
|
|
56
|
+
const ticker = text(row.ticker);
|
|
57
|
+
const shares = amount(row.shares);
|
|
58
|
+
const putCall = text(row.putCall);
|
|
59
|
+
const notCommon = NOT_COMMON.find(([pattern]) => pattern.test(text(row.titleOfClass)))?.[1];
|
|
60
|
+
const skip = putCall ? `${putCall.toLowerCase()} option, not shares`
|
|
61
|
+
: text(row.shareType).toUpperCase() === "PRN" ? "principal amount, not shares"
|
|
62
|
+
: notCommon ? `${notCommon}, not common stock`
|
|
63
|
+
: !ticker ? `CUSIP ${text(row.cusip) || "unknown"} has no ticker`
|
|
64
|
+
: shares == null || shares <= 0 ? "no share count reported"
|
|
65
|
+
: null;
|
|
66
|
+
const key = skip ? `${index}|skip` : ticker.toUpperCase();
|
|
67
|
+
const line = lines.get(key);
|
|
68
|
+
if (line) {
|
|
69
|
+
line.value += value;
|
|
70
|
+
line.shares += shares ?? 0;
|
|
71
|
+
} else {
|
|
72
|
+
lines.set(key, { ticker, issuer: text(row.issuer), cusip: text(row.cusip), value, shares: shares ?? 0, skip });
|
|
73
|
+
}
|
|
74
|
+
}
|
|
75
|
+
return [...lines.values()].sort((left, right) => right.value - left.value);
|
|
76
|
+
}
|
|
77
|
+
|
|
78
|
+
/** Round to four decimals: a notional share count need not be whole, but it need not show float noise either. */
|
|
79
|
+
const roundShares = (value: number) => Math.round(value * 10_000) / 10_000;
|
|
80
|
+
|
|
81
|
+
/**
|
|
82
|
+
* Positions worth `notional` in total, weighted by reported value: each line's
|
|
83
|
+
* reported shares scaled by notional over the lines' total value, at the
|
|
84
|
+
* quarter-end price the filing implies.
|
|
85
|
+
*/
|
|
86
|
+
export function notionalPositions(
|
|
87
|
+
lines: readonly Pick<ThirteenFImportLine, "ticker" | "issuer" | "value" | "shares">[],
|
|
88
|
+
notional: number,
|
|
89
|
+
filingValue: number | null,
|
|
90
|
+
): ThirteenFImportPosition[] {
|
|
91
|
+
const total = lines.reduce((sum, line) => sum + line.value, 0);
|
|
92
|
+
if (!(total > 0) || !(notional > 0)) return [];
|
|
93
|
+
return lines.map((line) => ({
|
|
94
|
+
ticker: line.ticker,
|
|
95
|
+
issuer: line.issuer,
|
|
96
|
+
weight: line.value / total,
|
|
97
|
+
filingWeight: filingValue && filingValue > 0 ? line.value / filingValue : null,
|
|
98
|
+
shares: roundShares(line.shares * notional / total),
|
|
99
|
+
avgCost: line.value / line.shares,
|
|
100
|
+
}));
|
|
101
|
+
}
|
|
102
|
+
|
|
103
|
+
/** The filing a 13F holdings report covers, from its metadata, or null when it names no dated filing. */
|
|
104
|
+
export function importSource(metadata: Record<string, unknown> | undefined): PortfolioImportSource | null {
|
|
105
|
+
const cik = text(metadata?.cik), name = text(metadata?.fund);
|
|
106
|
+
const period = text(metadata?.latestPeriod), filed = text(metadata?.latestFiled);
|
|
107
|
+
if (!cik || !period || !filed) return null;
|
|
108
|
+
return { kind: "13f", cik, name: name || cik, period, filed };
|
|
109
|
+
}
|