gloomberb 0.18.3 → 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/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 +84 -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 +22 -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 +21 -4
- 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/themes.ts +7 -1
- package/src/api-client/types.ts +90 -2
- 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/star-prompt/status-line.tsx +2 -2
- package/src/architecture/core-builtin-allowlist.json +5 -2
- 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 +1117 -264
- 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 +192 -47
- 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 +19 -13
- 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 +24 -18
- package/src/cli/known-gaps.ts +118 -25
- package/src/cli/listing-arg.ts +300 -41
- package/src/cli/name-entries.ts +30 -18
- 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 +75 -20
- package/src/cli/pane-functions/catalog.ts +24 -23
- package/src/cli/pane-functions/discovery.ts +1 -1
- package/src/cli/pane-functions/dom.ts +10 -7
- 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 +24 -11
- package/src/cli/pane-functions/index.ts +18 -16
- 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 +47 -10
- 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 +61 -16
- package/src/cli/restore-plugins.ts +29 -14
- package/src/cli/result.ts +111 -22
- 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 +198 -68
- 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 +373 -16
- package/src/components/chart/composite/interactions.ts +7 -2
- 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 +305 -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 +13 -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/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/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 +12 -6
- package/src/components/layout/header.tsx +7 -6
- 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/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/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 +29 -12
- package/src/i18n/ja.ts +29 -12
- package/src/i18n/ko.ts +29 -12
- package/src/i18n/zh-cn.ts +29 -12
- package/src/i18n/zh-tw.ts +29 -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 +29 -19
- 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 +107 -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 +76 -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 +97 -36
- package/src/plugins/builtin/attention/pane.tsx +6 -2
- 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 +6 -3
- 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 +22 -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 +110 -23
- package/src/plugins/builtin/broker-trading/ticket-parts.tsx +36 -7
- package/src/plugins/builtin/broker-trading/ticket.tsx +112 -31
- 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 +25 -12
- 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/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 +6 -8
- 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 +127 -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 +11 -4
- package/src/plugins/builtin/company-attention/app-rank.tsx +7 -5
- 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 +79 -23
- 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 +1 -1
- 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 +5 -3
- 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 +3 -2
- 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/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/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 +18 -11
- 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 +68 -6
- package/src/plugins/builtin/equity-screener/live.ts +1 -1
- package/src/plugins/builtin/equity-screener/model.ts +6 -0
- package/src/plugins/builtin/equity-screener/pane.tsx +45 -10
- 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 +6 -1
- 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/headless.ts +9 -4
- 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 +13 -1
- package/src/plugins/builtin/holders/format.ts +28 -17
- package/src/plugins/builtin/holders/headless.ts +46 -7
- 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/treemap.tsx +2 -2
- package/src/plugins/builtin/insider/headless.ts +1 -1
- package/src/plugins/builtin/insider/signals-client.ts +1 -1
- package/src/plugins/builtin/insider/signals.tsx +1 -1
- 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/headless.ts +4 -4
- 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 +10 -4
- 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 +33 -19
- 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 +29 -8
- 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 +49 -14
- package/src/plugins/builtin/openfda/pane.tsx +1 -1
- package/src/plugins/builtin/options/carry.ts +2 -2
- package/src/plugins/builtin/options/index.tsx +1 -1
- package/src/plugins/builtin/options/view.tsx +10 -10
- package/src/plugins/builtin/options-calculator/headless.ts +46 -7
- package/src/plugins/builtin/options-scenario/client.ts +123 -28
- 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 +36 -15
- 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 +9 -5
- 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 +143 -59
- package/src/plugins/builtin/portfolio-list/cli/bulk-symbols.ts +72 -24
- 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 +4 -1
- 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 +8 -1
- 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/model.ts +6 -2
- package/src/plugins/builtin/risk-factors/index.tsx +2 -2
- package/src/plugins/builtin/scanner/lock-note.ts +1 -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 +2 -1
- 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-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 +21 -0
- package/src/plugins/builtin/shared/series-cache.ts +2 -0
- package/src/plugins/builtin/shared/ticker-surface.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/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 +5 -4
- package/src/plugins/builtin/vol-surface/headless.ts +12 -3
- package/src/plugins/builtin/vol-surface/model.ts +4 -2
- 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/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/styles.css +76 -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/desktop/backend-requests.ts +3 -0
- package/src/renderers/electrobun/bun/desktop/backend.ts +46 -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/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 +5 -5
- package/src/renderers/electrobun/view/remote/asset-data-client.ts +1 -1
- 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 +1 -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 +32 -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/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 +17 -4
- 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 +210 -33
- package/src/tickers/index-roots.ts +47 -0
- package/src/tickers/instrument-label.ts +5 -1
- 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 +14 -0
- package/src/types/exchange-rate.ts +6 -0
- package/src/types/financials.ts +104 -7
- package/src/types/headless.ts +76 -6
- package/src/types/instrument.ts +3 -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/index.ts +10 -5
- 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-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 +3 -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
package/src/cli/report-tables.ts
CHANGED
|
@@ -57,6 +57,12 @@ export interface CliReportColumn<Row = Record<string, unknown>> {
|
|
|
57
57
|
format?: (value: unknown, row: Row) => string;
|
|
58
58
|
/** The row field naming the unit of a number in this column; the number then exports as it is, with that unit. */
|
|
59
59
|
unitKey?: string;
|
|
60
|
+
/**
|
|
61
|
+
* With `unitKey`: the unit always goes to a `<header> unit` column beside
|
|
62
|
+
* the figures, never into the header, so the header is the same whichever
|
|
63
|
+
* rows loaded (a market cap in one currency for some peers, in another for others).
|
|
64
|
+
*/
|
|
65
|
+
unitColumn?: boolean;
|
|
60
66
|
}
|
|
61
67
|
|
|
62
68
|
/** A label/value line of a report. `unit` names the unit of a numeric `value` when `formatted` cannot say it. */
|
|
@@ -83,6 +89,8 @@ interface ResolvedColumn {
|
|
|
83
89
|
cells: ResolvedCell[];
|
|
84
90
|
/** The unit the column draws its numbers in, for a table with no rows to say it. */
|
|
85
91
|
unit?: string;
|
|
92
|
+
/** The unit always has a column of its own (`unitColumn`). */
|
|
93
|
+
unitColumn?: boolean;
|
|
86
94
|
}
|
|
87
95
|
|
|
88
96
|
const BLANK = { kind: "blank" } as const;
|
|
@@ -318,7 +326,7 @@ function rowUnits(columns: readonly ResolvedColumn[], mixed: readonly boolean[],
|
|
|
318
326
|
*/
|
|
319
327
|
function assembleTable(title: string, columns: readonly ResolvedColumn[], rowCount: number, status?: StatusColumn): CliReportTable {
|
|
320
328
|
const units = columns.map((column) => rowCount === 0 && column.unit != null ? new Set([column.unit]) : numberUnits(column.cells));
|
|
321
|
-
const mixed = units.map((columnUnits) => columnUnits.size > 1);
|
|
329
|
+
const mixed = units.map((columnUnits, index) => columnUnits.size > 1 || columns[index]!.unitColumn === true);
|
|
322
330
|
const byRow = mixed.some(Boolean) ? rowUnits(columns, mixed, rowCount) : null;
|
|
323
331
|
const layout = columns.flatMap((column, index) => {
|
|
324
332
|
const columnUnits = units[index]!;
|
|
@@ -381,7 +389,9 @@ const EMPTY_ROW: unknown = (() => {
|
|
|
381
389
|
* plain figure), read from what its format draws for one; null when it draws
|
|
382
390
|
* no figure for one, passes the value through as it is, or throws.
|
|
383
391
|
*/
|
|
384
|
-
function drawnUnit<Row>(column: CliReportColumn<Row>, row: Row): string | null {
|
|
392
|
+
function drawnUnit<Row>(column: CliReportColumn<Row>, row: Row, rowUnitKey?: string): string | null {
|
|
393
|
+
// A figure in the row's own unit is bare: the row's `currency_or_unit` names it.
|
|
394
|
+
if (rowUnitKey && column.unitKey === rowUnitKey) return "";
|
|
385
395
|
const unit = column.unitKey ? (row as Record<string, unknown> | undefined)?.[column.unitKey] : undefined;
|
|
386
396
|
if (typeof unit === "string" && unit) return unit;
|
|
387
397
|
if (!column.format) return null;
|
|
@@ -438,29 +448,36 @@ const IDENTIFIER_KEY = /^(?:id|cik|code|cusip|figi|isin|symbol|ticker)$|(?:Id|Ci
|
|
|
438
448
|
* when one of its columns draws figures through a format, read from the
|
|
439
449
|
* columns alone so it is there with or without rows, and a table of text has
|
|
440
450
|
* none; beside a column of its own named Status it is `value_status`.
|
|
451
|
+
* `rowUnitKey` is the row field its `currency_or_unit` cell is read from: a
|
|
452
|
+
* column whose `unitKey` is that field exports its figures bare under its own
|
|
453
|
+
* header (`Last`, never `Last ($)` beside a franc), each row's unit named there.
|
|
441
454
|
*/
|
|
442
455
|
export function exportRowsTable<Row extends Record<string, unknown>>(
|
|
443
456
|
title: string,
|
|
444
457
|
columns: readonly CliReportColumn<Row>[],
|
|
445
458
|
rows: readonly Row[],
|
|
446
|
-
{ status = false }: { status?: boolean } = {},
|
|
459
|
+
{ status = false, rowUnitKey }: { status?: boolean; rowUnitKey?: string } = {},
|
|
447
460
|
): CliReportTable {
|
|
448
461
|
const reasons = rows.map((): Array<{ header: string; text: string }> => []);
|
|
449
462
|
const units = columns.map(columnUnit);
|
|
450
463
|
// Decided by the columns alone, so a table has the column, or not, whatever rows it has.
|
|
451
464
|
const withStatus = status && units.some((unit) => unit != null);
|
|
452
465
|
const resolved = columns.map((column, columnIndex): ResolvedColumn => {
|
|
453
|
-
const rowUnits = rows.map((row) => drawnUnit(column, row));
|
|
466
|
+
const rowUnits = rows.map((row) => drawnUnit(column, row, rowUnitKey));
|
|
454
467
|
const values = rows.map((row) => (row as Record<string, unknown> | undefined)?.[column.key]);
|
|
468
|
+
const inRowUnit = !!rowUnitKey && column.unitKey === rowUnitKey;
|
|
455
469
|
const { header, cells } = resolveColumn(
|
|
456
470
|
column.header,
|
|
457
471
|
rows.map((row, index): Cell => {
|
|
458
472
|
const value = values[index];
|
|
459
473
|
const unit = column.unitKey ? (row as Record<string, unknown> | undefined)?.[column.unitKey] : undefined;
|
|
460
|
-
|
|
461
|
-
|
|
474
|
+
const drawn = column.format ? column.format(value, row) : null;
|
|
475
|
+
// A figure the text leaves out of this row (another session's print) is not one of its figures.
|
|
476
|
+
const left = drawn != null && readDisplay(drawn) === BLANK_DISPLAY;
|
|
477
|
+
if (!left && typeof value === "number" && Number.isFinite(value) && (inRowUnit || (typeof unit === "string" && unit))) {
|
|
478
|
+
return { kind: "number", value: exportNumber(value), unit: inRowUnit ? "" : unit as string };
|
|
462
479
|
}
|
|
463
|
-
return exportCell(value,
|
|
480
|
+
return exportCell(value, drawn, column.key);
|
|
464
481
|
}),
|
|
465
482
|
!IDENTIFIER_KEY.test(column.key),
|
|
466
483
|
);
|
|
@@ -478,7 +495,8 @@ export function exportRowsTable<Row extends Record<string, unknown>>(
|
|
|
478
495
|
}),
|
|
479
496
|
};
|
|
480
497
|
const unit = units[columnIndex];
|
|
481
|
-
|
|
498
|
+
const withUnit = unit == null ? table : { ...table, unit };
|
|
499
|
+
return column.unitColumn && column.unitKey && !inRowUnit ? { ...withUnit, unitColumn: true } : withUnit;
|
|
482
500
|
});
|
|
483
501
|
const statusColumn = withStatus ? {
|
|
484
502
|
header: columns.some((column) => column.header.trim().toLowerCase() === "status") ? "value_status" : "status",
|
|
@@ -552,18 +570,33 @@ function sectionList(tables: readonly CliReportTable[]): string {
|
|
|
552
570
|
}
|
|
553
571
|
|
|
554
572
|
/**
|
|
555
|
-
* `--section
|
|
556
|
-
*
|
|
573
|
+
* The table `--section` names by title, in any case: the one titled so, else
|
|
574
|
+
* the one whose title starts with it, as a title that carries its date does
|
|
575
|
+
* (`Strikes` for `Strikes · Oct 30 '26`). A start several titles share picks
|
|
576
|
+
* none.
|
|
577
|
+
*/
|
|
578
|
+
function sectionByTitle(tables: readonly CliReportTable[], wanted: string): CliReportTable | undefined {
|
|
579
|
+
const name = wanted.toLowerCase();
|
|
580
|
+
const titles = tables.map((table) => table.title.trim().toLowerCase());
|
|
581
|
+
const exact = titles.indexOf(name);
|
|
582
|
+
if (exact >= 0) return tables[exact];
|
|
583
|
+
const starting = tables.filter((_, index) => titles[index]!.startsWith(name));
|
|
584
|
+
if (starting.length > 1) {
|
|
585
|
+
throw new Error(`"${wanted}" starts more than one section: ${starting.map((table) => table.title).join(", ")}. Give more of the title, or its number.`);
|
|
586
|
+
}
|
|
587
|
+
return starting[0];
|
|
588
|
+
}
|
|
589
|
+
|
|
590
|
+
/**
|
|
591
|
+
* `--section`: one table, by its title or the start of it (any case), or its
|
|
592
|
+
* 1-based position. Without a selector the report keeps every table.
|
|
557
593
|
*/
|
|
558
594
|
export function selectReportTables(report: CliReportTables, selector: string | true | undefined): CliReportTables {
|
|
559
595
|
if (selector === undefined) return report;
|
|
560
596
|
if (selector === true || !selector.trim()) throw new Error("--section needs a section title or number.");
|
|
561
597
|
const wanted = selector.trim();
|
|
562
598
|
if (report.tables.length === 0) throw new Error(`No section "${wanted}": this report has no tables.`);
|
|
563
|
-
const
|
|
564
|
-
? Number(wanted) - 1
|
|
565
|
-
: report.tables.findIndex((table) => table.title.trim().toLowerCase() === wanted.toLowerCase());
|
|
566
|
-
const table = report.tables[index];
|
|
599
|
+
const table = /^\d+$/.test(wanted) ? report.tables[Number(wanted) - 1] : sectionByTitle(report.tables, wanted);
|
|
567
600
|
if (!table) throw new Error(`No section "${wanted}". Sections: ${sectionList(report.tables)}.`);
|
|
568
601
|
return { ...report, tables: [table] };
|
|
569
602
|
}
|
|
@@ -582,7 +615,10 @@ function csvLine(row: readonly unknown[]): string {
|
|
|
582
615
|
|
|
583
616
|
/**
|
|
584
617
|
* A table with the fixed columns after its own, every row naming what it is
|
|
585
|
-
* and the source and as-of the footer cites. A
|
|
618
|
+
* and the source and as-of the footer cites. A fixed column the table already
|
|
619
|
+
* has under the same name is left out, so its own per-row values stay the
|
|
620
|
+
* only ones (CBR's `source` and `as_of`) and a reader keyed by name finds one
|
|
621
|
+
* column. A table without columns stays empty.
|
|
586
622
|
*/
|
|
587
623
|
function identifiedTable(table: CliReportTable, report: CliReportTables, freshness: ReportFreshness | undefined): CliReportTable {
|
|
588
624
|
if (!freshness || table.columns.length === 0) return table;
|
|
@@ -592,7 +628,16 @@ function identifiedTable(table: CliReportTable, report: CliReportTables, freshne
|
|
|
592
628
|
const own = table.rowIdentities?.[index];
|
|
593
629
|
return own ? exportIdentityCells(freshness, { ...identity, ...own }) : cells;
|
|
594
630
|
};
|
|
595
|
-
|
|
631
|
+
const added = EXPORT_IDENTITY_COLUMNS.flatMap((column, index) => table.columns.includes(column) ? [] : [index]);
|
|
632
|
+
if (added.length === 0) return table;
|
|
633
|
+
return {
|
|
634
|
+
...table,
|
|
635
|
+
columns: [...table.columns, ...added.map((index) => EXPORT_IDENTITY_COLUMNS[index]!)],
|
|
636
|
+
rows: table.rows.map((row, index) => {
|
|
637
|
+
const identityCells = rowCells(index);
|
|
638
|
+
return [...row, ...added.map((column) => identityCells[column]!)];
|
|
639
|
+
}),
|
|
640
|
+
};
|
|
596
641
|
}
|
|
597
642
|
|
|
598
643
|
/**
|
|
@@ -1,8 +1,10 @@
|
|
|
1
1
|
import { saveConfig } from "../data/config/store";
|
|
2
2
|
import { loadCliConfigIfAvailable } from "./context";
|
|
3
3
|
import { getPluginsDir } from "../plugins/loader";
|
|
4
|
-
import { seedExtractedPlugins } from "../plugins/extracted-plugins";
|
|
4
|
+
import { pluginSeedFailure, pluginSeedNotice, samePluginSeedFailure, seedExtractedPlugins } from "../plugins/extracted-plugins";
|
|
5
|
+
import { setPluginSeedNotice } from "../plugins/seed-notice";
|
|
5
6
|
import { debugLog } from "../utils/debug-log";
|
|
7
|
+
import type { AppConfig } from "../types/config";
|
|
6
8
|
|
|
7
9
|
const log = debugLog.createLogger("plugin-seed");
|
|
8
10
|
|
|
@@ -10,39 +12,52 @@ const log = debugLog.createLogger("plugin-seed");
|
|
|
10
12
|
* Reinstalls plugins that moved out of this repository into their own.
|
|
11
13
|
*
|
|
12
14
|
* Runs before the plugin catalog is read so a restored plugin is available in
|
|
13
|
-
* the same session, and
|
|
14
|
-
* normally and try again next time
|
|
15
|
+
* the same session, and never blocks or prints: an offline launch should
|
|
16
|
+
* start normally and try again next time. What it could not install becomes
|
|
17
|
+
* one notice the app shows once it is up (`setPluginSeedNotice`), saying why
|
|
18
|
+
* when git is missing, and `doctor` names the plugins.
|
|
15
19
|
*
|
|
16
|
-
* Returns the seeded ids so a caller that
|
|
17
|
-
* can adopt
|
|
18
|
-
* this it would keep an object
|
|
19
|
-
* overwrite the record on the next save.
|
|
20
|
+
* Returns what it recorded (the seeded ids, and what failed) so a caller that
|
|
21
|
+
* already holds the config in memory can adopt it. The desktop loads its
|
|
22
|
+
* config before restoring, and without this it would keep an object one
|
|
23
|
+
* launch stale and overwrite the record on the next save.
|
|
20
24
|
*/
|
|
21
|
-
export async function restoreExtractedPlugins(): Promise<
|
|
25
|
+
export async function restoreExtractedPlugins(): Promise<Pick<AppConfig, "seededPlugins" | "pluginSeedFailure"> | null> {
|
|
22
26
|
try {
|
|
23
27
|
const config = await loadCliConfigIfAvailable();
|
|
24
28
|
// No data directory yet means a first run: there is nothing to restore.
|
|
25
29
|
if (!config) return null;
|
|
26
|
-
// Through the registry like `
|
|
30
|
+
// Through the registry like `gloom install`: the reviewed commit, and
|
|
27
31
|
// nothing on a Gloomberb too old for it. That failure is retried at the
|
|
28
32
|
// next launch, by when this Gloomberb has usually updated itself. The
|
|
29
33
|
// registry is read once, and only when something is left to install.
|
|
30
|
-
|
|
34
|
+
// Quiet: the terminal app is about to own the screen, and git's or bun's
|
|
35
|
+
// output would be left behind in the scrollback.
|
|
36
|
+
const { gitInstalled, installListedPlugin, loadRegistryListings } = await import("../plugins/installer");
|
|
31
37
|
let listings: ReturnType<typeof loadRegistryListings> | undefined;
|
|
38
|
+
let gitMissing: boolean | undefined;
|
|
32
39
|
const result = await seedExtractedPlugins(config, async (repo) => {
|
|
40
|
+
// Without git every clone fails the same way: no registry read, no attempt.
|
|
41
|
+
gitMissing ??= !gitInstalled();
|
|
42
|
+
if (gitMissing) throw new Error("git is not installed");
|
|
33
43
|
listings ??= loadRegistryListings();
|
|
34
|
-
return installListedPlugin(repo, {}, await listings);
|
|
44
|
+
return installListedPlugin(repo, { quiet: true }, await listings);
|
|
35
45
|
});
|
|
46
|
+
// Recorded, so doctor knows a launch tried, and a failure the next launch
|
|
47
|
+
// retries is not announced again while it lasts.
|
|
48
|
+
const failure = pluginSeedFailure(result.failed, gitMissing === true);
|
|
49
|
+
setPluginSeedNotice(pluginSeedNotice(failure, config.pluginSeedFailure));
|
|
36
50
|
|
|
37
51
|
const seeded = [...new Set(result.seeded)].sort();
|
|
38
52
|
const existing = [...new Set(config.seededPlugins ?? [])].sort();
|
|
39
|
-
|
|
53
|
+
const record = { seededPlugins: seeded, pluginSeedFailure: failure };
|
|
54
|
+
if (seeded.join() === existing.join() && samePluginSeedFailure(failure, config.pluginSeedFailure)) return record;
|
|
40
55
|
|
|
41
|
-
await saveConfig({ ...config,
|
|
56
|
+
await saveConfig({ ...config, ...record });
|
|
42
57
|
if (result.installed.length > 0) {
|
|
43
58
|
log.info(`Restored ${result.installed.join(", ")} into ${getPluginsDir()}`);
|
|
44
59
|
}
|
|
45
|
-
return
|
|
60
|
+
return record;
|
|
46
61
|
} catch (error) {
|
|
47
62
|
log.error(`Plugin restore skipped: ${error}`);
|
|
48
63
|
return null;
|
package/src/cli/result.ts
CHANGED
|
@@ -1,5 +1,6 @@
|
|
|
1
1
|
import type { CliGlobalOptions } from "./options";
|
|
2
2
|
import {
|
|
3
|
+
cliPlainEnabled,
|
|
3
4
|
cliStyles,
|
|
4
5
|
cliTerminalWidth,
|
|
5
6
|
renderStats,
|
|
@@ -13,7 +14,7 @@ import {
|
|
|
13
14
|
} from "../utils/cli-output";
|
|
14
15
|
import { serializeCsv } from "../utils/csv";
|
|
15
16
|
import { formatUtcTime, isEpochMilliseconds, isZonedIsoDateTime } from "../utils/utc-time";
|
|
16
|
-
import { formatFreshnessLine, type ReportFreshness } from "./pane-functions/freshness";
|
|
17
|
+
import { formatFreshnessLine, withSavedCopy, type ReportFreshness } from "./pane-functions/freshness";
|
|
17
18
|
import { withSearchHints, type FredSeriesCheck } from "./not-a-ticker";
|
|
18
19
|
import { renderReportCsv, renderReportNdjson, withCsvFooter, type CliReportTables } from "./report-tables";
|
|
19
20
|
import {
|
|
@@ -98,6 +99,11 @@ export interface CliResultRenderOptions<T = unknown, Row = Record<string, unknow
|
|
|
98
99
|
* `metadata.rows` in JSON.
|
|
99
100
|
*/
|
|
100
101
|
dateKey?: string;
|
|
102
|
+
/**
|
|
103
|
+
* The row key that splits the rows into series of their own, each windowed
|
|
104
|
+
* apart: with `symbol`, `--tail 5` keeps every symbol's newest five rows.
|
|
105
|
+
*/
|
|
106
|
+
seriesKey?: string;
|
|
101
107
|
/** How many rows to show when neither `--limit` nor `--tail` is given; every row when absent. */
|
|
102
108
|
defaultLimit?: number;
|
|
103
109
|
/**
|
|
@@ -114,6 +120,15 @@ export interface CliResultRenderOptions<T = unknown, Row = Record<string, unknow
|
|
|
114
120
|
exportIdentity?: ExportIdentity | ((row: Row) => ExportIdentity);
|
|
115
121
|
/** What CSV says after the source lines as `# note:` lines: what the rows do not show, such as where a series begins. */
|
|
116
122
|
exportNotes?: readonly string[];
|
|
123
|
+
/**
|
|
124
|
+
* Why a row's figures are empty (`Not a ticker: ZZZZQQ.`, `Chg%: no previous
|
|
125
|
+
* close`), for the `status` column CSV writes after the row's own columns and
|
|
126
|
+
* the `status` field of an NDJSON row; empty for a whole row. The column is
|
|
127
|
+
* there whenever this is, with rows or without, so the header never depends
|
|
128
|
+
* on what loaded. A figure that is no number (NaN) is written empty and,
|
|
129
|
+
* without a reason here, named as `<header>: not available`.
|
|
130
|
+
*/
|
|
131
|
+
exportStatus?: (row: Row) => string | null | undefined;
|
|
117
132
|
}
|
|
118
133
|
|
|
119
134
|
interface CliResultJsonEnvelope<T> extends Omit<CliResult<T>, "freshness" | "exportFreshness" | "failure"> {
|
|
@@ -149,11 +164,28 @@ function rowWindowOptions(options: CliGlobalOptions, renderOptions: Pick<CliResu
|
|
|
149
164
|
function windowed<Row>(
|
|
150
165
|
rows: readonly Row[],
|
|
151
166
|
options: CliGlobalOptions,
|
|
152
|
-
renderOptions: Pick<CliResultRenderOptions, "dateKey" | "defaultLimit">,
|
|
167
|
+
renderOptions: Pick<CliResultRenderOptions, "dateKey" | "defaultLimit" | "seriesKey">,
|
|
153
168
|
): RowWindow<Row> {
|
|
154
|
-
const { dateKey } = renderOptions;
|
|
169
|
+
const { dateKey, seriesKey } = renderOptions;
|
|
155
170
|
const dateOf = dateKey ? (row: Row) => (isPlainObject(row) ? row[dateKey] : undefined) : undefined;
|
|
156
|
-
|
|
171
|
+
const windowOptions = rowWindowOptions(options, renderOptions);
|
|
172
|
+
if (!seriesKey) return windowRows(rows, windowOptions, dateOf);
|
|
173
|
+
const series = new Map<unknown, Row[]>();
|
|
174
|
+
for (const row of rows) {
|
|
175
|
+
const key = isPlainObject(row) ? row[seriesKey] : undefined;
|
|
176
|
+
const group = series.get(key);
|
|
177
|
+
if (group) group.push(row);
|
|
178
|
+
else series.set(key, [row]);
|
|
179
|
+
}
|
|
180
|
+
const windows = [...series.values()].map((group) => windowRows(group, windowOptions, dateOf));
|
|
181
|
+
const count = windowOptions.tail ?? windowOptions.limit;
|
|
182
|
+
return {
|
|
183
|
+
rows: windows.flatMap((window) => window.rows),
|
|
184
|
+
total: rows.length,
|
|
185
|
+
kept: windows.find((window) => window.kept)?.kept ?? null,
|
|
186
|
+
note: windows.some((window) => window.note)
|
|
187
|
+
? `showing the oldest ${count} ${count === 1 ? "row" : "rows"} of each ${seriesKey}; --tail ${count} for the latest` : null,
|
|
188
|
+
};
|
|
157
189
|
}
|
|
158
190
|
|
|
159
191
|
function asRows<T, Row>(data: T, rows?: (data: T) => Row[]): Row[] {
|
|
@@ -206,7 +238,7 @@ function formatTextValue(
|
|
|
206
238
|
depth = 0,
|
|
207
239
|
width: number | null = null,
|
|
208
240
|
): string {
|
|
209
|
-
const missing = context === "record" ? cliStyles.muted("-") : "";
|
|
241
|
+
const missing = context === "record" ? cliPlainEnabled() ? "—" : cliStyles.muted("-") : "";
|
|
210
242
|
if (value == null || value === "") return missing;
|
|
211
243
|
// Times print in UTC with the zone named, never in the host's zone; JSON and CSV keep the raw value.
|
|
212
244
|
if (value instanceof Date) return formatUtcTime(value);
|
|
@@ -291,23 +323,69 @@ function serializeColumns<Row>(columns?: CliResultColumn<Row>[]) {
|
|
|
291
323
|
}));
|
|
292
324
|
}
|
|
293
325
|
|
|
326
|
+
/** A number a spreadsheet cannot read: NaN or an infinity, which exports write empty, never as the word. */
|
|
327
|
+
function isNonFiniteNumber(value: unknown): boolean {
|
|
328
|
+
return typeof value === "number" && !Number.isFinite(value);
|
|
329
|
+
}
|
|
330
|
+
|
|
331
|
+
/**
|
|
332
|
+
* What a row's status cell says: the command's reason, else the figures
|
|
333
|
+
* written empty for being no number. Empty when nothing is missing.
|
|
334
|
+
*/
|
|
335
|
+
function exportStatusText(reason: string | null | undefined, blanked: readonly string[]): string {
|
|
336
|
+
const own = reason?.trim();
|
|
337
|
+
if (own) return own;
|
|
338
|
+
return blanked.length > 0 ? `${blanked.join(", ")}: not available` : "";
|
|
339
|
+
}
|
|
340
|
+
|
|
341
|
+
/** `status`, or `value_status` beside a column of the table's own named Status. */
|
|
342
|
+
function statusHeader(headers: readonly string[]): string {
|
|
343
|
+
return headers.some((header) => header.trim().toLowerCase() === "status") ? "value_status" : "status";
|
|
344
|
+
}
|
|
345
|
+
|
|
294
346
|
function renderCsv<Row extends Record<string, unknown>>(
|
|
295
347
|
rows: Row[],
|
|
296
348
|
columns?: CliResultColumn<Row>[],
|
|
297
349
|
identity?: (row: Row) => string[],
|
|
350
|
+
status?: (row: Row) => string | null | undefined,
|
|
298
351
|
): string {
|
|
299
352
|
const resolvedColumns = columns && columns.length > 0
|
|
300
353
|
? columns
|
|
301
354
|
: inferColumns(rows as Record<string, unknown>[]) as CliResultColumn<Row>[];
|
|
355
|
+
const headers = resolvedColumns.map((column) => column.header);
|
|
302
356
|
return serializeCsv([
|
|
303
|
-
[...
|
|
304
|
-
...rows.map((row) =>
|
|
305
|
-
|
|
306
|
-
|
|
307
|
-
|
|
357
|
+
[...headers, ...status ? [statusHeader(headers)] : [], ...identity ? EXPORT_IDENTITY_COLUMNS : []],
|
|
358
|
+
...rows.map((row) => {
|
|
359
|
+
const values = resolvedColumns.map((column) => (column.value ? column.value(row) : row[column.key]));
|
|
360
|
+
const blanked = resolvedColumns.flatMap((column, index) => isNonFiniteNumber(values[index]) ? [column.header] : []);
|
|
361
|
+
return [
|
|
362
|
+
...values.map((value) => isNonFiniteNumber(value) ? "" : value),
|
|
363
|
+
...status ? [exportStatusText(status(row), blanked)] : [],
|
|
364
|
+
...identity?.(row) ?? [],
|
|
365
|
+
];
|
|
366
|
+
}),
|
|
308
367
|
]);
|
|
309
368
|
}
|
|
310
369
|
|
|
370
|
+
/**
|
|
371
|
+
* The key an NDJSON row says why its figures are empty under: `status`, or
|
|
372
|
+
* `value_status` beside a field of the row's own that the export writes under
|
|
373
|
+
* that name (an order's status), as CSV's header does.
|
|
374
|
+
*/
|
|
375
|
+
function ndjsonStatusKey(rows: readonly unknown[], columns?: readonly CliResultColumn<never>[]): string {
|
|
376
|
+
const own = columns && columns.length > 0
|
|
377
|
+
? columns.some((column) => column.key === "status")
|
|
378
|
+
: rows.some((row) => isPlainObject(row) && "status" in row);
|
|
379
|
+
return own ? "value_status" : "status";
|
|
380
|
+
}
|
|
381
|
+
|
|
382
|
+
/** An NDJSON row: a figure that is no number is null, and the row says why its figures are empty when the command does. */
|
|
383
|
+
function ndjsonRow<Row extends Record<string, unknown>>(row: Row, status: ((row: Row) => string | null | undefined) | undefined, statusKey: string): Record<string, unknown> {
|
|
384
|
+
const blanked = Object.entries(row).flatMap(([key, value]) => isNonFiniteNumber(value) ? [key] : []);
|
|
385
|
+
const own = blanked.length > 0 ? { ...row, ...Object.fromEntries(blanked.map((key) => [key, null])) } : row;
|
|
386
|
+
return status ? { ...own, [statusKey]: exportStatusText(status(row), blanked) || null } : own;
|
|
387
|
+
}
|
|
388
|
+
|
|
311
389
|
function stringField(row: Record<string, unknown>, key: string): string | null {
|
|
312
390
|
const value = row?.[key];
|
|
313
391
|
return typeof value === "string" && value.trim() ? value : null;
|
|
@@ -348,10 +426,11 @@ function renderTextTable<Row extends Record<string, unknown>>(
|
|
|
348
426
|
): string {
|
|
349
427
|
const resolvedColumns = textColumns(rows, columns);
|
|
350
428
|
const cells = rows.map((row) => resolvedColumns.map((column) => formatTextCell(column, row, "table")));
|
|
351
|
-
// A column no row fills is noise in a table; exports keep it
|
|
429
|
+
// A column no row fills is noise in a table; exports keep it, and so does plain output, whose
|
|
430
|
+
// tables keep one shape from query to query with "—" in the empty cells.
|
|
352
431
|
const filled = resolvedColumns
|
|
353
432
|
.map((column, index) => ({ column, index }))
|
|
354
|
-
.filter(({ column, index }) => column.width != null || cells.some((row) => row[index] !== ""));
|
|
433
|
+
.filter(({ column, index }) => cliPlainEnabled() || column.width != null || cells.some((row) => row[index] !== ""));
|
|
355
434
|
const shown = filled.length > 0 ? filled : resolvedColumns.map((column, index) => ({ column, index }));
|
|
356
435
|
return renderTable(
|
|
357
436
|
shown.map(({ column }) => ({
|
|
@@ -395,9 +474,13 @@ function overflowsTerminal<Row extends Record<string, unknown>>(rows: Row[]): bo
|
|
|
395
474
|
return width > terminalWidth;
|
|
396
475
|
}
|
|
397
476
|
|
|
398
|
-
/**
|
|
399
|
-
|
|
400
|
-
|
|
477
|
+
/**
|
|
478
|
+
* The closing source, as-of and status line of a text result, for output
|
|
479
|
+
* printed without `printResult`; `shown` is the data the line is drawn from,
|
|
480
|
+
* which says whether it came from a saved copy.
|
|
481
|
+
*/
|
|
482
|
+
export function cliFreshnessFooter(freshness: ReportFreshness, shown?: unknown): string {
|
|
483
|
+
return cliStyles.muted(wrapToTerminal(formatFreshnessLine(withSavedCopy(freshness, shown))));
|
|
401
484
|
}
|
|
402
485
|
|
|
403
486
|
export function serializeCliResult<T, Row extends Record<string, unknown> = Record<string, unknown>>(
|
|
@@ -405,8 +488,10 @@ export function serializeCliResult<T, Row extends Record<string, unknown> = Reco
|
|
|
405
488
|
options: CliGlobalOptions,
|
|
406
489
|
renderOptions: CliResultRenderOptions<T, Row> = {},
|
|
407
490
|
): string {
|
|
408
|
-
const { freshness, exportFreshness, failure, ...rest } = result;
|
|
409
|
-
|
|
491
|
+
const { freshness: reported, exportFreshness, failure, ...rest } = result;
|
|
492
|
+
// Rows shown from a saved copy, its refresh having failed, say so in place of live or delayed.
|
|
493
|
+
const freshness = reported && withSavedCopy(reported, result.data);
|
|
494
|
+
const cited = freshness ?? (exportFreshness && withSavedCopy(exportFreshness, result.data));
|
|
410
495
|
if (options.format === "json") {
|
|
411
496
|
const columns = serializeColumns(renderOptions.columns);
|
|
412
497
|
const window = Array.isArray(result.data) ? windowed(result.data as unknown[], options, renderOptions) : null;
|
|
@@ -443,14 +528,18 @@ function serializeCliRows<T, Row extends Record<string, unknown>>(
|
|
|
443
528
|
}
|
|
444
529
|
const window = windowed(asRows(result.data, renderOptions.rows), options, renderOptions);
|
|
445
530
|
const rows = window.rows;
|
|
531
|
+
const status = renderOptions.exportStatus;
|
|
446
532
|
if (options.format === "ndjson") {
|
|
447
|
-
|
|
448
|
-
|
|
449
|
-
|
|
533
|
+
const statusKey = ndjsonStatusKey(rows, renderOptions.columns as readonly CliResultColumn<never>[] | undefined);
|
|
534
|
+
return rows.map((row) => {
|
|
535
|
+
if (!isPlainObject(row)) return JSON.stringify(row);
|
|
536
|
+
const fields = ndjsonRow(row as Row, status, statusKey);
|
|
537
|
+
return JSON.stringify(cited ? { ...fields, ...exportIdentityFields(cited, rowIdentity(row as Row, renderOptions.exportIdentity)) } : fields);
|
|
538
|
+
}).join("\n");
|
|
450
539
|
}
|
|
451
540
|
if (options.format === "csv") {
|
|
452
|
-
if (!cited) return renderCsv(rows as Row[], renderOptions.columns);
|
|
453
|
-
const csv = renderCsv(rows as Row[], renderOptions.columns, (row) => exportIdentityCells(cited, rowIdentity(row, renderOptions.exportIdentity)));
|
|
541
|
+
if (!cited) return renderCsv(rows as Row[], renderOptions.columns, undefined, status);
|
|
542
|
+
const csv = renderCsv(rows as Row[], renderOptions.columns, (row) => exportIdentityCells(cited, rowIdentity(row, renderOptions.exportIdentity)), status);
|
|
454
543
|
return withCsvFooter(csv, [...exportSourceLines(cited), ...(renderOptions.exportNotes ?? []).map((note) => `note: ${note}`)]);
|
|
455
544
|
}
|
|
456
545
|
if (renderOptions.text) {
|
package/src/cli/series-search.ts
CHANGED
|
@@ -27,7 +27,7 @@ function fredSeriesIdOf(expression: string): string | null {
|
|
|
27
27
|
return /^FRED:([A-Z0-9]+)$/i.exec(expression)?.[1]?.toUpperCase() ?? null;
|
|
28
28
|
}
|
|
29
29
|
|
|
30
|
-
/** The FRED series the plugins' catalog charts, as `
|
|
30
|
+
/** The FRED series the plugins' catalog charts, as `gloom fred` takes them: DFEDTARU, ECBDFR. */
|
|
31
31
|
export function catalogFredSeriesIds(plugins: readonly SeriesSource[]): Set<string> {
|
|
32
32
|
return new Set(plugins.flatMap((plugin) => plugin.series ?? [])
|
|
33
33
|
.flatMap((definition) => definition.expression ? [fredSeriesIdOf(definition.expression)] : [])
|
|
@@ -96,14 +96,14 @@ export function renderSeriesMatches(
|
|
|
96
96
|
const shown = matches.slice(0, limit);
|
|
97
97
|
const count = shown.length < matches.length ? `${shown.length} of ${matches.length}` : String(matches.length);
|
|
98
98
|
const quoted = `"${query.replace(/"/g, "")}"`;
|
|
99
|
-
// A FRED series named by its id is also one `
|
|
99
|
+
// A FRED series named by its id is also one `gloom fred` prints.
|
|
100
100
|
const asked = query.trim().toUpperCase().replace(/^FRED:/, "");
|
|
101
101
|
const fred = matches.find((match) => match.exact && fredSeriesIdOf(match.expression) === asked);
|
|
102
102
|
const hint = fred
|
|
103
|
-
? `Print it with
|
|
103
|
+
? `Print it with gloom fred ${asked}; chart it with gloom fn G ${fred.expression}.`
|
|
104
104
|
: shown.length < matches.length
|
|
105
|
-
? `Chart one with
|
|
106
|
-
: "Chart one with
|
|
105
|
+
? `Chart one with gloom fn G <chart>; gloom ${rest === "catalog" ? `catalog ${quoted}` : `shot CAT ${quoted}`} lists all ${matches.length}.`
|
|
106
|
+
: "Chart one with gloom fn G <chart>.";
|
|
107
107
|
return [
|
|
108
108
|
`${renderSection(`Series for "${query}"`)} ${cliStyles.muted(`(${count})`)}`,
|
|
109
109
|
renderTable(
|
|
@@ -1,6 +1,7 @@
|
|
|
1
1
|
import { apiClient } from "../api-client";
|
|
2
2
|
import type { BankFiguresPayload } from "../api-client/bank-figures";
|
|
3
3
|
import type { FinancialStatement } from "../types/financials";
|
|
4
|
+
import { fetchOfferingFilings, type OfferingFiling } from "../utils/cash-runway";
|
|
4
5
|
import { logFailure } from "../utils/log-failure";
|
|
5
6
|
import { nonUsSecListingVenue } from "../utils/sec";
|
|
6
7
|
|
|
@@ -42,6 +43,8 @@ export interface StatementReportSources {
|
|
|
42
43
|
/** The company's 10-K, 10-Q, 8-K, 20-F and 40-F filings, newest first. */
|
|
43
44
|
statementFilings(symbol: string): Promise<PeriodicFiling[]>;
|
|
44
45
|
bankFigures(symbol: string): Promise<BankFiguresPayload>;
|
|
46
|
+
/** The company's latest offering prospectuses (424B5, 424B4), newest first. */
|
|
47
|
+
offeringFilings?(symbol: string): Promise<OfferingFiling[]>;
|
|
45
48
|
}
|
|
46
49
|
|
|
47
50
|
export const cloudStatementReportSources: StatementReportSources = {
|
|
@@ -62,8 +65,24 @@ export const cloudStatementReportSources: StatementReportSources = {
|
|
|
62
65
|
});
|
|
63
66
|
},
|
|
64
67
|
bankFigures: (symbol) => apiClient.getCloudBankFigures(symbol),
|
|
68
|
+
offeringFilings: (symbol) => fetchOfferingFilings(apiClient, symbol),
|
|
65
69
|
};
|
|
66
70
|
|
|
71
|
+
/**
|
|
72
|
+
* A US listing's latest offering prospectuses, for the note that its cash
|
|
73
|
+
* predates one; nothing (and no request) for any other listing, or when
|
|
74
|
+
* `wanted` is false. A failed read leaves the note out.
|
|
75
|
+
*/
|
|
76
|
+
export async function loadOfferingFilings(
|
|
77
|
+
sources: StatementReportSources | undefined,
|
|
78
|
+
listing: { symbol: string; exchange?: string },
|
|
79
|
+
wanted: boolean,
|
|
80
|
+
): Promise<OfferingFiling[]> {
|
|
81
|
+
if (!wanted || !sources?.offeringFilings || nonUsSecListingVenue(listing.symbol, listing.exchange)) return [];
|
|
82
|
+
return sources.offeringFilings(listing.symbol)
|
|
83
|
+
.catch(logFailure("cli.statement-filings", "Reading the offering filings failed", [] as OfferingFiling[]));
|
|
84
|
+
}
|
|
85
|
+
|
|
67
86
|
/** The filing a statement row's period was read from: its form when the filing list names it, and its filed date. */
|
|
68
87
|
export interface StatementFiling {
|
|
69
88
|
/** 10-Q, 10-K, 20-F or 40-F; null when the filing is not among those listed. */
|
|
@@ -0,0 +1,49 @@
|
|
|
1
|
+
import { saveConfig } from "../data/config/store";
|
|
2
|
+
import { mergeSavedSuffixedListings } from "../portfolio/suffixed-listings";
|
|
3
|
+
import type { CliCommandContext } from "../types/plugin";
|
|
4
|
+
import { debugLog } from "../utils/debug-log";
|
|
5
|
+
import { logFailure } from "../utils/log-failure";
|
|
6
|
+
import { withConfigData, withMarketData } from "./scoped-context";
|
|
7
|
+
import type { ConfigContext, MarketContext } from "./types";
|
|
8
|
+
|
|
9
|
+
const log = debugLog.createLogger("cli.suffixed-listings");
|
|
10
|
+
|
|
11
|
+
/**
|
|
12
|
+
* The profile with the rows a collection holds under a vendor's suffixed key
|
|
13
|
+
* (GARAN.IS) merged into their listing's row (`mergeSuffixedListings`), as
|
|
14
|
+
* the app does at launch, for a command about to change a portfolio or
|
|
15
|
+
* watchlist: what it reads is then what it saves over. A dry run writes
|
|
16
|
+
* nothing and reads the profile as it is. A merge that fails leaves the rows
|
|
17
|
+
* as they were.
|
|
18
|
+
*/
|
|
19
|
+
async function mergedForWrite<TContext extends ConfigContext>(ctx: Pick<CliCommandContext, "cliOptions">, context: TContext): Promise<TContext> {
|
|
20
|
+
if (ctx.cliOptions.dryRun) return context;
|
|
21
|
+
try {
|
|
22
|
+
const merged = await mergeSavedSuffixedListings(await context.store.loadAllTickers(), context.config, {
|
|
23
|
+
config: saveConfig,
|
|
24
|
+
tickers: (rows) => context.store.saveTickers(rows),
|
|
25
|
+
});
|
|
26
|
+
// In place: a market context's provider reads the config through this object.
|
|
27
|
+
if (merged) context.config = merged.config;
|
|
28
|
+
for (const kept of merged?.keptCustom ?? []) log.info("custom fields kept on the suffixed row", kept);
|
|
29
|
+
} catch (error) {
|
|
30
|
+
logFailure("cli.suffixed-listings", "Merging suffixed listing rows failed")(error);
|
|
31
|
+
}
|
|
32
|
+
return context;
|
|
33
|
+
}
|
|
34
|
+
|
|
35
|
+
/** `withConfigData` for a command that changes a portfolio or watchlist (`mergedForWrite`). Commands that only read use `withConfigData`. */
|
|
36
|
+
export function withCollectionConfigData<TResult>(
|
|
37
|
+
ctx: Pick<CliCommandContext, "initConfigData" | "cliOptions">,
|
|
38
|
+
operation: (context: ConfigContext) => TResult | Promise<TResult>,
|
|
39
|
+
): Promise<TResult> {
|
|
40
|
+
return withConfigData(async () => mergedForWrite(ctx, await ctx.initConfigData()), operation);
|
|
41
|
+
}
|
|
42
|
+
|
|
43
|
+
/** `withMarketData` for a command that changes a portfolio or watchlist (`mergedForWrite`). */
|
|
44
|
+
export function withCollectionMarketData<TResult>(
|
|
45
|
+
ctx: Pick<CliCommandContext, "initMarketData" | "cliOptions">,
|
|
46
|
+
operation: (context: MarketContext) => TResult | Promise<TResult>,
|
|
47
|
+
): Promise<TResult> {
|
|
48
|
+
return withMarketData(async () => mergedForWrite(ctx, await ctx.initMarketData()), operation);
|
|
49
|
+
}
|