gloomberb 0.18.2 → 0.18.4
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +8 -8
- package/README.zh-CN.md +11 -11
- package/bin/{gloomberb → gloom} +3 -1
- package/package.json +6 -2
- package/patches/electrobun@1.18.1.patch +106 -5
- package/src/account/checkout-handoff.tsx +225 -0
- package/src/account/device-signin-dialog.tsx +2 -2
- package/src/account/device-signin.ts +2 -2
- package/src/account/upgrade-dialog.tsx +1 -1
- package/src/api-client/askg.ts +2 -2
- package/src/api-client/auth.ts +2 -2
- package/src/api-client/central-bank-rates.ts +6 -0
- package/src/api-client/collections.ts +5 -1
- package/src/api-client/cot.ts +2 -0
- package/src/api-client/crypto-etf-flows.ts +37 -0
- package/src/api-client/crypto-markets.ts +60 -0
- package/src/api-client/data.ts +99 -5
- package/src/api-client/doe.ts +15 -0
- package/src/api-client/equity-screener.ts +28 -0
- package/src/api-client/exchange-announcements.ts +38 -0
- package/src/api-client/fund-facts.ts +39 -0
- package/src/api-client/futures-curve.ts +9 -1
- package/src/api-client/hiring.ts +301 -0
- package/src/api-client/index.ts +24 -5
- package/src/api-client/market-discovery.ts +14 -0
- package/src/api-client/members.ts +6 -0
- package/src/api-client/mna.ts +6 -0
- package/src/api-client/paths.ts +18 -1
- package/src/api-client/request.ts +26 -7
- package/src/api-client/short-side-publications.ts +37 -0
- package/src/api-client/socket.ts +64 -4
- package/src/api-client/swap-curve.ts +35 -0
- package/src/api-client/telemetry.ts +17 -0
- package/src/api-client/themes.ts +7 -1
- package/src/api-client/types.ts +90 -2
- package/src/app/global-shortcuts.ts +1 -16
- package/src/app/pane-runtime/plugin-bindings.ts +9 -2
- package/src/app/runtime/desktop-deeplink.ts +5 -5
- package/src/app/runtime/plugin-bindings.ts +2 -2
- package/src/app/runtime/startup.ts +13 -0
- package/src/app/runtime/update.ts +28 -8
- package/src/app/star-prompt/status-line.tsx +2 -2
- package/src/architecture/core-builtin-allowlist.json +5 -2
- package/src/architecture/pane-tabs-allowlist.json +65 -0
- package/src/architecture/ui-literals-allowlist.json +3 -3
- package/src/architecture/ui-tokens-allowlist.json +1 -1
- package/src/brokers/broker-portfolio-sync.ts +37 -0
- package/src/brokers/directory.ts +11 -0
- package/src/brokers/logos.ts +3 -1
- package/src/brokers/signed-in/adapter.ts +304 -26
- package/src/brokers/signed-in/client.ts +14 -2
- package/src/brokers/signed-in/connect.ts +10 -2
- package/src/brokers/sync-broker-instance.ts +9 -1
- package/src/capabilities/chart-series.ts +22 -6
- package/src/cli/bank-section.ts +1 -1
- package/src/cli/base-converter.ts +23 -14
- package/src/cli/central-bank-events.ts +1 -1
- package/src/cli/command-options.ts +59 -4
- package/src/cli/commands/api.ts +9 -6
- package/src/cli/commands/broker.ts +2 -2
- package/src/cli/commands/command-utils.ts +2 -2
- package/src/cli/commands/crypto-hints.ts +7 -20
- package/src/cli/commands/fred-series.ts +4 -2
- package/src/cli/commands/keybindings.ts +2 -2
- package/src/cli/commands/market.ts +1189 -296
- package/src/cli/commands/news-hints.ts +2 -2
- package/src/cli/commands/news-search.ts +59 -6
- package/src/cli/commands/options-leaps.ts +41 -26
- package/src/cli/commands/overview.ts +121 -48
- package/src/cli/commands/plugins.ts +9 -9
- package/src/cli/commands/remote.ts +13 -10
- package/src/cli/commands/search.ts +64 -44
- package/src/cli/commands/system.ts +27 -19
- package/src/cli/commands/themes.ts +1 -1
- package/src/cli/commands/ticker.ts +272 -70
- package/src/cli/context.ts +3 -2
- package/src/cli/desktop-pane-shot-view.ts +2 -2
- package/src/cli/desktop-pane-shot.ts +1 -1
- package/src/cli/earnings-calendar.ts +4 -4
- package/src/cli/entry.ts +18 -1
- package/src/cli/errors.ts +20 -2
- package/src/cli/exit-codes.ts +1 -1
- package/src/cli/export-source.ts +10 -4
- package/src/cli/freshness.ts +2 -8
- package/src/cli/fx-forward.ts +130 -0
- package/src/cli/fx-pair.ts +10 -9
- package/src/cli/glossary.ts +64 -20
- package/src/cli/help.ts +20 -14
- package/src/cli/history-export.ts +126 -0
- package/src/cli/history-rows.ts +196 -43
- package/src/cli/index-roots.ts +5 -45
- package/src/cli/index.ts +32 -18
- package/src/cli/issuer-membership.ts +103 -0
- package/src/cli/known-gaps.ts +118 -25
- package/src/cli/listing-arg.ts +315 -43
- package/src/cli/name-entries.ts +73 -22
- package/src/cli/native-smoke.ts +2 -0
- package/src/cli/not-a-ticker.ts +19 -9
- package/src/cli/opentui-libc.ts +5 -0
- package/src/cli/options.ts +12 -0
- package/src/cli/pane-functions/capabilities.ts +77 -20
- package/src/cli/pane-functions/catalog.ts +40 -23
- package/src/cli/pane-functions/discovery.ts +1 -1
- package/src/cli/pane-functions/dom.ts +12 -8
- package/src/cli/pane-functions/financial-ratio-shot.ts +2 -2
- package/src/cli/pane-functions/freshness.ts +174 -23
- package/src/cli/pane-functions/function-help.ts +66 -27
- package/src/cli/pane-functions/headless.ts +48 -16
- package/src/cli/pane-functions/index.ts +82 -21
- package/src/cli/pane-functions/options.ts +22 -2
- package/src/cli/pane-functions/report-notices.ts +12 -4
- package/src/cli/pane-functions/report.ts +5 -5
- package/src/cli/pane-functions/resolver.ts +65 -14
- package/src/cli/pane-functions/screenshot-assessment.ts +322 -0
- package/src/cli/pane-functions/screenshot-bridge.ts +152 -0
- package/src/cli/pane-functions/screenshot-chart-evidence.ts +396 -0
- package/src/cli/pane-functions/screenshot-data-evidence.ts +383 -0
- package/src/cli/pane-functions/screenshot-evidence.ts +1 -1
- package/src/cli/pane-functions/screenshot-payload.ts +453 -0
- package/src/cli/pane-functions/screenshot-render.ts +316 -0
- package/src/cli/pane-functions/screenshot-types.ts +162 -0
- package/src/cli/pane-functions/shot-options.ts +8 -3
- package/src/cli/peso-dollar-rates.ts +79 -0
- package/src/cli/quote-answer.ts +38 -3
- package/src/cli/report-tables.ts +190 -27
- package/src/cli/restore-plugins.ts +29 -14
- package/src/cli/result.ts +122 -25
- package/src/cli/series-search.ts +5 -5
- package/src/cli/statement-filings.ts +19 -0
- package/src/cli/suffixed-listing-rows.ts +49 -0
- package/src/cli/symbol-args.ts +50 -15
- package/src/cli/symbol-cells.ts +120 -0
- package/src/cli/symbol-list.ts +226 -60
- package/src/cli/symbol-rows.ts +131 -25
- package/src/cli/ticker-resolution.ts +108 -11
- package/src/cli/treasury-yields.ts +5 -5
- package/src/cli/types.ts +2 -0
- package/src/cli/uncovered-instrument.ts +3 -3
- package/src/cli/unknown-command.ts +6 -6
- package/src/components/chart/composite/chart-layout.ts +131 -0
- package/src/components/chart/composite/composite-chart.tsx +387 -21
- package/src/components/chart/composite/drawing-store.ts +26 -6
- package/src/components/chart/composite/interactions.ts +9 -3
- package/src/components/chart/composite/legend.tsx +75 -3
- package/src/components/chart/composite/levels.ts +5 -0
- package/src/components/chart/composite/panel-gestures.ts +41 -0
- package/src/components/chart/composite/panel-labels.ts +2 -1
- package/src/components/chart/composite/panel-surface.tsx +316 -11
- package/src/components/chart/composite/price-axis-labels.tsx +27 -3
- package/src/components/chart/composite/rasterizer.ts +44 -19
- package/src/components/chart/composite/scene.ts +16 -4
- package/src/components/chart/composite/text-renderer.ts +48 -21
- package/src/components/chart/composite/toolbar.tsx +52 -5
- package/src/components/chart/composite/types.ts +19 -0
- package/src/components/chart/composite/use-composite-chart-keyboard.ts +120 -13
- package/src/components/chart/composite/use-composite-value-scales.ts +44 -0
- package/src/components/chart/composite/use-composite-viewport.ts +12 -3
- package/src/components/chart/composite/value-scale.ts +149 -0
- package/src/components/chart/composite/volume-profile-paint.ts +6 -3
- package/src/components/chart/core/pointer.ts +2 -0
- package/src/components/chart-table/index.ts +2 -0
- package/src/components/chart-table/read.tsx +74 -0
- package/src/components/command-bar/commands/collection-list.ts +41 -19
- package/src/components/command-bar/commands/collection.ts +9 -3
- package/src/components/command-bar/commands/direct/index.ts +1 -1
- package/src/components/command-bar/commands/direct/runtime.ts +3 -2
- package/src/components/command-bar/pane-templates/items.ts +59 -6
- package/src/components/command-bar/pane-templates/workflow.ts +10 -1
- package/src/components/command-bar/routes/root/command-items.ts +32 -6
- package/src/components/command-bar/routes/root/plugin-install.ts +1 -1
- package/src/components/command-bar/routes/root/provider-search.ts +42 -11
- package/src/components/command-bar/routes/root/results.ts +18 -4
- package/src/components/command-bar/routes/root/runtime.ts +15 -3
- package/src/components/command-bar/routes/root/search-providers.ts +25 -2
- package/src/components/command-bar/routes/root/selection.ts +6 -1
- package/src/components/command-bar/routes/root/shortcut-feedback.ts +4 -1
- package/src/components/command-bar/routes/root/shortcuts.ts +30 -3
- package/src/components/command-bar/routes/ticker-search/results.ts +73 -4
- package/src/components/command-bar/selection-runtime.ts +50 -10
- package/src/components/command-bar/surface/index.tsx +24 -2
- package/src/components/command-bar/view-model.ts +7 -0
- package/src/components/command-bar/workflow/broker.ts +2 -2
- package/src/components/command-bar/workflow/collection-actions.ts +46 -7
- package/src/components/command-bar/workflow/collection-ticker.ts +32 -4
- package/src/components/command-bar/workflow/fields.ts +8 -2
- package/src/components/command-bar/workflow/ops.ts +18 -4
- package/src/components/command-bar/workflow/portfolio-position.ts +53 -4
- package/src/components/command-bar/workflow/submit.ts +3 -2
- package/src/components/command-bar/workflow/tickers.ts +5 -1
- package/src/components/company-logo.tsx +39 -0
- package/src/components/data-table/sections.ts +4 -2
- package/src/components/data-table/view.tsx +23 -3
- package/src/components/form-modal/confirm.tsx +2 -1
- package/src/components/form-modal/request.ts +5 -0
- package/src/components/form-modal/routes.ts +4 -1
- package/src/components/index.ts +13 -6
- package/src/components/layout/detached-pane-shell.tsx +1 -0
- package/src/components/layout/floating-pane.tsx +1 -0
- package/src/components/layout/header.tsx +234 -60
- package/src/components/layout/market-summary.ts +9 -6
- package/src/components/layout/pane/capture-status.ts +1 -1
- package/src/components/layout/pane/footer/model.ts +11 -5
- package/src/components/layout/pane/header.tsx +10 -3
- package/src/components/layout/pane/index.tsx +1 -0
- package/src/components/layout/pane/pane-tabs.tsx +9 -1
- package/src/components/layout/shell/chrome.ts +19 -6
- package/src/components/layout/shell/index.tsx +2 -1
- package/src/components/layout/shell/pane/layers.tsx +19 -1
- package/src/components/layout/status-bar.tsx +2 -2
- package/src/components/market-board/index.tsx +11 -3
- package/src/components/onboarding/onboarding-wizard.tsx +1 -0
- package/src/components/onboarding/portfolio-step/broker-setup-panel.tsx +2 -2
- package/src/components/onboarding/wizard-broker-sync.ts +4 -1
- package/src/components/pane-settings-dialog/desktop.tsx +20 -7
- package/src/components/pane-settings-dialog/tui.tsx +17 -9
- package/src/components/pane-settings-dialog/value.ts +8 -1
- package/src/components/pane-settings-dialog.tsx +44 -13
- package/src/components/sign-in-code-panel.tsx +27 -19
- package/src/components/ui/column-grid.tsx +48 -4
- package/src/components/ui/country-flag-art.tsx +180 -0
- package/src/components/ui/country-flag.tsx +118 -12
- package/src/components/ui/data-table/opentui/index.tsx +61 -2
- package/src/components/ui/data-table/opentui/model.ts +109 -2
- package/src/components/ui/data-table/types.ts +1 -1
- package/src/components/ui/display.tsx +5 -1
- package/src/components/ui/index.ts +3 -1
- package/src/components/ui/logo-mark.tsx +11 -2
- package/src/components/ui/query-bar.tsx +1 -1
- package/src/components/ui/row-notes.ts +79 -0
- package/src/components/ui/stat-grid.tsx +28 -3
- package/src/components/ui/status.tsx +3 -1
- package/src/core/app-services.ts +4 -0
- package/src/core/state/app/layout.ts +4 -4
- package/src/data/cached-query.ts +8 -1
- package/src/data/config/chart-settings.ts +3 -3
- package/src/data/config/home.ts +10 -2
- package/src/data/config/layout.ts +4 -1
- package/src/data/config/store/node.ts +4 -0
- package/src/data/config/store/normalize.ts +13 -3
- package/src/data/config/store/portfolio-as-of-column.ts +2 -2
- package/src/data/json-storage.ts +2 -0
- package/src/data/saved-copies.ts +84 -0
- package/src/docs/snapshot.json +65 -32
- package/src/i18n/es.ts +51 -12
- package/src/i18n/ja.ts +51 -12
- package/src/i18n/ko.ts +51 -12
- package/src/i18n/zh-cn.ts +51 -12
- package/src/i18n/zh-tw.ts +51 -12
- package/src/layout/desks.ts +1 -1
- package/src/layout/launch-layout.ts +1 -1
- package/src/layout/pane-manager/floating-actions.ts +5 -3
- package/src/layout/pane-manager/floating.ts +43 -1
- package/src/layout/pane-manager/index.ts +2 -0
- package/src/layout/selected-ticker.ts +74 -0
- package/src/market-data/depositary-pair.ts +251 -0
- package/src/market-data/futures-board.ts +1 -1
- package/src/market-data/futures-contract.ts +124 -40
- package/src/market-data/fx-closes.ts +17 -2
- package/src/market-data/hooks.tsx +19 -11
- package/src/market-data/market/change-basis.ts +49 -7
- package/src/market-data/market/freshness.ts +34 -5
- package/src/market-data/market/period-return.ts +163 -0
- package/src/market-data/market/trading-sessions.ts +13 -0
- package/src/market-data/market/year-to-date.ts +8 -13
- package/src/market-data/performance.ts +20 -14
- package/src/market-data/perpetual-premium.ts +32 -0
- package/src/market-data/published-apac-sessions.ts +2 -1
- package/src/market-data/published-futures-sessions.ts +69 -0
- package/src/market-data/quotes/contributions.ts +5 -1
- package/src/market-data/quotes/freshness.ts +42 -0
- package/src/market-data/quotes/intraday-bar.ts +37 -0
- package/src/market-data/quotes/regular-session-valuation.ts +13 -8
- package/src/market-data/quotes/resolution.ts +4 -2
- package/src/market-data/tax-equivalent.ts +1 -1
- package/src/market-data/ticker-price-returns.ts +3 -1
- package/src/news/aggregator.ts +5 -1
- package/src/news/news-model.ts +4 -0
- package/src/news/types.ts +11 -0
- package/src/notifications/app-notifier.ts +1 -1
- package/src/plugins/auto-update.ts +2 -2
- package/src/plugins/builtin/account-management/index.tsx +1 -0
- package/src/plugins/builtin/account-management/pane.tsx +9 -8
- package/src/plugins/builtin/alerts/alert-engine.ts +30 -18
- package/src/plugins/builtin/alerts/calendar-events.ts +378 -0
- package/src/plugins/builtin/alerts/cli.ts +485 -76
- package/src/plugins/builtin/alerts/command.ts +5 -10
- package/src/plugins/builtin/alerts/event-rows.ts +9 -5
- package/src/plugins/builtin/alerts/events-pane.tsx +71 -56
- package/src/plugins/builtin/alerts/events.ts +108 -5
- package/src/plugins/builtin/alerts/fired-log.ts +78 -0
- package/src/plugins/builtin/alerts/format.ts +2 -1
- package/src/plugins/builtin/alerts/headless.ts +100 -39
- package/src/plugins/builtin/alerts/history-pane.tsx +105 -62
- package/src/plugins/builtin/alerts/history-rows.ts +89 -0
- package/src/plugins/builtin/alerts/index.tsx +45 -18
- package/src/plugins/builtin/alerts/iv-level.ts +365 -0
- package/src/plugins/builtin/alerts/levels.ts +3 -3
- package/src/plugins/builtin/alerts/pane.tsx +97 -29
- package/src/plugins/builtin/alerts/price.ts +35 -0
- package/src/plugins/builtin/alerts/quotes.ts +24 -0
- package/src/plugins/builtin/alerts/research-builder.ts +84 -11
- package/src/plugins/builtin/alerts/research-rules.ts +77 -3
- package/src/plugins/builtin/alerts/scheduled-check.ts +206 -32
- package/src/plugins/builtin/alerts/scheduled-sources.ts +26 -3
- package/src/plugins/builtin/alerts/scheduled.ts +188 -29
- package/src/plugins/builtin/alerts/storage.ts +13 -10
- package/src/plugins/builtin/alerts/targets.ts +12 -3
- package/src/plugins/builtin/analytics/index.tsx +8 -2
- package/src/plugins/builtin/analytics/metrics.ts +1 -1
- package/src/plugins/builtin/analytics/risk-book.ts +215 -0
- package/src/plugins/builtin/analytics/risk-client.ts +13 -6
- package/src/plugins/builtin/analytics/risk-headless.ts +55 -21
- package/src/plugins/builtin/analytics/risk-math.ts +6 -3
- package/src/plugins/builtin/analytics/risk-model.ts +297 -104
- package/src/plugins/builtin/analytics/risk-options.ts +17 -2
- package/src/plugins/builtin/analytics/risk-pane.tsx +107 -43
- package/src/plugins/builtin/attention/pane.tsx +22 -16
- package/src/plugins/builtin/awards/headless.ts +7 -3
- package/src/plugins/builtin/awards/model.ts +18 -0
- package/src/plugins/builtin/awards/pane.tsx +12 -9
- package/src/plugins/builtin/backtest/export.ts +1 -1
- package/src/plugins/builtin/backtest/headless.ts +3 -3
- package/src/plugins/builtin/backtest/rules.ts +41 -5
- package/src/plugins/builtin/broker-manager/add-flow.tsx +12 -7
- package/src/plugins/builtin/broker-manager/detail.tsx +47 -19
- package/src/plugins/builtin/broker-manager/footer.ts +27 -11
- package/src/plugins/builtin/broker-manager/index.tsx +21 -12
- package/src/plugins/builtin/broker-manager/keyboard.ts +1 -1
- package/src/plugins/builtin/broker-manager/model.ts +12 -2
- package/src/plugins/builtin/broker-manager/pane-actions.tsx +183 -57
- package/src/plugins/builtin/broker-manager/table.ts +28 -12
- package/src/plugins/builtin/broker-trading/account-picker.tsx +2 -1
- package/src/plugins/builtin/broker-trading/chart-levels.ts +82 -13
- package/src/plugins/builtin/broker-trading/controller.ts +45 -13
- package/src/plugins/builtin/broker-trading/dock.tsx +24 -4
- package/src/plugins/builtin/broker-trading/headless.ts +2 -1
- package/src/plugins/builtin/broker-trading/index.tsx +7 -1
- package/src/plugins/builtin/broker-trading/linked-orders.ts +148 -0
- package/src/plugins/builtin/broker-trading/order-feed.ts +75 -7
- package/src/plugins/builtin/broker-trading/orders.tsx +109 -31
- package/src/plugins/builtin/broker-trading/overview-orders.tsx +9 -3
- package/src/plugins/builtin/broker-trading/pane-model.ts +30 -2
- package/src/plugins/builtin/broker-trading/pane.tsx +115 -26
- package/src/plugins/builtin/broker-trading/ticket-parts.tsx +36 -7
- package/src/plugins/builtin/broker-trading/ticket.tsx +122 -36
- package/src/plugins/builtin/buildout/cells.tsx +4 -0
- package/src/plugins/builtin/buildout/detail/index.tsx +5 -1
- package/src/plugins/builtin/buildout/detail/ui.tsx +7 -4
- package/src/plugins/builtin/buildout/pane/index.tsx +34 -18
- package/src/plugins/builtin/buildout/pane/status.tsx +0 -4
- package/src/plugins/builtin/builtin-plugin-meta.ts +1 -1
- package/src/plugins/builtin/catalysts/client.ts +2 -2
- package/src/plugins/builtin/catalysts/detail.tsx +3 -2
- package/src/plugins/builtin/catalysts/index.tsx +1 -1
- package/src/plugins/builtin/catalysts/model.ts +49 -4
- package/src/plugins/builtin/catalysts/pane.tsx +9 -11
- package/src/plugins/builtin/central-bank-rates/client.ts +5 -0
- package/src/plugins/builtin/central-bank-rates/headless.ts +36 -10
- package/src/plugins/builtin/central-bank-rates/model.ts +33 -8
- package/src/plugins/builtin/changelog/index.tsx +1 -0
- package/src/plugins/builtin/chart-composer/catalog-inventory.ts +1 -0
- package/src/plugins/builtin/chart-composer/chart-spec-edit.ts +2 -1
- package/src/plugins/builtin/chart-composer/chart-spec.ts +7 -0
- package/src/plugins/builtin/chart-composer/cli-options.ts +2 -5
- package/src/plugins/builtin/chart-composer/data-catalog-pane.tsx +2 -1
- package/src/plugins/builtin/chart-composer/editor/controller.ts +2 -0
- package/src/plugins/builtin/chart-composer/editor.tsx +4 -1
- package/src/plugins/builtin/chart-composer/headless-schema.ts +28 -26
- package/src/plugins/builtin/chart-composer/headless.ts +253 -35
- package/src/plugins/builtin/chart-composer/index.tsx +12 -2
- package/src/plugins/builtin/chart-composer/leverage-overlay.ts +142 -0
- package/src/plugins/builtin/chart-composer/pane.tsx +128 -28
- package/src/plugins/builtin/chart-composer/series-catalog.ts +1 -0
- package/src/plugins/builtin/chart-composer/series-expression.ts +65 -6
- package/src/plugins/builtin/chart-composer/session-history.ts +15 -21
- package/src/plugins/builtin/chart-composer/session-range.ts +4 -2
- package/src/plugins/builtin/chart-composer/settings.ts +31 -19
- package/src/plugins/builtin/chart-composer/use-series-catalog.ts +5 -6
- package/src/plugins/builtin/chart-composer/viewport-labels.ts +18 -8
- package/src/plugins/builtin/chat/attachments/model.ts +3 -1
- package/src/plugins/builtin/chat/content/index.tsx +1 -1
- package/src/plugins/builtin/chat/pane-links/open.ts +1 -1
- package/src/plugins/builtin/chat/people.ts +1 -1
- package/src/plugins/builtin/clinical-trials/client.ts +5 -2
- package/src/plugins/builtin/clinical-trials/model.ts +13 -4
- package/src/plugins/builtin/clinical-trials/pane.tsx +32 -12
- package/src/plugins/builtin/clinical-trials/ticker-sponsor.ts +17 -0
- package/src/plugins/builtin/cloud/askg/controller.ts +1 -1
- package/src/plugins/builtin/cloud/askg/lock-note.ts +1 -1
- package/src/plugins/builtin/cloud/askg/tool-display.ts +1 -1
- package/src/plugins/builtin/cloud/auth-commands.ts +3 -3
- package/src/plugins/builtin/cloud/team/pane-sections.tsx +105 -47
- package/src/plugins/builtin/cloud/team/pane-ui.tsx +42 -4
- package/src/plugins/builtin/cloud/team/pane.tsx +204 -64
- package/src/plugins/builtin/cloud/thesis/store.ts +45 -22
- package/src/plugins/builtin/cloud-tweets/registration.ts +1 -0
- package/src/plugins/builtin/commodities-energy/index.tsx +29 -2
- package/src/plugins/builtin/commodities-energy/view-state.ts +2 -0
- package/src/plugins/builtin/commodity-balances/pane.tsx +14 -8
- package/src/plugins/builtin/company-attention/app-rank.tsx +11 -10
- package/src/plugins/builtin/company-attention/building-model.ts +222 -0
- package/src/plugins/builtin/company-attention/building.tsx +172 -0
- package/src/plugins/builtin/company-attention/client.ts +117 -1
- package/src/plugins/builtin/company-attention/evidence.ts +16 -3
- package/src/plugins/builtin/company-attention/headless.ts +101 -5
- package/src/plugins/builtin/company-attention/index.tsx +6 -3
- package/src/plugins/builtin/company-attention/model.ts +33 -7
- package/src/plugins/builtin/company-attention/moves-model.ts +253 -0
- package/src/plugins/builtin/company-attention/moves.tsx +159 -0
- package/src/plugins/builtin/company-attention/pane.tsx +89 -31
- package/src/plugins/builtin/company-attention/signals-model.ts +229 -0
- package/src/plugins/builtin/company-attention/signals.tsx +160 -0
- package/src/plugins/builtin/company-kpis/headless.ts +3 -2
- package/src/plugins/builtin/company-kpis/model.ts +2 -2
- package/src/plugins/builtin/company-kpis/pane.tsx +5 -4
- package/src/plugins/builtin/composite-plugins.ts +2 -1
- package/src/plugins/builtin/congress-trades/headless.ts +1 -1
- package/src/plugins/builtin/connections/index.ts +1 -0
- package/src/plugins/builtin/correlation/headless-schema.ts +3 -2
- package/src/plugins/builtin/correlation/headless.ts +7 -4
- package/src/plugins/builtin/correlation/relationship/model.ts +1 -0
- package/src/plugins/builtin/correlation/settings.ts +1 -0
- package/src/plugins/builtin/cot/headless.ts +28 -6
- package/src/plugins/builtin/cot/model.ts +12 -0
- package/src/plugins/builtin/cot/pane.tsx +7 -5
- package/src/plugins/builtin/cpi/headless.ts +5 -1
- package/src/plugins/builtin/cpi/pane.tsx +11 -9
- package/src/plugins/builtin/credit-boards/model.ts +2 -0
- package/src/plugins/builtin/credit-documents/headless.ts +1 -1
- package/src/plugins/builtin/credit-documents/pane.tsx +8 -7
- package/src/plugins/builtin/crypto-board/client.ts +86 -0
- package/src/plugins/builtin/crypto-board/defi-view.tsx +218 -0
- package/src/plugins/builtin/crypto-board/defi.ts +239 -0
- package/src/plugins/builtin/crypto-board/headless.ts +117 -6
- package/src/plugins/builtin/crypto-board/index.tsx +8 -3
- package/src/plugins/builtin/crypto-board/model.ts +40 -8
- package/src/plugins/builtin/crypto-board/pane.tsx +55 -21
- package/src/plugins/builtin/crypto-board/series.ts +19 -1
- package/src/plugins/builtin/crypto-etf-flows/client.ts +60 -0
- package/src/plugins/builtin/crypto-etf-flows/headless.ts +132 -0
- package/src/plugins/builtin/crypto-etf-flows/index.tsx +44 -0
- package/src/plugins/builtin/crypto-etf-flows/model.ts +121 -0
- package/src/plugins/builtin/crypto-etf-flows/pane.tsx +193 -0
- package/src/plugins/builtin/debt-maturities/pane.tsx +4 -3
- package/src/plugins/builtin/debug/index.tsx +1 -0
- package/src/plugins/builtin/dividend-yield/index.tsx +1 -1
- package/src/plugins/builtin/docs/index.tsx +1 -1
- package/src/plugins/builtin/docs/pane.tsx +2 -2
- package/src/plugins/builtin/docs/targets.ts +1 -1
- package/src/plugins/builtin/doe/client.ts +5 -1
- package/src/plugins/builtin/doe/headless.ts +12 -6
- package/src/plugins/builtin/doe/model.ts +43 -6
- package/src/plugins/builtin/doe/pane.tsx +19 -12
- package/src/plugins/builtin/earnings/board-model.ts +13 -6
- package/src/plugins/builtin/earnings/board-table.ts +4 -1
- package/src/plugins/builtin/earnings/board.tsx +253 -50
- package/src/plugins/builtin/earnings/calendar-model.ts +188 -0
- package/src/plugins/builtin/earnings/calendar.tsx +338 -0
- package/src/plugins/builtin/earnings/client.ts +4 -3
- package/src/plugins/builtin/earnings/headless.ts +53 -15
- package/src/plugins/builtin/earnings/history-model.ts +53 -36
- package/src/plugins/builtin/earnings/index.tsx +15 -22
- package/src/plugins/builtin/earnings/model.ts +17 -12
- package/src/plugins/builtin/earnings/scope.ts +89 -0
- package/src/plugins/builtin/earnings-calls/calendar.tsx +310 -0
- package/src/plugins/builtin/earnings-calls/data.ts +146 -2
- package/src/plugins/builtin/earnings-calls/headless.ts +151 -9
- package/src/plugins/builtin/earnings-calls/index.tsx +3 -3
- package/src/plugins/builtin/earnings-calls/lock-note.ts +1 -1
- package/src/plugins/builtin/earnings-calls/pane.tsx +149 -31
- package/src/plugins/builtin/earnings-calls/upcoming.ts +195 -0
- package/src/plugins/builtin/earnings-ripple/pane.tsx +10 -5
- package/src/plugins/builtin/econ/calendar-model.ts +132 -20
- package/src/plugins/builtin/econ/detail-view.tsx +48 -10
- package/src/plugins/builtin/econ/fred-catalog.ts +23 -6
- package/src/plugins/builtin/econ/fred-series-map.ts +4 -0
- package/src/plugins/builtin/econ/index.tsx +112 -25
- package/src/plugins/builtin/econ/print-watch.ts +2 -1
- package/src/plugins/builtin/econ/types.ts +32 -1
- package/src/plugins/builtin/econ-statistics/client.ts +16 -3
- package/src/plugins/builtin/econ-statistics/defs.ts +4 -0
- package/src/plugins/builtin/econ-statistics/detail.tsx +2 -2
- package/src/plugins/builtin/econ-statistics/headless.ts +13 -2
- package/src/plugins/builtin/econ-statistics/index.tsx +3 -3
- package/src/plugins/builtin/econ-statistics/pane.tsx +2 -1
- package/src/plugins/builtin/econ-statistics/stats.ts +103 -0
- package/src/plugins/builtin/econ-statistics/view.ts +16 -1
- package/src/plugins/builtin/equity-screener/client.ts +21 -3
- package/src/plugins/builtin/equity-screener/headless.ts +77 -5
- package/src/plugins/builtin/equity-screener/live.ts +1 -1
- package/src/plugins/builtin/equity-screener/model.ts +34 -0
- package/src/plugins/builtin/equity-screener/pane.tsx +148 -106
- package/src/plugins/builtin/equity-screener/screen-check.ts +90 -0
- package/src/plugins/builtin/equity-screener/ticker-check.tsx +148 -0
- package/src/plugins/builtin/estimate-revisions/headless.ts +3 -1
- package/src/plugins/builtin/estimate-revisions/lock-note.ts +3 -3
- package/src/plugins/builtin/estimate-revisions/model.ts +8 -10
- package/src/plugins/builtin/exposure/headless.ts +51 -6
- package/src/plugins/builtin/exposure/index.tsx +28 -2
- package/src/plugins/builtin/exposure/model.ts +7 -0
- package/src/plugins/builtin/exposure/pane.tsx +16 -10
- package/src/plugins/builtin/fear-greed/index.tsx +1 -1
- package/src/plugins/builtin/filing-events/index.tsx +1 -1
- package/src/plugins/builtin/futures/model.ts +10 -9
- package/src/plugins/builtin/futures/returns.ts +8 -36
- package/src/plugins/builtin/futures/table.tsx +1 -1
- package/src/plugins/builtin/futures-curve/client.ts +40 -9
- package/src/plugins/builtin/futures-curve/headless.ts +39 -17
- package/src/plugins/builtin/futures-curve/model.ts +258 -69
- package/src/plugins/builtin/futures-curve/pane.tsx +46 -17
- package/src/plugins/builtin/fx-matrix/client.ts +15 -8
- package/src/plugins/builtin/fx-matrix/headless.ts +32 -14
- package/src/plugins/builtin/fx-matrix/index.tsx +13 -11
- package/src/plugins/builtin/fx-matrix/live-legs.ts +22 -0
- package/src/plugins/builtin/fx-matrix/settings.ts +2 -1
- package/src/plugins/builtin/gpu/board.tsx +4 -1
- package/src/plugins/builtin/gpu/changes.tsx +10 -10
- package/src/plugins/builtin/gpu/equities.tsx +4 -1
- package/src/plugins/builtin/gpu/headless.ts +9 -4
- package/src/plugins/builtin/gpu/history.tsx +4 -2
- package/src/plugins/builtin/gpu/pane.tsx +5 -3
- package/src/plugins/builtin/help/index.tsx +13 -3
- package/src/plugins/builtin/holders/beneficial-model.ts +8 -11
- package/src/plugins/builtin/holders/beneficial-report.ts +6 -5
- package/src/plugins/builtin/holders/beneficial-view.tsx +7 -3
- package/src/plugins/builtin/holders/client.ts +15 -2
- package/src/plugins/builtin/holders/format.ts +28 -17
- package/src/plugins/builtin/holders/headless.ts +48 -8
- package/src/plugins/builtin/holders/index-holders.ts +264 -0
- package/src/plugins/builtin/holders/pane.tsx +79 -15
- package/src/plugins/builtin/holders/report-rows.ts +35 -7
- package/src/plugins/builtin/holders/table-model.ts +2 -1
- package/src/plugins/builtin/holders/thirteenf-match.ts +3 -1
- package/src/plugins/builtin/holders/treemap.tsx +2 -2
- package/src/plugins/builtin/insider/base-values.ts +11 -7
- package/src/plugins/builtin/insider/client.ts +3 -0
- package/src/plugins/builtin/insider/headless.ts +20 -7
- package/src/plugins/builtin/insider/index.tsx +17 -8
- package/src/plugins/builtin/insider/issuer.ts +34 -4
- package/src/plugins/builtin/insider/signals-client.ts +3 -3
- package/src/plugins/builtin/insider/signals.tsx +1 -1
- package/src/plugins/builtin/insider/table-model.ts +35 -13
- package/src/plugins/builtin/insider/table.tsx +5 -2
- package/src/plugins/builtin/ipo-calendar/pane.tsx +7 -4
- package/src/plugins/builtin/iv-history/client.ts +20 -0
- package/src/plugins/builtin/iv-history/events.ts +145 -0
- package/src/plugins/builtin/iv-history/format.ts +3 -0
- package/src/plugins/builtin/iv-history/headless.ts +91 -7
- package/src/plugins/builtin/iv-history/index.tsx +1 -1
- package/src/plugins/builtin/iv-history/model.ts +13 -4
- package/src/plugins/builtin/iv-history/series.ts +3 -1
- package/src/plugins/builtin/jobs/lock-note.ts +1 -1
- package/src/plugins/builtin/jobs/model.ts +4 -15
- package/src/plugins/builtin/jobs/pane.tsx +7 -5
- package/src/plugins/builtin/jobs/share-bars.tsx +11 -5
- package/src/plugins/builtin/jodi/pane.tsx +14 -8
- package/src/plugins/builtin/layout-manager/index.tsx +1 -0
- package/src/plugins/builtin/macro-day/headless.ts +20 -7
- package/src/plugins/builtin/macro-day/index.tsx +3 -2
- package/src/plugins/builtin/macro-day/model.ts +29 -8
- package/src/plugins/builtin/macro-day/pane.tsx +46 -10
- package/src/plugins/builtin/macro-day/releases.ts +55 -13
- package/src/plugins/builtin/market-heatmap/data.ts +9 -2
- package/src/plugins/builtin/market-heatmap/evidence.ts +1 -1
- package/src/plugins/builtin/market-heatmap/headless.ts +9 -6
- package/src/plugins/builtin/market-heatmap/index.tsx +3 -3
- package/src/plugins/builtin/market-heatmap/model.ts +10 -7
- package/src/plugins/builtin/market-movers/client.ts +36 -21
- package/src/plugins/builtin/market-movers/headless.ts +8 -2
- package/src/plugins/builtin/market-movers/index.tsx +16 -10
- package/src/plugins/builtin/market-movers/screener.ts +33 -11
- package/src/plugins/builtin/market-movers/session-body.tsx +4 -2
- package/src/plugins/builtin/market-movers/session-table.ts +4 -2
- package/src/plugins/builtin/market-movers/table.ts +4 -1
- package/src/plugins/builtin/market-valuation/headless.ts +2 -0
- package/src/plugins/builtin/market-valuation/view.ts +5 -0
- package/src/plugins/builtin/members/headless.ts +6 -5
- package/src/plugins/builtin/members/pane.tsx +11 -4
- package/src/plugins/builtin/mna/client.ts +1 -0
- package/src/plugins/builtin/mna/detail.tsx +20 -32
- package/src/plugins/builtin/mna/distress/detail.tsx +16 -4
- package/src/plugins/builtin/mna/distress/model.ts +3 -2
- package/src/plugins/builtin/mna/distress/pane.tsx +7 -4
- package/src/plugins/builtin/mna/headless.ts +6 -13
- package/src/plugins/builtin/mna/model.ts +93 -15
- package/src/plugins/builtin/mna/pane.tsx +5 -4
- package/src/plugins/builtin/news/headless.ts +12 -6
- package/src/plugins/builtin/news/index.tsx +10 -1
- package/src/plugins/builtin/news/wire/index.tsx +3 -2
- package/src/plugins/builtin/news/wire/news/command-bar-search.ts +26 -10
- package/src/plugins/builtin/news/wire/news/query-presets.ts +6 -2
- package/src/plugins/builtin/news/wire/rss/cli.ts +3 -3
- package/src/plugins/builtin/notes/cli.ts +50 -15
- package/src/plugins/builtin/notes/export.ts +17 -6
- package/src/plugins/builtin/notes/files.ts +16 -5
- package/src/plugins/builtin/openfda/pane.tsx +1 -1
- package/src/plugins/builtin/options/carry.ts +2 -2
- package/src/plugins/builtin/options/enrichment-model.ts +10 -9
- package/src/plugins/builtin/options/index.tsx +1 -1
- package/src/plugins/builtin/options/model-spot.ts +70 -4
- package/src/plugins/builtin/options/view.tsx +51 -23
- package/src/plugins/builtin/options-calculator/headless.ts +46 -7
- package/src/plugins/builtin/options-calculator/pane.tsx +3 -2
- package/src/plugins/builtin/options-positioning/headless.ts +11 -3
- package/src/plugins/builtin/options-positioning/model.ts +24 -0
- package/src/plugins/builtin/options-positioning/pane.tsx +10 -12
- package/src/plugins/builtin/options-scenario/client.ts +142 -29
- package/src/plugins/builtin/options-scenario/collar.ts +8 -6
- package/src/plugins/builtin/options-scenario/csp-screen-headless.ts +127 -0
- package/src/plugins/builtin/options-scenario/csp-screen-pane.tsx +165 -0
- package/src/plugins/builtin/options-scenario/csp-screen.ts +258 -0
- package/src/plugins/builtin/options-scenario/csp.ts +101 -21
- package/src/plugins/builtin/options-scenario/headless.ts +49 -21
- package/src/plugins/builtin/options-scenario/hedge.ts +20 -14
- package/src/plugins/builtin/options-scenario/index.tsx +28 -3
- package/src/plugins/builtin/options-scenario/model.ts +13 -0
- package/src/plugins/builtin/options-scenario/pane.tsx +22 -10
- package/src/plugins/builtin/perps/equity-row.tsx +11 -3
- package/src/plugins/builtin/perps/freshness.ts +8 -5
- package/src/plugins/builtin/perps/headless.ts +3 -1
- package/src/plugins/builtin/perps/list-perpetuals.ts +25 -4
- package/src/plugins/builtin/perps/live-rows.ts +161 -0
- package/src/plugins/builtin/perps/markets-section.tsx +154 -0
- package/src/plugins/builtin/perps/pane.tsx +36 -17
- package/src/plugins/builtin/perps/venue-markets.ts +96 -0
- package/src/plugins/builtin/plugin-marketplace/index.tsx +2 -1
- package/src/plugins/builtin/plugin-marketplace/pane.tsx +145 -60
- package/src/plugins/builtin/portfolio-list/cli/bulk-symbols.ts +78 -27
- package/src/plugins/builtin/portfolio-list/cli/portfolio-command.ts +158 -141
- package/src/plugins/builtin/portfolio-list/cli/render.ts +49 -20
- package/src/plugins/builtin/portfolio-list/cli/shared.ts +3 -3
- package/src/plugins/builtin/portfolio-list/cli/watchlist-command.ts +29 -24
- package/src/plugins/builtin/portfolio-list/headless.ts +6 -3
- package/src/plugins/builtin/portfolio-list/income.ts +13 -2
- package/src/plugins/builtin/portfolio-list/index.tsx +9 -2
- package/src/plugins/builtin/portfolio-list/pane/index.tsx +21 -8
- package/src/plugins/builtin/portfolio-list/pane/purchase-date-fx.ts +46 -0
- package/src/plugins/builtin/portfolio-list/summary/live-accounts.ts +16 -9
- package/src/plugins/builtin/portfolio-list/summary/totals.ts +2 -15
- package/src/plugins/builtin/power/client.ts +6 -3
- package/src/plugins/builtin/power/evidence.ts +22 -7
- package/src/plugins/builtin/power/gas.tsx +5 -1
- package/src/plugins/builtin/power/pane.tsx +44 -32
- package/src/plugins/builtin/power/prices.tsx +10 -3
- package/src/plugins/builtin/research/analyst-headless.ts +25 -8
- package/src/plugins/builtin/research/analyst-model.ts +68 -3
- package/src/plugins/builtin/research/corporate-actions-pane.tsx +63 -14
- package/src/plugins/builtin/research/event-model.ts +3 -1
- package/src/plugins/builtin/research/event-sources.ts +12 -4
- package/src/plugins/builtin/research/index.tsx +2 -1
- package/src/plugins/builtin/research/relative-valuation-basis.ts +58 -0
- package/src/plugins/builtin/research/relative-valuation-columns.ts +31 -2
- package/src/plugins/builtin/research/relative-valuation-currency.ts +12 -5
- package/src/plugins/builtin/research/relative-valuation-headless.ts +84 -26
- package/src/plugins/builtin/research/relative-valuation-model.ts +88 -19
- package/src/plugins/builtin/research/relative-valuation-pane.tsx +76 -9
- package/src/plugins/builtin/research/relative-valuation-peers.ts +1 -1
- package/src/plugins/builtin/reverse-dcf/client.ts +2 -1
- package/src/plugins/builtin/reverse-dcf/model.ts +10 -5
- package/src/plugins/builtin/risk-factors/index.tsx +2 -2
- package/src/plugins/builtin/scanner/lock-note.ts +1 -1
- package/src/plugins/builtin/seasonality/client.ts +2 -1
- package/src/plugins/builtin/sec/forms.ts +13 -0
- package/src/plugins/builtin/sec/fund-abroad.ts +32 -0
- package/src/plugins/builtin/sec/fund-facts.ts +68 -8
- package/src/plugins/builtin/sec/headless.ts +85 -8
- package/src/plugins/builtin/sec/index.tsx +58 -12
- package/src/plugins/builtin/sectors/client.ts +6 -4
- package/src/plugins/builtin/sectors/sector-model.ts +11 -15
- package/src/plugins/builtin/series-inventory.ts +2 -0
- package/src/plugins/builtin/shared/broker-reconnect.ts +107 -22
- package/src/plugins/builtin/shared/cloud-resource.ts +15 -2
- package/src/plugins/builtin/shared/cloud-upgrade.ts +34 -6
- package/src/plugins/builtin/shared/earnings-calendar.ts +375 -0
- package/src/plugins/builtin/{earnings/estimate-basis.ts → shared/earnings-estimate-basis.ts} +1 -1
- package/src/plugins/builtin/shared/earnings-report.ts +3 -3
- package/src/plugins/builtin/shared/fx-rate-freshness.ts +23 -1
- package/src/plugins/builtin/shared/job-posting.ts +129 -0
- package/src/plugins/builtin/shared/pro-lock-note.ts +3 -3
- package/src/plugins/builtin/shared/report-freshness.ts +3 -0
- package/src/plugins/builtin/shared/research-trading.tsx +23 -0
- package/src/plugins/builtin/shared/series-cache.ts +2 -0
- package/src/plugins/builtin/shared/series-list-detail.tsx +3 -1
- package/src/plugins/builtin/shared/ticker-surface.ts +2 -1
- package/src/plugins/builtin/shared/volatility/options.ts +2 -1
- package/src/plugins/builtin/short-interest/client.ts +2 -0
- package/src/plugins/builtin/short-interest/headless.ts +41 -12
- package/src/plugins/builtin/short-interest/index.tsx +23 -1
- package/src/plugins/builtin/short-interest/model.ts +70 -19
- package/src/plugins/builtin/short-interest/pane.tsx +19 -2
- package/src/plugins/builtin/short-interest/publications-client.ts +82 -0
- package/src/plugins/builtin/short-interest/publications-headless.ts +29 -0
- package/src/plugins/builtin/short-interest/publications-model.ts +50 -0
- package/src/plugins/builtin/short-interest/publications-pane.tsx +66 -0
- package/src/plugins/builtin/short-interest/schedule.ts +35 -2
- package/src/plugins/builtin/short-interest/surface.tsx +11 -4
- package/src/plugins/builtin/short-interest/types.ts +9 -0
- package/src/plugins/builtin/short-interest/watch-client.ts +14 -8
- package/src/plugins/builtin/short-interest/watch-model.ts +12 -25
- package/src/plugins/builtin/short-interest/watch-pane.tsx +5 -1
- package/src/plugins/builtin/social-mentions/client.ts +2 -1
- package/src/plugins/builtin/supply-chain/flow.tsx +33 -9
- package/src/plugins/builtin/supply-chain/model.ts +51 -3
- package/src/plugins/builtin/supply-chain/pane.tsx +78 -39
- package/src/plugins/builtin/supply-chain/row-evidence.tsx +1 -1
- package/src/plugins/builtin/themes/headless.ts +8 -5
- package/src/plugins/builtin/themes/model.ts +14 -4
- package/src/plugins/builtin/themes/pane.tsx +24 -5
- package/src/plugins/builtin/thirteenf/headless.ts +5 -5
- package/src/plugins/builtin/thirteenf/signals.ts +3 -1
- package/src/plugins/builtin/ticker-detail/adr-pair/headless.ts +123 -0
- package/src/plugins/builtin/ticker-detail/adr-pair/model.ts +132 -0
- package/src/plugins/builtin/ticker-detail/adr-pair/tab.tsx +87 -0
- package/src/plugins/builtin/ticker-detail/data-panes/historical-prices.tsx +40 -26
- package/src/plugins/builtin/ticker-detail/data-panes/history-bars.ts +8 -4
- package/src/plugins/builtin/ticker-detail/data-panes/returns-history.ts +67 -3
- package/src/plugins/builtin/ticker-detail/data-panes/returns-model.ts +112 -5
- package/src/plugins/builtin/ticker-detail/data-panes/returns-pane.tsx +17 -2
- package/src/plugins/builtin/ticker-detail/financials/aggregation.ts +21 -7
- package/src/plugins/builtin/ticker-detail/financials/model.ts +36 -1
- package/src/plugins/builtin/ticker-detail/financials/offerings.ts +56 -0
- package/src/plugins/builtin/ticker-detail/financials/ratios.ts +62 -13
- package/src/plugins/builtin/ticker-detail/financials/tab.tsx +30 -4
- package/src/plugins/builtin/ticker-detail/headless-schema.ts +14 -2
- package/src/plugins/builtin/ticker-detail/headless.ts +148 -35
- package/src/plugins/builtin/ticker-detail/index.tsx +37 -5
- package/src/plugins/builtin/ticker-detail/overview/model.ts +65 -10
- package/src/plugins/builtin/ticker-detail/overview/pane.tsx +9 -1
- package/src/plugins/builtin/ticker-detail/overview-tab.tsx +68 -11
- package/src/plugins/builtin/ticker-detail/pane.tsx +11 -0
- package/src/plugins/builtin/ticker-detail/quote-footer.ts +8 -3
- package/src/plugins/builtin/ticker-detail/research-tabs.ts +11 -0
- package/src/plugins/builtin/vol-surface/client.ts +28 -7
- package/src/plugins/builtin/vol-surface/headless.ts +43 -15
- package/src/plugins/builtin/vol-surface/model.ts +34 -12
- package/src/plugins/builtin/vol-surface/pane.tsx +33 -13
- package/src/plugins/builtin/vol-surface/stored.ts +34 -3
- package/src/plugins/builtin/vol-surface/tables.ts +14 -0
- package/src/plugins/builtin/volatility/model.ts +5 -10
- package/src/plugins/builtin/world-venue-map/basemap-layer.tsx +4 -3
- package/src/plugins/builtin/world-venue-map/basemap.ts +3 -1
- package/src/plugins/builtin/world-venue-map/chokepoint-chart.ts +40 -0
- package/src/plugins/builtin/world-venue-map/evidence.ts +1 -1
- package/src/plugins/builtin/world-venue-map/geo-series.ts +90 -11
- package/src/plugins/builtin/world-venue-map/headless.ts +1 -1
- package/src/plugins/builtin/world-venue-map/index.ts +3 -26
- package/src/plugins/builtin/world-venue-map/layers.ts +1 -1
- package/src/plugins/builtin/world-venue-map/map.tsx +2 -1
- package/src/plugins/builtin/world-venue-map/pane.tsx +4 -2
- package/src/plugins/builtin/world-venue-map/venue-header.tsx +15 -4
- package/src/plugins/builtin/yield-curve/client.ts +25 -0
- package/src/plugins/builtin/yield-curve/curves.ts +7 -4
- package/src/plugins/builtin/yield-curve/headless.ts +38 -4
- package/src/plugins/builtin/yield-curve/history.ts +4 -3
- package/src/plugins/builtin/yield-curve/index.tsx +12 -6
- package/src/plugins/builtin/yield-curve/swaps-model.ts +93 -0
- package/src/plugins/builtin/yield-curve/swaps.tsx +99 -0
- package/src/plugins/bundle.ts +1 -1
- package/src/plugins/catalog-browser.ts +2 -1
- package/src/plugins/compat.ts +3 -3
- package/src/plugins/dependencies.ts +75 -14
- package/src/plugins/extracted-plugins.ts +132 -34
- package/src/plugins/host-link.ts +149 -34
- package/src/plugins/installer.ts +35 -10
- package/src/plugins/loader.ts +206 -38
- package/src/plugins/manager-node.ts +2 -2
- package/src/plugins/marketplace/deactivation.ts +22 -0
- package/src/plugins/marketplace/model.ts +2 -2
- package/src/plugins/marketplace/packs.ts +1 -1
- package/src/plugins/ownership.ts +1 -1
- package/src/plugins/peer-retry.ts +155 -0
- package/src/plugins/registry/contributions.ts +3 -1
- package/src/plugins/registry/index.ts +4 -3
- package/src/plugins/registry/plugin-state.ts +3 -0
- package/src/plugins/seed-notice.ts +20 -0
- package/src/plugins/shortcut-argument.ts +39 -0
- package/src/portfolio/allocation.ts +1 -1
- package/src/portfolio/collection-name.ts +31 -0
- package/src/portfolio/column-values.ts +10 -8
- package/src/portfolio/cost-fx.ts +296 -19
- package/src/portfolio/manual-lots.ts +75 -0
- package/src/portfolio/mutations.ts +60 -22
- package/src/portfolio/suffixed-listings.ts +209 -0
- package/src/portfolio/totals-currency.ts +24 -0
- package/src/public/__snapshots__/public-api.test.ts.snap +14 -0
- package/src/public/time-series.ts +11 -8
- package/src/remote/schema.ts +1 -1
- package/src/renderers/browser/config-host.ts +3 -0
- package/src/renderers/browser/main.tsx +23 -3
- package/src/renderers/dom/boot-frame-page.ts +187 -0
- package/src/renderers/dom/boot-frame.ts +237 -0
- package/src/renderers/dom/build-assets.ts +46 -8
- package/src/renderers/dom/desktop/controls.tsx +1 -1
- package/src/renderers/dom/desktop/query-bar.tsx +2 -0
- package/src/renderers/dom/dom-ui-host.tsx +4 -29
- package/src/renderers/dom/host/ascii-text.ts +16 -2
- package/src/renderers/dom/host/box.tsx +43 -2
- package/src/renderers/dom/host/chart-surface.tsx +2 -0
- package/src/renderers/dom/host/hls.chunk.ts +3 -0
- package/src/renderers/dom/host/image-surface.tsx +49 -0
- package/src/renderers/dom/host/media-surface.tsx +24 -18
- package/src/renderers/dom/host/mouse.ts +30 -0
- package/src/renderers/dom/host/size-observer.ts +1 -1
- package/src/renderers/dom/host/style.ts +1 -1
- package/src/renderers/dom/host/tabs.tsx +16 -5
- package/src/renderers/dom/host/top-surface.ts +127 -0
- package/src/renderers/dom/styles.css +115 -0
- package/src/renderers/dom/test-utils.tsx +2 -1
- package/src/renderers/electrobun/bun/application-menu/index.ts +3 -3
- package/src/renderers/electrobun/bun/core-capabilities.ts +9 -1
- package/src/renderers/electrobun/bun/desktop/backend-requests.ts +3 -0
- package/src/renderers/electrobun/bun/desktop/backend.ts +56 -3
- package/src/renderers/electrobun/bun/desktop/detached-windows.ts +1 -1
- package/src/renderers/electrobun/bun/desktop/host-requests.ts +9 -3
- package/src/renderers/electrobun/bun/desktop/initialization.ts +81 -18
- package/src/renderers/electrobun/bun/desktop/update.ts +210 -30
- package/src/renderers/electrobun/bun/external-plugins.ts +29 -7
- package/src/renderers/electrobun/bun/index.ts +11 -1
- package/src/renderers/electrobun/bun/window/boot-frame.ts +67 -0
- package/src/renderers/electrobun/bun/window/create.ts +4 -1
- package/src/renderers/electrobun/shared/boot-frame.ts +7 -0
- package/src/renderers/electrobun/shared/protocol.ts +6 -1
- package/src/renderers/electrobun/view/cli-pane-shot-entry.tsx +1 -1
- package/src/renderers/electrobun/view/config-host.ts +3 -0
- package/src/renderers/electrobun/view/fatal-screen.tsx +1 -1
- package/src/renderers/electrobun/view/main.tsx +30 -4
- package/src/renderers/electrobun/view/news-source.ts +9 -7
- package/src/renderers/electrobun/view/remote/asset-data-client.ts +9 -2
- package/src/renderers/electrobun/view/ui-host.tsx +1 -1
- package/src/renderers/opentui/browser-open.ts +88 -0
- package/src/renderers/opentui/host.tsx +5 -14
- package/src/renderers/opentui/image/loader.ts +3 -2
- package/src/renderers/opentui/native-smoke.ts +10 -1
- package/src/renderers/opentui/pane-image/index.ts +2 -1
- package/src/renderers/opentui/render-lib.ts +253 -0
- package/src/renderers/opentui/render-timing-smoke.ts +1 -1
- package/src/renderers/opentui/start.tsx +8 -1
- package/src/renderers/share/layout-view.tsx +2 -2
- package/src/renderers/share/main.tsx +4 -4
- package/src/renderers/share/view.tsx +1 -1
- package/src/series/resolve.ts +22 -6
- package/src/series/standalone.ts +30 -2
- package/src/series/types.ts +8 -1
- package/src/shares/api.ts +4 -1
- package/src/shares/pane.ts +1 -1
- package/src/sources/gloomberb-cloud/fred-series.ts +46 -1
- package/src/sources/gloomberb-cloud/index.ts +39 -16
- package/src/sources/gloomberb-cloud/news.ts +39 -0
- package/src/sources/gloomberb-cloud/normalizers.ts +14 -1
- package/src/sources/gloomberb-cloud/perpetuals.ts +49 -1
- package/src/sources/listing-symbols.ts +37 -0
- package/src/sources/provider-errors.ts +16 -2
- package/src/sources/provider-router/financial-routes.ts +21 -3
- package/src/sources/provider-router/financials.ts +15 -2
- package/src/sources/provider-router/history.ts +30 -8
- package/src/sources/provider-router/index.ts +16 -0
- package/src/sources/provider-router/primary.ts +1 -1
- package/src/state/app/bootstrap.ts +23 -0
- package/src/state/hooks/inline-tickers.ts +30 -5
- package/src/sync/controller.ts +1 -1
- package/src/sync/core-contributors.ts +46 -14
- package/src/team/collections-sync.ts +2 -1
- package/src/team/collections.ts +178 -17
- package/src/telemetry/crash-reports.ts +21 -4
- package/src/telemetry/update-failures-node.ts +59 -0
- package/src/telemetry/update-failures.ts +307 -0
- package/src/test-support/builtin-panes.ts +1 -1
- package/src/theme/colors.ts +3 -30
- package/src/theme/ui-tokens.ts +37 -1
- package/src/tickers/company-name-listing.ts +215 -36
- package/src/tickers/company-name.ts +43 -0
- package/src/tickers/index-roots.ts +47 -0
- package/src/tickers/instrument-label.ts +5 -1
- package/src/tickers/listing-fate.ts +30 -0
- package/src/tickers/metadata.ts +10 -0
- package/src/tickers/perpetual-listing.ts +5 -2
- package/src/tickers/search/home-listing.ts +75 -0
- package/src/tickers/search/index.ts +76 -27
- package/src/tickers/search/ranking.ts +54 -4
- package/src/tickers/search/upsert.ts +29 -0
- package/src/tickers/terminal-codes.ts +416 -40
- package/src/time-series/bar-aggregation.ts +243 -0
- package/src/time-series/base-series.ts +307 -0
- package/src/time-series/chart-bounds.ts +349 -0
- package/src/time-series/chart-seed.ts +142 -0
- package/src/time-series/economic.ts +5 -0
- package/src/time-series/fundamentals.ts +18 -3
- package/src/time-series/history-acquisition.ts +499 -0
- package/src/time-series/leverage.ts +100 -0
- package/src/time-series/market-resolution.ts +4 -2
- package/src/time-series/market.ts +2 -1
- package/src/time-series/price-comparison.ts +175 -30
- package/src/time-series/range.ts +9 -1
- package/src/time-series/resolution.ts +174 -16
- package/src/time-series/resolve-context.ts +157 -0
- package/src/time-series/resolve.ts +126 -1577
- package/src/time-series/series-name.ts +38 -0
- package/src/time-series/series-presentation.ts +208 -0
- package/src/time-series/spec.ts +11 -6
- package/src/time-series/studies.ts +109 -12
- package/src/time-series/tail-reconcile.ts +121 -0
- package/src/time-series/types.ts +29 -2
- package/src/time-series/use-chart-resolution.ts +4 -5
- package/src/types/broker.ts +10 -0
- package/src/types/config.ts +14 -0
- package/src/types/data-provider.ts +20 -0
- package/src/types/exchange-rate.ts +6 -0
- package/src/types/financials.ts +104 -7
- package/src/types/headless.ts +83 -6
- package/src/types/instrument.ts +3 -0
- package/src/types/issuer-listings.ts +28 -0
- package/src/types/plugin.ts +65 -8
- package/src/types/price-history.ts +2 -0
- package/src/types/ticker.ts +13 -0
- package/src/types/trading.ts +59 -1
- package/src/ui/ascii-font.ts +13 -1
- package/src/ui/host.tsx +6 -1
- package/src/updater/command-names.ts +175 -0
- package/src/updater/failure.ts +163 -0
- package/src/updater/index.ts +97 -28
- package/src/utils/calendar-date.ts +32 -15
- package/src/utils/cash-runway.ts +241 -0
- package/src/utils/central-banks.ts +42 -0
- package/src/utils/cli-output.ts +259 -80
- package/src/utils/contract-month.ts +16 -0
- package/src/utils/crypto-pair.ts +61 -3
- package/src/utils/currency-pair.ts +26 -0
- package/src/utils/currency-units.ts +29 -0
- package/src/utils/datetime-format.ts +10 -0
- package/src/utils/debug-log.ts +1 -1
- package/src/utils/decimal-comma.ts +39 -6
- package/src/utils/exchange-announcements.ts +71 -0
- package/src/utils/exchange-rate-snapshot.ts +10 -0
- package/src/utils/financial-statements.ts +83 -4
- package/src/utils/format.ts +34 -16
- package/src/utils/fundamentals.ts +150 -34
- package/src/utils/fx-market-hours.ts +10 -1
- package/src/utils/latest-financial-period.ts +8 -0
- package/src/utils/linux-libc.ts +54 -0
- package/src/utils/market-capitalization.ts +111 -15
- package/src/utils/max-drawdown.ts +64 -0
- package/src/utils/network-failure.ts +83 -0
- package/src/utils/option-expiry.ts +139 -7
- package/src/utils/price-earnings.ts +11 -5
- package/src/utils/price-history.ts +18 -8
- package/src/utils/price-window.ts +131 -0
- package/src/utils/release-date.ts +47 -0
- package/src/utils/sec.ts +71 -0
- package/src/utils/throttled-fetch.ts +11 -4
- package/src/utils/trailing-eps.ts +67 -0
- package/src/utils/typed-text.ts +21 -0
- package/src/utils/utc-time.ts +24 -1
- package/src/version.ts +6 -0
- package/src/cli/pane-functions/screenshot.ts +0 -2122
|
@@ -1,6 +1,9 @@
|
|
|
1
1
|
import type { MnaDeal, MnaStatus, MnaTerms } from "../../../api-client/mna";
|
|
2
2
|
import type { Quote } from "../../../types/financials";
|
|
3
|
+
import { getListingSymbol } from "../../../sources/listing-symbols";
|
|
4
|
+
import { parsePublicTickerKey } from "../../../utils/exchanges";
|
|
3
5
|
import { formatCompact } from "../../../utils/format";
|
|
6
|
+
import { nonUsSecListingVenue } from "../../../utils/sec";
|
|
4
7
|
|
|
5
8
|
export const MNA_PANE_ID = "mna";
|
|
6
9
|
export const MISSING = "--";
|
|
@@ -33,6 +36,28 @@ function ratioLabel(ratio: number, symbol: string | null): string {
|
|
|
33
36
|
return symbol ? `${shares} ${symbol}` : `${shares} sh`;
|
|
34
37
|
}
|
|
35
38
|
|
|
39
|
+
/**
|
|
40
|
+
* The symbol a company's deals are filed under, from the ticker a pane is
|
|
41
|
+
* linked to. A deal carries its companies' quote symbols: plain for a US
|
|
42
|
+
* listing, suffixed by the venue elsewhere (ATH.TO, SHEL.L, 9984.T). A
|
|
43
|
+
* listing abroad therefore asks by that quote symbol: its bare symbol is
|
|
44
|
+
* another company's US ticker (ATH is Athene in New York, Athabasca in
|
|
45
|
+
* Toronto). A US listing, a symbol with no venue and a symbol already
|
|
46
|
+
* suffixed go as they are, so a US ticker is asked for exactly as before.
|
|
47
|
+
* `savedExchange` is the venue the saved ticker names, for a key with none.
|
|
48
|
+
*/
|
|
49
|
+
export function dealsSymbol(key: string | null | undefined, savedExchange = ""): string {
|
|
50
|
+
const value = key?.trim();
|
|
51
|
+
if (!value) return "";
|
|
52
|
+
if (nonUsSecListingVenue(value, savedExchange)) return getListingSymbol(value, savedExchange).toUpperCase();
|
|
53
|
+
return parsePublicTickerKey(value).symbol;
|
|
54
|
+
}
|
|
55
|
+
|
|
56
|
+
/** Each holder gets the cash or the shares, not both. Older servers never say so. */
|
|
57
|
+
export function isElection(terms: MnaTerms): boolean {
|
|
58
|
+
return terms.election === true && terms.cashPerShare != null && terms.exchangeRatio != null;
|
|
59
|
+
}
|
|
60
|
+
|
|
36
61
|
/** What one target share gets, in as few characters as the terms allow. */
|
|
37
62
|
export function termsLabel(terms: MnaTerms): string {
|
|
38
63
|
const parts: string[] = [];
|
|
@@ -48,7 +73,7 @@ export function termsLabel(terms: MnaTerms): string {
|
|
|
48
73
|
: terms.consideration === "mixed" ? "Cash and stock"
|
|
49
74
|
: MISSING);
|
|
50
75
|
}
|
|
51
|
-
let label = parts.join(" + ");
|
|
76
|
+
let label = parts.join(isElection(terms) ? " or " : " + ");
|
|
52
77
|
if (terms.cvr) label += " + CVR";
|
|
53
78
|
if (terms.partial) label += ", partial";
|
|
54
79
|
return label;
|
|
@@ -75,7 +100,7 @@ const PENCE = new Set(["GBp", "GBX"]);
|
|
|
75
100
|
* London quotes arrive in pounds while UK offers are often in pence, so the
|
|
76
101
|
* two compare after scaling; any other currency mismatch has no price.
|
|
77
102
|
*/
|
|
78
|
-
function inQuoteCurrency(amount: number, from: string | null, quoteCurrency: string | undefined): number | null {
|
|
103
|
+
export function inQuoteCurrency(amount: number, from: string | null, quoteCurrency: string | undefined): number | null {
|
|
79
104
|
const offer = from ?? "USD";
|
|
80
105
|
const quote = quoteCurrency ?? "USD";
|
|
81
106
|
if (offer === quote) return amount;
|
|
@@ -85,28 +110,81 @@ function inQuoteCurrency(amount: number, from: string | null, quoteCurrency: str
|
|
|
85
110
|
return offer.toUpperCase() === quote.toUpperCase() ? amount : null;
|
|
86
111
|
}
|
|
87
112
|
|
|
113
|
+
function cashLeg(terms: MnaTerms, targetQuote: Quote | null): number | null {
|
|
114
|
+
return terms.cashPerShare == null ? null : inQuoteCurrency(terms.cashPerShare, terms.currency, targetQuote?.currency);
|
|
115
|
+
}
|
|
116
|
+
|
|
117
|
+
function stockLeg(terms: MnaTerms, targetQuote: Quote | null, ratioQuote: Quote | null): number | null {
|
|
118
|
+
const price = ratioQuote?.price;
|
|
119
|
+
if (terms.exchangeRatio == null || !terms.ratioSymbol || price == null || !Number.isFinite(price) || price <= 0) return null;
|
|
120
|
+
const leg = inQuoteCurrency(price, ratioQuote?.currency ?? null, targetQuote?.currency);
|
|
121
|
+
return leg == null ? null : terms.exchangeRatio * leg;
|
|
122
|
+
}
|
|
123
|
+
|
|
124
|
+
/**
|
|
125
|
+
* The leg an election is priced at. It pays each holder the cash or the
|
|
126
|
+
* shares, never both, so it is priced at its cash leg: the legs are set about
|
|
127
|
+
* equal at signing, proration means a holder cannot count on getting the
|
|
128
|
+
* stock, and the cash does not move. The stock leg stands in only when the
|
|
129
|
+
* cash cannot be compared with the target's quote. Without a quote, the cash.
|
|
130
|
+
*/
|
|
131
|
+
export function electionLeg(terms: MnaTerms, targetQuote: Quote | null): "cash" | "stock" {
|
|
132
|
+
return !targetQuote || cashLeg(terms, targetQuote) != null ? "cash" : "stock";
|
|
133
|
+
}
|
|
134
|
+
|
|
88
135
|
/**
|
|
89
136
|
* What the terms pay per target share at the latest prices, in the target
|
|
90
137
|
* quote's currency. Null when a leg cannot be priced: no terms, a ratio
|
|
91
|
-
* without its listing, or cash in another currency.
|
|
138
|
+
* without its listing, or cash in another currency. An election is one leg,
|
|
139
|
+
* the one {@link electionLeg} picks.
|
|
92
140
|
*/
|
|
93
141
|
function offerValue(deal: MnaDeal, targetQuote: Quote | null, ratioQuote: Quote | null): number | null {
|
|
94
142
|
const { terms } = deal;
|
|
95
143
|
if (terms.cashPerShare == null && terms.exchangeRatio == null) return null;
|
|
96
|
-
let total
|
|
97
|
-
if (terms
|
|
98
|
-
|
|
99
|
-
|
|
100
|
-
|
|
144
|
+
let total: number | null;
|
|
145
|
+
if (isElection(terms)) {
|
|
146
|
+
total = electionLeg(terms, targetQuote) === "cash"
|
|
147
|
+
? cashLeg(terms, targetQuote)
|
|
148
|
+
: stockLeg(terms, targetQuote, ratioQuote);
|
|
149
|
+
} else {
|
|
150
|
+
const cash = terms.cashPerShare == null ? 0 : cashLeg(terms, targetQuote);
|
|
151
|
+
const stock = terms.exchangeRatio == null ? 0 : stockLeg(terms, targetQuote, ratioQuote);
|
|
152
|
+
total = cash == null || stock == null ? null : cash + stock;
|
|
101
153
|
}
|
|
102
|
-
|
|
103
|
-
|
|
104
|
-
|
|
105
|
-
|
|
106
|
-
|
|
107
|
-
|
|
154
|
+
return total != null && total > 0 ? total : null;
|
|
155
|
+
}
|
|
156
|
+
|
|
157
|
+
/**
|
|
158
|
+
* What the terms were worth each day since the announcement: flat for cash,
|
|
159
|
+
* the ratio times the paying listing's close for stock. An election draws
|
|
160
|
+
* the one leg its Offer is priced at (`leg`, from {@link electionLeg}), its
|
|
161
|
+
* stock leg in the target quote's currency as the Offer converts it.
|
|
162
|
+
*/
|
|
163
|
+
export function offerSeries(
|
|
164
|
+
deal: MnaDeal,
|
|
165
|
+
ratioCloses: readonly { date: Date; close: number }[],
|
|
166
|
+
days: readonly string[],
|
|
167
|
+
leg: "cash" | "stock" | null,
|
|
168
|
+
toQuote: (close: number) => number | null = (close) => close,
|
|
169
|
+
): Array<{ day: string; value: number }> {
|
|
170
|
+
const { cashPerShare, exchangeRatio, currency } = deal.terms;
|
|
171
|
+
if (cashPerShare == null && exchangeRatio == null) return [];
|
|
172
|
+
const pence = currency === "GBp" || currency === "GBX";
|
|
173
|
+
const cash = cashPerShare == null || leg === "stock" ? 0 : pence ? cashPerShare / 100 : cashPerShare;
|
|
174
|
+
const ratioByDay = new Map(ratioCloses.map((point) => [point.date.toISOString().slice(0, 10), point.close]));
|
|
175
|
+
const out: Array<{ day: string; value: number }> = [];
|
|
176
|
+
let lastRatio: number | null = null;
|
|
177
|
+
for (const day of days) {
|
|
178
|
+
if (day < deal.announced) continue;
|
|
179
|
+
if (exchangeRatio == null || leg === "cash") {
|
|
180
|
+
out.push({ day, value: cash });
|
|
181
|
+
continue;
|
|
182
|
+
}
|
|
183
|
+
const close = ratioByDay.get(day);
|
|
184
|
+
lastRatio = close == null ? lastRatio : toQuote(close) ?? lastRatio;
|
|
185
|
+
if (lastRatio != null) out.push({ day, value: cash + exchangeRatio * lastRatio });
|
|
108
186
|
}
|
|
109
|
-
return
|
|
187
|
+
return out;
|
|
110
188
|
}
|
|
111
189
|
|
|
112
190
|
export interface DealSpread {
|
|
@@ -26,7 +26,6 @@ import { usePlanAccess } from "../../../api-client/plan-access";
|
|
|
26
26
|
import { useAsyncResource, useAutoRefresh, usePaneSettingValue, usePluginPaneState, useShortcut } from "../../../public/react";
|
|
27
27
|
import { usePaneInstance } from "../../../state/app/context";
|
|
28
28
|
import { usePaneTickerIdentity } from "../../../state/hooks/pane-ticker";
|
|
29
|
-
import { listingIdentity } from "../shared/ticker-request";
|
|
30
29
|
import { blendHex } from "../../../theme/colors";
|
|
31
30
|
import { useThemeColors } from "../../../theme/theme-context";
|
|
32
31
|
import type { PaneProps, TickerResearchTabProps } from "../../../types/plugin";
|
|
@@ -42,6 +41,7 @@ import { MnaDealDetail, mnaDealTitle } from "./detail";
|
|
|
42
41
|
import { DistressBoard } from "./distress/pane";
|
|
43
42
|
import {
|
|
44
43
|
dealSpread,
|
|
44
|
+
dealsSymbol,
|
|
45
45
|
expectedCloseDate,
|
|
46
46
|
formatDealValue,
|
|
47
47
|
formatExpectedClose,
|
|
@@ -133,10 +133,11 @@ const MNA_TABS: { label: string; value: MnaTab }[] = [
|
|
|
133
133
|
|
|
134
134
|
/** `MA`, or `MA ACVA`. A link supplies the ticker; an older pane still has it in settings. */
|
|
135
135
|
export function MnaPane(props: PaneProps) {
|
|
136
|
-
const { symbol: bound } = usePaneTickerIdentity();
|
|
136
|
+
const { symbol: bound, ticker: boundTicker } = usePaneTickerIdentity();
|
|
137
137
|
const [ticker] = usePaneSettingValue("ticker", "");
|
|
138
138
|
const fromSettings = typeof ticker === "string" ? ticker.trim().toUpperCase() : "";
|
|
139
|
-
|
|
139
|
+
// Deals are filed under a listing's quote symbol (ATH.TO), not its bare symbol (ATH:TSX is not ATH).
|
|
140
|
+
const symbol = dealsSymbol(bound, boundTicker?.metadata.exchange) || fromSettings;
|
|
140
141
|
// One company's deals have no market-wide distress tab beside them.
|
|
141
142
|
if (symbol) return <MnaDealsView key={symbol} focused={props.focused} width={props.width} height={props.height} symbol={symbol} />;
|
|
142
143
|
return <MnaBoard focused={props.focused} width={props.width} height={props.height} />;
|
|
@@ -172,7 +173,7 @@ function MnaBoard({ focused, width, height }: { focused: boolean; width: number;
|
|
|
172
173
|
|
|
173
174
|
export function MnaTickerTab({ focused, width, height }: TickerResearchTabProps) {
|
|
174
175
|
const { ticker } = usePaneTickerIdentity();
|
|
175
|
-
const symbol = ticker?.metadata.ticker;
|
|
176
|
+
const symbol = dealsSymbol(ticker?.metadata.ticker, ticker?.metadata.exchange);
|
|
176
177
|
if (!symbol) return <EmptyState title="Select a ticker." />;
|
|
177
178
|
return <MnaDealsView key={symbol} focused={focused} width={width} height={height} symbol={symbol} />;
|
|
178
179
|
}
|
|
@@ -1,4 +1,3 @@
|
|
|
1
|
-
import type { CloudNewsListResponse } from "../../../api-client";
|
|
2
1
|
import type {
|
|
3
2
|
HeadlessPaneContext,
|
|
4
3
|
HeadlessPaneDefinition,
|
|
@@ -7,8 +6,10 @@ import type {
|
|
|
7
6
|
} from "../../../types/plugin";
|
|
8
7
|
import type { NewsArticle, NewsQuery } from "../../../news/types";
|
|
9
8
|
import {
|
|
10
|
-
|
|
9
|
+
coinNewsFallbackNotice,
|
|
11
10
|
mapCloudNewsArticle,
|
|
11
|
+
readCloudNews,
|
|
12
|
+
type CloudNewsRead,
|
|
12
13
|
} from "../../../sources/gloomberb-cloud/news";
|
|
13
14
|
import { parsePublicTickerKey } from "../../../utils/exchanges";
|
|
14
15
|
import { formatUtcSeconds } from "../../../utils/utc-time";
|
|
@@ -29,14 +30,14 @@ export interface NewsHeadlessDependencies {
|
|
|
29
30
|
loadNews(
|
|
30
31
|
query: NewsQuery,
|
|
31
32
|
context: HeadlessPaneContext,
|
|
32
|
-
): Promise<
|
|
33
|
+
): Promise<CloudNewsRead>;
|
|
33
34
|
now(): Date;
|
|
34
35
|
/** Whether the session has real-time news; without it the stories are held back. */
|
|
35
36
|
realtimeAccess?(): Promise<boolean | null>;
|
|
36
37
|
}
|
|
37
38
|
|
|
38
39
|
const defaultDependencies: NewsHeadlessDependencies = {
|
|
39
|
-
loadNews: (query, context) => context.apiClient
|
|
40
|
+
loadNews: (query, context) => readCloudNews(context.apiClient, query),
|
|
40
41
|
now: () => new Date(),
|
|
41
42
|
realtimeAccess: cloudRealtimeAccess,
|
|
42
43
|
};
|
|
@@ -71,7 +72,7 @@ function selectedSentiment(args: HeadlessPaneLoadArgs): string {
|
|
|
71
72
|
}
|
|
72
73
|
|
|
73
74
|
function projectNewsHeadless(
|
|
74
|
-
response:
|
|
75
|
+
response: CloudNewsRead,
|
|
75
76
|
args: HeadlessPaneLoadArgs,
|
|
76
77
|
now: Date,
|
|
77
78
|
realtime: boolean | null,
|
|
@@ -80,7 +81,7 @@ function projectNewsHeadless(
|
|
|
80
81
|
const minImportance = Number(args.options.minImportance ?? 0);
|
|
81
82
|
const limit = Number(args.options.limit ?? 50);
|
|
82
83
|
const matching = response.items
|
|
83
|
-
.map((item) => mapCloudNewsArticle(item, args.symbols[0]))
|
|
84
|
+
.map((item) => mapCloudNewsArticle(item, response.searchedFor ? undefined : args.symbols[0]))
|
|
84
85
|
.filter((article) => sentiment === "any" || article.sentiment === sentiment)
|
|
85
86
|
.filter((article) => article.importance >= minImportance)
|
|
86
87
|
.sort((left, right) => right.publishedAt.getTime() - left.publishedAt.getTime());
|
|
@@ -91,6 +92,10 @@ function projectNewsHeadless(
|
|
|
91
92
|
items,
|
|
92
93
|
// Dated by the newest story, held back for an account without real-time news.
|
|
93
94
|
freshness: cloudNewsFreshness(realtime),
|
|
95
|
+
// A coin pair no story is filed under shows the stories that mention the coin, and says so.
|
|
96
|
+
...(response.searchedFor && args.symbols[0]
|
|
97
|
+
? { notes: [coinNewsFallbackNotice(parsePublicTickerKey(args.symbols[0]).symbol, response.searchedFor)] }
|
|
98
|
+
: {}),
|
|
94
99
|
metadata: {
|
|
95
100
|
nextCursor: response.nextCursor,
|
|
96
101
|
sentiment,
|
|
@@ -98,6 +103,7 @@ function projectNewsHeadless(
|
|
|
98
103
|
total: matching.length,
|
|
99
104
|
returned: items.length,
|
|
100
105
|
truncated: items.length < matching.length || response.nextCursor != null,
|
|
106
|
+
...(response.searchedFor ? { searchedFor: response.searchedFor } : {}),
|
|
101
107
|
},
|
|
102
108
|
};
|
|
103
109
|
}
|
|
@@ -5,7 +5,8 @@ import { useArticleSummary, useResolvedEntryValue } from "../../../market-data/h
|
|
|
5
5
|
import { instrumentFromTicker } from "../../../market-data/request-types";
|
|
6
6
|
import { useCallback } from "react";
|
|
7
7
|
import { useDebouncedPluginPaneState, usePluginPaneState } from "../../runtime";
|
|
8
|
-
import { EmptyState, PaneStatusBody, QueryBar } from "../../../components";
|
|
8
|
+
import { EmptyState, PaneStatusBody, QueryBar, usePaneNoticeFooter } from "../../../components";
|
|
9
|
+
import { coinNewsFallbackNotice } from "../../../sources/gloomberb-cloud/news";
|
|
9
10
|
import { newsMuteSettingsDef, newsMutesApplyToFeed, useNewsMuteFilter } from "./wire/mutes";
|
|
10
11
|
import { newsListEmptyCopy } from "./wire/filter-articles";
|
|
11
12
|
import { NEWS_LIST_SEARCH_PLACEHOLDER, useNewsListSearch, useNewsListSearchHint } from "./wire/news/list-search";
|
|
@@ -45,6 +46,7 @@ function TickerNewsView({ width, height, focused }: { width: number; height: num
|
|
|
45
46
|
exchange: instrument.exchange,
|
|
46
47
|
tickerTier: "primary" as const,
|
|
47
48
|
limit: NEWS_ITEM_LIMIT,
|
|
49
|
+
...(ticker?.metadata.name ? { listingName: ticker.metadata.name } : {}),
|
|
48
50
|
} : null;
|
|
49
51
|
const newsState = useNewsArticles(newsQuery);
|
|
50
52
|
const loaded = usePersistedNewsArticles(
|
|
@@ -91,6 +93,13 @@ function TickerNewsView({ width, height, focused }: { width: number; height: num
|
|
|
91
93
|
}, [markArticleRead, popOutArticle, readableArticle]);
|
|
92
94
|
|
|
93
95
|
useNewsListSearchHint("ticker-news", focused && !detailOpen, search.focusSearch);
|
|
96
|
+
// A coin pair no story is filed under lists the stories that mention the coin; the footer says so.
|
|
97
|
+
const searchedFor = loaded[0]?.searchedFor;
|
|
98
|
+
usePaneNoticeFooter({
|
|
99
|
+
registrationId: "ticker-news-notices",
|
|
100
|
+
notices: searchedFor && instrument ? [coinNewsFallbackNotice(instrument.symbol, searchedFor)] : [],
|
|
101
|
+
focused,
|
|
102
|
+
});
|
|
94
103
|
useNewsArticleFooter({
|
|
95
104
|
registrationId: "news",
|
|
96
105
|
focused: listFocused,
|
|
@@ -92,6 +92,7 @@ const newsWirePanes: PluginModule["panes"] = [
|
|
|
92
92
|
{
|
|
93
93
|
id: NEWS_STORY_PANE_ID,
|
|
94
94
|
reportFreshness: NEWS_REPORT_FRESHNESS,
|
|
95
|
+
reportArgument: { kind: "free-text", placeholder: "story id", description: "The id of the story to open." },
|
|
95
96
|
name: "Story",
|
|
96
97
|
icon: "A",
|
|
97
98
|
component: NewsStoryPane,
|
|
@@ -147,8 +148,8 @@ const newsWirePaneTemplates: PluginModule["paneTemplates"] = [
|
|
|
147
148
|
id: "news-industry-pane",
|
|
148
149
|
paneId: "news-industry",
|
|
149
150
|
label: TOPIC_NEWS_TITLE,
|
|
150
|
-
description: "Market news by topic code (MNA, CB, ENERGY, REG, CRYPTO, EARN, IPO) or sector, and public fund letters (LTR)",
|
|
151
|
-
keywords: ["news", "industry", "sector", "topic", "ni", "mna", "central banks", "crypto", "ipo", "earnings", "regulation", "letters", "ltr", "fund letters", "investor letters"],
|
|
151
|
+
description: "Market news by topic code (MNA, CB, ENERGY, METALS, REG, CRYPTO, EARN, IPO) or sector, and public fund letters (LTR)",
|
|
152
|
+
keywords: ["news", "industry", "sector", "topic", "ni", "mna", "central banks", "metals", "precious metals", "crypto", "ipo", "earnings", "regulation", "letters", "ltr", "fund letters", "investor letters"],
|
|
152
153
|
shortcut: {
|
|
153
154
|
prefix: "NI",
|
|
154
155
|
argPlaceholder: "code",
|
|
@@ -7,6 +7,7 @@ import type {
|
|
|
7
7
|
CommandBarSearchProvider,
|
|
8
8
|
GloomPluginContext,
|
|
9
9
|
} from "../../../../../types/plugin";
|
|
10
|
+
import { abortable, settleWithin } from "../../../../../utils/async-deadline";
|
|
10
11
|
import { formatFeedTime } from "../../../../../utils/datetime-format";
|
|
11
12
|
import { logFailure } from "../../../../../utils/log-failure";
|
|
12
13
|
import { openNewsStoryPane } from "./pop-out";
|
|
@@ -54,10 +55,19 @@ export function matchLoadedStories(
|
|
|
54
55
|
.slice(0, limit);
|
|
55
56
|
}
|
|
56
57
|
|
|
58
|
+
/**
|
|
59
|
+
* How long a lookup waits for the feed to load before it answers with the
|
|
60
|
+
* stories the app already holds. The feed waits on its slowest source, so one
|
|
61
|
+
* feed that is down must not keep the command bar searching.
|
|
62
|
+
*/
|
|
63
|
+
const WARM_TIMEOUT_MS = 3_000;
|
|
64
|
+
|
|
57
65
|
interface StorySearchDeps {
|
|
58
66
|
getService(): NewsService | null;
|
|
59
67
|
isSignedIn(): boolean;
|
|
60
68
|
now(): number;
|
|
69
|
+
/** How long to wait for the feed to load. Default 3000. */
|
|
70
|
+
warmTimeoutMs?: number;
|
|
61
71
|
}
|
|
62
72
|
|
|
63
73
|
const defaultDeps: StorySearchDeps = {
|
|
@@ -66,22 +76,28 @@ const defaultDeps: StorySearchDeps = {
|
|
|
66
76
|
now: Date.now,
|
|
67
77
|
};
|
|
68
78
|
|
|
69
|
-
|
|
79
|
+
const warming = new WeakMap<NewsService, Promise<unknown>>();
|
|
70
80
|
|
|
71
81
|
/**
|
|
72
82
|
* Unless News Feed is open, the app may hold few stories or none, so a lookup
|
|
73
83
|
* first loads the latest feed News Feed reads (the same request, delayed when
|
|
74
84
|
* the account has no live news). The service keeps it for a while after, so
|
|
75
|
-
* later lookups reuse it instead of asking again.
|
|
85
|
+
* later lookups reuse it instead of asking again. The wait ends when the
|
|
86
|
+
* feed has loaded, the lookup is abandoned, or `timeoutMs` passes; a load
|
|
87
|
+
* still running then carries on for the next lookup.
|
|
76
88
|
*/
|
|
77
|
-
async function warmLatestStories(service: NewsService): Promise<void> {
|
|
89
|
+
async function warmLatestStories(service: NewsService, signal: AbortSignal, timeoutMs: number): Promise<void> {
|
|
78
90
|
if (service.getQueryState(NEWS_QUERY_PRESETS.feed).articles.length > 0) return;
|
|
79
|
-
|
|
80
|
-
|
|
81
|
-
.
|
|
82
|
-
|
|
83
|
-
|
|
84
|
-
|
|
91
|
+
let loading = warming.get(service);
|
|
92
|
+
if (!loading) {
|
|
93
|
+
loading = service.load(NEWS_QUERY_PRESETS.feed)
|
|
94
|
+
.catch(logFailure("news.command-bar-search", "Load news for command bar search failed", null))
|
|
95
|
+
.finally(() => {
|
|
96
|
+
warming.delete(service);
|
|
97
|
+
});
|
|
98
|
+
warming.set(service, loading);
|
|
99
|
+
}
|
|
100
|
+
await settleWithin(abortable(loading, signal, "News lookup abandoned"), timeoutMs);
|
|
85
101
|
}
|
|
86
102
|
|
|
87
103
|
/**
|
|
@@ -104,7 +120,7 @@ export function createLoadedStorySearchProvider(
|
|
|
104
120
|
if (deps.isSignedIn()) return [];
|
|
105
121
|
const service = deps.getService();
|
|
106
122
|
if (!service) return [];
|
|
107
|
-
await warmLatestStories(service);
|
|
123
|
+
await warmLatestStories(service, signal, deps.warmTimeoutMs ?? WARM_TIMEOUT_MS);
|
|
108
124
|
if (signal.aborted) return [];
|
|
109
125
|
const now = deps.now();
|
|
110
126
|
return matchLoadedStories(service.listArticles(), query).map((article) => ({
|
|
@@ -17,8 +17,9 @@ export type SectorNewsSelection = "all" | typeof SECTOR_NEWS_SECTORS[number];
|
|
|
17
17
|
|
|
18
18
|
/**
|
|
19
19
|
* NI codes, Bloomberg style: topics the service tags from a story's text and
|
|
20
|
-
* source (`NI MNA`), and the sectors NI always had (`NI TECH`). ENERGY
|
|
21
|
-
*
|
|
20
|
+
* source (`NI MNA`), and the sectors NI always had (`NI TECH`). ENERGY and
|
|
21
|
+
* METALS are topics, so they take their market's news from every sector:
|
|
22
|
+
* METALS is metal prices, futures and bullion, not a miner's releases. `LTR` is the one code that
|
|
22
23
|
* lists no stories: public fund and investor letters, as links.
|
|
23
24
|
*/
|
|
24
25
|
export interface NewsIndustryCode {
|
|
@@ -34,6 +35,7 @@ export const NEWS_INDUSTRY_CODES: readonly NewsIndustryCode[] = [
|
|
|
34
35
|
{ code: "MNA", label: "M&A", topic: "mna" },
|
|
35
36
|
{ code: "CB", label: "Central banks", topic: "cb" },
|
|
36
37
|
{ code: "ENERGY", label: "Energy", topic: "energy" },
|
|
38
|
+
{ code: "METALS", label: "Metals", topic: "metals" },
|
|
37
39
|
{ code: "REG", label: "Regulation", topic: "reg" },
|
|
38
40
|
{ code: "CRYPTO", label: "Crypto", topic: "crypto" },
|
|
39
41
|
{ code: "EARN", label: "Earnings", topic: "earn" },
|
|
@@ -58,6 +60,8 @@ const INDUSTRY_CODE_ALIASES: Record<string, string> = {
|
|
|
58
60
|
earnings: "EARN",
|
|
59
61
|
ipos: "IPO",
|
|
60
62
|
regulation: "REG",
|
|
63
|
+
metal: "METALS",
|
|
64
|
+
precious_metals: "METALS",
|
|
61
65
|
};
|
|
62
66
|
|
|
63
67
|
function industryKey(value: string): string {
|
|
@@ -14,10 +14,10 @@ export const rssCliCommand: CliCommandDef = {
|
|
|
14
14
|
},
|
|
15
15
|
execute: async (args, ctx) => {
|
|
16
16
|
const action = args[0] ?? "fetch";
|
|
17
|
-
if (action !== "fetch") ctx.fail("Usage:
|
|
17
|
+
if (action !== "fetch") ctx.fail("Usage: gloom rss fetch <url> [--name <label>]");
|
|
18
18
|
const rawArgs = args.slice(1);
|
|
19
19
|
const name = takeOption(rawArgs, "--name") ?? "RSS";
|
|
20
|
-
const url = requireArg(rawArgs[0], "Usage:
|
|
20
|
+
const url = requireArg(rawArgs[0], "Usage: gloom rss fetch <url> [--name <label>]", ctx);
|
|
21
21
|
const capability = createRssNewsCapability([{
|
|
22
22
|
id: "cli-feed",
|
|
23
23
|
url,
|
|
@@ -37,7 +37,7 @@ export const rssCliCommand: CliCommandDef = {
|
|
|
37
37
|
})) }, {
|
|
38
38
|
textColumns: [
|
|
39
39
|
{ key: "publishedAt", header: "Published" },
|
|
40
|
-
{ key: "source", header: "Source"
|
|
40
|
+
{ key: "source", header: "Source" },
|
|
41
41
|
{ key: "title", header: "Title" },
|
|
42
42
|
{ key: "url", header: "URL", optional: true },
|
|
43
43
|
{ key: "summary", header: "Summary", optional: true },
|
|
@@ -1,12 +1,14 @@
|
|
|
1
1
|
import { apiClient } from "../../../api-client";
|
|
2
|
-
import { withCliServices, withConfigData } from "../../../cli/scoped-context";
|
|
2
|
+
import { withCliServices, withConfigData, withMarketData } from "../../../cli/scoped-context";
|
|
3
3
|
import type { CliServicesContext } from "../../../cli/types";
|
|
4
4
|
import { CLI_COMMAND_GROUPS } from "../../../cli/help";
|
|
5
5
|
import { dryRunNote } from "../../../cli/helpers";
|
|
6
6
|
import { requireArg, takeOption } from "../../../cli/commands/command-utils";
|
|
7
7
|
import { EXCHANGE_OPTION, listingReadNotes, requireListingArg } from "../../../cli/listing-arg";
|
|
8
|
+
import { isNotATickerMessage } from "../../../cli/not-a-ticker";
|
|
9
|
+
import { requireQuotedListing } from "../../../cli/quote-answer";
|
|
8
10
|
import { createPluginPersistence } from "../../plugin-persistence";
|
|
9
|
-
import type {
|
|
11
|
+
import type { BuiltinCliCommandDef } from "../../../cli/command-options";
|
|
10
12
|
import { cliStyles } from "../../../utils/cli-output";
|
|
11
13
|
import { errorMessage } from "../../../utils/errors";
|
|
12
14
|
import { logFailure } from "../../../utils/log-failure";
|
|
@@ -15,9 +17,11 @@ import { describeExportSkip, exportNotesToDirectory, type NotesExportSource } fr
|
|
|
15
17
|
import { NotesFiles } from "./files";
|
|
16
18
|
import { CloudNotesStore } from "./store";
|
|
17
19
|
|
|
18
|
-
export const notesCliCommand:
|
|
20
|
+
export const notesCliCommand: BuiltinCliCommandDef = {
|
|
19
21
|
name: "notes",
|
|
20
22
|
description: "Read, write, or export ticker notes",
|
|
23
|
+
// A note's text is saved as typed, and an export's folder is a path; the symbol is read as any other.
|
|
24
|
+
keepsArgAsTyped: ([action], index) => (action === "set" && index >= 2) || (action === "export" && index >= 1),
|
|
21
25
|
help: {
|
|
22
26
|
group: CLI_COMMAND_GROUPS.portfolios,
|
|
23
27
|
usage: ["notes show <symbol>", "notes set <symbol> <text...>", "notes delete <symbol>", "notes quick list", "notes export [dir]"],
|
|
@@ -28,13 +32,43 @@ export const notesCliCommand: CliCommandDef = {
|
|
|
28
32
|
const args = [...rawArgs];
|
|
29
33
|
const exchange = takeOption(args, "--exchange");
|
|
30
34
|
// A note belongs to one listing: SAN:EPA, or SAN with --exchange EPA.
|
|
31
|
-
// What a typed listing was read as (7203:TSE as 7203:JPX) is said beside the note.
|
|
35
|
+
// What a typed listing was read as (7203:TSE as 7203:JPX, Apple as AAPL) is said beside the note.
|
|
32
36
|
let read: { warnings?: string[] } = {};
|
|
33
|
-
const
|
|
34
|
-
|
|
35
|
-
|
|
36
|
-
|
|
37
|
-
|
|
37
|
+
const said = (warnings: string[]) => {
|
|
38
|
+
if (warnings.length > 0) read = { warnings };
|
|
39
|
+
};
|
|
40
|
+
/**
|
|
41
|
+
* The file a note of the symbol typed is kept in, the same for show, set
|
|
42
|
+
* and delete. A note already kept under what was typed is the one, so a
|
|
43
|
+
* note written before names were read (APPLE.md) or for a symbol that
|
|
44
|
+
* stopped trading stays reachable. Otherwise the symbol is read as
|
|
45
|
+
* `quote` reads it (`requireQuotedListing`): a company's name is its
|
|
46
|
+
* listing (`Apple` is AAPL, under the bare symbol as the app keeps a
|
|
47
|
+
* ticker it was not given a venue for), and a pair its listing
|
|
48
|
+
* (USDNGN=X). With `refuse`, a definite "Not a ticker" fails the command
|
|
49
|
+
* with `quote`'s search hint, so no note is written for a symbol that
|
|
50
|
+
* does not exist. Any other failure (offline, the data service down, a
|
|
51
|
+
* symbol with no quote) keeps what was typed, as does `lookUp: false`,
|
|
52
|
+
* which opens no data source.
|
|
53
|
+
*/
|
|
54
|
+
const noteSymbol = async (usage: string, notes: NotesFiles, options: { refuse?: boolean; lookUp?: boolean } = {}) => {
|
|
55
|
+
const raw = requireArg(args[1], usage, ctx);
|
|
56
|
+
const typed = await requireListingArg(raw, exchange, ctx);
|
|
57
|
+
const asTyped = () => {
|
|
58
|
+
said(listingReadNotes(typed));
|
|
59
|
+
return typed.key;
|
|
60
|
+
};
|
|
61
|
+
if ((await notes.load(typed.key).catch(logFailure("notes.cli", "Read the note kept under a typed symbol failed", ""))).trim()) return asTyped();
|
|
62
|
+
if (options.lookUp === false) return asTyped();
|
|
63
|
+
try {
|
|
64
|
+
const quoted = await withMarketData(ctx, (market) => requireQuotedListing(raw, exchange, market, ctx, `notes ${args[0] ?? "show"}`));
|
|
65
|
+
said(quoted.notes);
|
|
66
|
+
return typed.exchange ? quoted.listing.key : quoted.listing.symbol;
|
|
67
|
+
} catch (error) {
|
|
68
|
+
if (!isNotATickerMessage(errorMessage(error))) logFailure("notes.cli", "Read a note's symbol as quote does failed")(error);
|
|
69
|
+
else if (options.refuse) throw error;
|
|
70
|
+
return asTyped();
|
|
71
|
+
}
|
|
38
72
|
};
|
|
39
73
|
await withConfigData(ctx, async (config) => {
|
|
40
74
|
const notes = new NotesFiles(config.dataDir);
|
|
@@ -80,7 +114,7 @@ export const notesCliCommand: CliCommandDef = {
|
|
|
80
114
|
});
|
|
81
115
|
return;
|
|
82
116
|
}
|
|
83
|
-
warnings.push(...result.skipped.map(describeExportSkip));
|
|
117
|
+
warnings.push(...(result.warnings ?? []), ...result.skipped.map(describeExportSkip));
|
|
84
118
|
ctx.printResult({
|
|
85
119
|
data: {
|
|
86
120
|
dir: result.dir,
|
|
@@ -96,20 +130,21 @@ export const notesCliCommand: CliCommandDef = {
|
|
|
96
130
|
}
|
|
97
131
|
if (action === "quick") {
|
|
98
132
|
const subaction = args[1] ?? "list";
|
|
99
|
-
if (subaction !== "list") ctx.fail("Usage:
|
|
133
|
+
if (subaction !== "list") ctx.fail("Usage: gloom notes quick list");
|
|
100
134
|
const entries = await notes.loadQuickNotesIndex();
|
|
101
135
|
ctx.printResult({ data: entries }, { empty: "No quick notes." });
|
|
102
136
|
return;
|
|
103
137
|
}
|
|
104
138
|
if (action === "show") {
|
|
105
|
-
const symbol = await noteSymbol("Usage:
|
|
139
|
+
const symbol = await noteSymbol("Usage: gloom notes show <symbol>", notes);
|
|
106
140
|
ctx.printResult({ data: { symbol, text: await notes.load(symbol) }, ...read }, {
|
|
107
141
|
text: (data) => data.text?.trim() ? data.text.trimEnd() : cliStyles.muted(`No note for ${symbol}.`),
|
|
108
142
|
});
|
|
109
143
|
return;
|
|
110
144
|
}
|
|
111
145
|
if (action === "set") {
|
|
112
|
-
|
|
146
|
+
// A dry run looks nothing up: it says the note it would write under the symbol as typed.
|
|
147
|
+
const symbol = await noteSymbol("Usage: gloom notes set <symbol> <text...>", notes, { refuse: true, lookUp: !ctx.cliOptions.dryRun });
|
|
113
148
|
const text = args.slice(2).join(" ");
|
|
114
149
|
if (!ctx.cliOptions.dryRun) await notes.save(symbol, text);
|
|
115
150
|
ctx.printResult({ data: { changed: !ctx.cliOptions.dryRun, dryRun: ctx.cliOptions.dryRun, symbol, bytes: text.length }, ...read }, {
|
|
@@ -118,7 +153,7 @@ export const notesCliCommand: CliCommandDef = {
|
|
|
118
153
|
return;
|
|
119
154
|
}
|
|
120
155
|
if (action === "delete" || action === "rm") {
|
|
121
|
-
const symbol = await noteSymbol("Usage:
|
|
156
|
+
const symbol = await noteSymbol("Usage: gloom notes delete <symbol>", notes);
|
|
122
157
|
const existed = await notes.load(symbol).then((text) => !!text?.trim(), () => {
|
|
123
158
|
// Intentional ignore: an unreadable note is still deleted, so the message says it existed.
|
|
124
159
|
return true;
|
|
@@ -131,7 +166,7 @@ export const notesCliCommand: CliCommandDef = {
|
|
|
131
166
|
});
|
|
132
167
|
return;
|
|
133
168
|
}
|
|
134
|
-
ctx.fail("Usage:
|
|
169
|
+
ctx.fail("Usage: gloom notes show|set|delete|quick|export");
|
|
135
170
|
});
|
|
136
171
|
},
|
|
137
172
|
};
|
|
@@ -1,4 +1,5 @@
|
|
|
1
1
|
import { errorMessage } from "../../../utils/errors";
|
|
2
|
+
import { logFailure } from "../../../utils/log-failure";
|
|
2
3
|
import type { NoteFileEntry, QuickNoteEntry } from "./files";
|
|
3
4
|
import type { NotesStore } from "./store";
|
|
4
5
|
import { noteOwnerKey, splitNoteKey } from "./store";
|
|
@@ -25,6 +26,8 @@ export interface NotesExportResult {
|
|
|
25
26
|
/** The sources whose notes were written, in the order given. */
|
|
26
27
|
exported: string[];
|
|
27
28
|
skipped: NotesExportSkip[];
|
|
29
|
+
/** Notes were written, but some descriptive metadata could not be read. */
|
|
30
|
+
warnings?: string[];
|
|
28
31
|
}
|
|
29
32
|
|
|
30
33
|
function safeFileName(value: string): string {
|
|
@@ -46,15 +49,21 @@ export async function exportNotesToDirectory(
|
|
|
46
49
|
let files = 0;
|
|
47
50
|
const exported: string[] = [];
|
|
48
51
|
const skipped: NotesExportResult["skipped"] = [];
|
|
52
|
+
const warnings: string[] = [];
|
|
49
53
|
for (const source of sources) {
|
|
50
54
|
const folder = sources.length > 1 ? `${dir}/${safeFileName(source.label)}` : dir;
|
|
51
55
|
let entries: NoteFileEntry[];
|
|
52
56
|
let quick: QuickNoteEntry[];
|
|
57
|
+
let titlesWarning: string | null = null;
|
|
53
58
|
const unreadable: Array<{ key: string; error: unknown }> = [];
|
|
54
59
|
try {
|
|
55
60
|
[entries, quick] = await Promise.all([
|
|
56
61
|
source.store.list({ strict: true, skipped: (key, error) => unreadable.push({ key, error }) }),
|
|
57
|
-
source.store.loadQuickNotesIndex()
|
|
62
|
+
source.store.loadQuickNotesIndex({ strict: true }).catch((error) => {
|
|
63
|
+
logFailure("notes.export", "Read quick note titles for export failed")(error);
|
|
64
|
+
titlesWarning = `Quick notes from ${source.label} were exported using ids because their titles could not be read (${errorMessage(error)}).`;
|
|
65
|
+
return [];
|
|
66
|
+
}),
|
|
58
67
|
]);
|
|
59
68
|
} catch (error) {
|
|
60
69
|
skipped.push({ label: source.label, reason: errorMessage(error) });
|
|
@@ -74,9 +83,10 @@ export async function exportNotesToDirectory(
|
|
|
74
83
|
await writeFile(path, entry.text, "utf-8");
|
|
75
84
|
files += 1;
|
|
76
85
|
}
|
|
86
|
+
if (titlesWarning && entries.some((entry) => splitNoteKey(entry.key).kind === "quick")) warnings.push(titlesWarning);
|
|
77
87
|
exported.push(source.label);
|
|
78
88
|
}
|
|
79
|
-
return { dir, files, exported, skipped };
|
|
89
|
+
return { dir, files, exported, skipped, ...(warnings.length > 0 ? { warnings } : {}) };
|
|
80
90
|
}
|
|
81
91
|
|
|
82
92
|
/** One line per skip, as `notes export` warns and the Export Notes command reports. */
|
|
@@ -86,12 +96,13 @@ export function describeExportSkip(skip: NotesExportSkip): string {
|
|
|
86
96
|
: `Skipped the ${skip.label} note ${skip.note}: it could not be read (${skip.reason}).`;
|
|
87
97
|
}
|
|
88
98
|
|
|
89
|
-
/** The Export Notes command's notice: the count, then what was skipped. */
|
|
99
|
+
/** The Export Notes command's notice: the count, then warnings and what was skipped. */
|
|
90
100
|
export function exportNotice(result: NotesExportResult): { body: string; type: "success" | "error" } {
|
|
91
101
|
const exported = `Exported ${result.files} ${result.files === 1 ? "note" : "notes"} to ${result.dir}`;
|
|
92
|
-
|
|
93
|
-
|
|
94
|
-
const
|
|
102
|
+
const issues = [...(result.warnings ?? []), ...result.skipped.map(describeExportSkip)];
|
|
103
|
+
if (issues.length === 0) return { body: exported, type: "success" };
|
|
104
|
+
const shown = issues.slice(0, 3);
|
|
105
|
+
const more = issues.length - shown.length;
|
|
95
106
|
return {
|
|
96
107
|
body: [`${exported}.`, ...shown, ...(more > 0 ? [`${more} more could not be read.`] : [])].join(" "),
|
|
97
108
|
type: "error",
|