gloomberb 0.16.4 → 0.16.5
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +14 -91
- package/package.json +4 -1
- package/src/{plugins/builtin/cloud → account}/auth-form.tsx +9 -9
- package/src/{plugins/builtin/cloud → account}/auth-model.ts +4 -4
- package/src/account/billing.ts +57 -0
- package/src/{plugins/builtin/cloud → account}/device-signin-dialog.tsx +18 -12
- package/src/{plugins/builtin/cloud → account}/device-signin.ts +2 -2
- package/src/{plugins/builtin/cloud → account}/email-auth-attempt.ts +2 -2
- package/src/account/session.ts +16 -0
- package/src/{plugins/builtin/cloud → account}/upgrade-dialog.tsx +16 -15
- package/src/{plugins/builtin/cloud → account}/upgrade-personalization.ts +7 -7
- package/src/{plugins/builtin/cloud → account}/upgrade-tickers.ts +6 -6
- package/src/{plugins/builtin/cloud → account}/verification-panel.tsx +6 -6
- package/src/api-client/data.ts +24 -2
- package/src/api-client/earnings.ts +6 -0
- package/src/api-client/futures-curve.ts +56 -0
- package/src/api-client/index.ts +4 -1
- package/src/api-client/market-discovery.ts +10 -1
- package/src/api-client/paths.ts +7 -0
- package/src/api-client/research-activity.ts +15 -10
- package/src/api-client/types.ts +17 -1
- package/src/api-client/yield-curves.ts +8 -0
- package/src/app/global-shortcuts.ts +15 -1
- package/src/app/pane-runtime/ticker-open-runtime.ts +7 -3
- package/src/architecture/core-builtin-allowlist.json +4 -13
- package/src/brokers/signed-in/sign-in-dialog.tsx +11 -5
- package/src/capabilities/chart-series.ts +11 -1
- package/src/cli/commands/crypto-hints.ts +7 -0
- package/src/cli/commands/fred-series.ts +61 -0
- package/src/cli/commands/market.ts +407 -104
- package/src/cli/commands/news-hints.ts +62 -0
- package/src/cli/commands/news-search.ts +53 -0
- package/src/cli/commands/options-leaps.ts +5 -2
- package/src/cli/commands/overview.ts +93 -20
- package/src/cli/commands/remote.ts +2 -1
- package/src/cli/commands/search.ts +82 -9
- package/src/cli/commands/system.ts +55 -8
- package/src/cli/commands/ticker.ts +88 -11
- package/src/cli/context.ts +45 -14
- package/src/cli/desktop-pane-shot.ts +59 -7
- package/src/cli/earnings-calendar.ts +71 -0
- package/src/cli/freshness.ts +18 -7
- package/src/cli/glossary.ts +429 -0
- package/src/cli/history-rows.ts +48 -7
- package/src/cli/index-roots.ts +7 -0
- package/src/cli/index.ts +21 -7
- package/src/cli/known-gaps.ts +27 -0
- package/src/cli/listing-arg.ts +417 -56
- package/src/cli/not-a-ticker.ts +12 -5
- package/src/cli/pane-functions/access-gate.ts +5 -0
- package/src/cli/pane-functions/capabilities.ts +3 -2
- package/src/cli/pane-functions/catalog.ts +35 -5
- package/src/cli/pane-functions/data.ts +12 -8
- package/src/cli/pane-functions/discovery.ts +1 -0
- package/src/cli/pane-functions/dom.ts +20 -6
- package/src/cli/pane-functions/freshness.ts +363 -43
- package/src/cli/pane-functions/function-help.ts +12 -5
- package/src/cli/pane-functions/headless.ts +45 -17
- package/src/cli/pane-functions/index.ts +63 -10
- package/src/cli/pane-functions/market-session.ts +22 -8
- package/src/cli/pane-functions/options.ts +63 -22
- package/src/cli/pane-functions/report-notices.ts +25 -7
- package/src/cli/pane-functions/report.ts +15 -8
- package/src/cli/pane-functions/resolver.ts +49 -12
- package/src/cli/pane-functions/screenshot.ts +110 -23
- package/src/cli/report-tables.ts +3 -0
- package/src/cli/result.ts +4 -1
- package/src/cli/staged-tickers.ts +52 -0
- package/src/cli/symbol-args.ts +9 -0
- package/src/cli/symbol-list.ts +172 -0
- package/src/cli/ticker-resolution.ts +223 -30
- package/src/cli/types.ts +5 -0
- package/src/components/chart/composite/axis-overlays.tsx +6 -2
- package/src/components/chart/composite/composite-chart.tsx +40 -6
- package/src/components/chart/composite/legend.tsx +49 -2
- package/src/components/chart/composite/panel-surface.tsx +44 -17
- package/src/components/chart/composite/price-axis-labels.tsx +3 -1
- package/src/components/command-bar/panel/index.tsx +11 -3
- package/src/components/command-bar/panel/runtime.ts +3 -0
- package/src/components/command-bar/panel/types.ts +2 -0
- package/src/components/command-bar/routes/root/provider-search.ts +4 -3
- package/src/components/command-bar/routes/ticker-search/results.ts +12 -11
- package/src/components/command-bar/routes/ticker-search/route.ts +4 -3
- package/src/components/command-bar/workflow/tickers.ts +23 -4
- package/src/components/layout/detached-pane-shell.tsx +9 -0
- package/src/components/layout/floating-pane.tsx +3 -0
- package/src/components/layout/header.tsx +20 -5
- package/src/components/layout/pane/content.tsx +7 -13
- package/src/components/layout/pane/footer/index.tsx +6 -2
- package/src/components/layout/pane/footer/model.ts +35 -1
- package/src/components/layout/pane/header.tsx +24 -1
- package/src/components/layout/pane/index.tsx +12 -2
- package/src/components/layout/pane/sidebar.tsx +78 -10
- package/src/components/layout/shell/active-drag.ts +21 -5
- package/src/components/layout/shell/drag/index.ts +39 -9
- package/src/components/layout/shell/drag/live.ts +61 -51
- package/src/components/layout/shell/drag/runtime.ts +54 -12
- package/src/components/layout/shell/index.tsx +25 -7
- package/src/components/layout/shell/menu.ts +5 -0
- package/src/components/layout/shell/native/pointer-runtime.ts +3 -1
- package/src/components/layout/shell/pane/layers.tsx +192 -45
- package/src/components/layout/shell/terminal-pointer-runtime.ts +24 -0
- package/src/components/markdown-text.tsx +62 -20
- package/src/components/metric-treemap/heat-surface.tsx +10 -1
- package/src/components/onboarding/account-step/form-panel.tsx +1 -1
- package/src/components/onboarding/account-step/index.tsx +1 -1
- package/src/components/onboarding/account-step/qr-panel.tsx +1 -1
- package/src/components/onboarding/account-step/signed-in-panel.tsx +1 -1
- package/src/components/onboarding/onboarding-keyboard.ts +1 -1
- package/src/components/onboarding/onboarding-wizard.tsx +2 -2
- package/src/components/onboarding/use-onboarding-upgrade.ts +3 -3
- package/src/components/onboarding/wizard-account.ts +2 -2
- package/src/components/pane-template-wizard.tsx +9 -1
- package/src/components/price-selector-dialog.tsx +11 -2
- package/src/components/sign-in-gate.tsx +3 -3
- package/src/components/ticker/list-table-view.tsx +24 -1
- package/src/components/ui/action-row.tsx +2 -1
- package/src/components/ui/button.tsx +7 -1
- package/src/components/ui/choice-dialog.tsx +6 -4
- package/src/components/ui/confirm-dialog.tsx +28 -18
- package/src/components/ui/data-table/index.tsx +17 -6
- package/src/components/ui/data-table/opentui/index.tsx +37 -6
- package/src/components/ui/data-table/types.ts +12 -0
- package/src/components/ui/dialog-actions.tsx +64 -0
- package/src/components/ui/display.tsx +17 -3
- package/src/components/ui/frame.tsx +35 -2
- package/src/components/ui/icon.tsx +2 -0
- package/src/components/ui/text-prompt-dialog.tsx +11 -9
- package/src/data/cached-query.ts +2 -0
- package/src/data/config/store/normalize.ts +7 -2
- package/src/data/ticker-repository.ts +5 -0
- package/src/data/ticker-store.ts +15 -0
- package/src/docs/content.ts +215 -0
- package/src/docs/load.ts +139 -0
- package/src/docs/requests.ts +39 -0
- package/src/docs/snapshot.chunk.ts +8 -0
- package/src/docs/snapshot.json +7416 -0
- package/src/docs/topics.ts +216 -0
- package/src/i18n/es.ts +61 -4
- package/src/i18n/ja.ts +61 -4
- package/src/i18n/ko.ts +61 -4
- package/src/i18n/zh-cn.ts +61 -4
- package/src/i18n/zh-tw.ts +61 -4
- package/src/layout/desks.ts +1 -1
- package/src/layout/pane-manager/dock-tree.ts +18 -0
- package/src/layout/pane-manager/index.ts +1 -0
- package/src/market-data/coordinator/chart.ts +10 -4
- package/src/market-data/coordinator/index.ts +6 -3
- package/src/{plugins/builtin/futures/contracts.ts → market-data/futures-board.ts} +81 -28
- package/src/market-data/futures-contract.ts +151 -0
- package/src/market-data/hooks.tsx +10 -2
- package/src/market-data/market/format.ts +39 -21
- package/src/market-data/market/freshness.ts +81 -18
- package/src/market-data/market/status.ts +19 -23
- package/src/market-data/published-apac-sessions.ts +23 -1
- package/src/market-data/quotes/contributions.ts +3 -0
- package/src/market-data/quotes/metadata.ts +7 -24
- package/src/market-data/quotes/resolution.ts +2 -0
- package/src/market-data/quotes/screener-live-quotes.ts +5 -4
- package/src/market-data/result-types.ts +2 -0
- package/src/plugins/builtin/account-management/model.ts +1 -56
- package/src/plugins/builtin/account-management/pane.tsx +6 -4
- package/src/plugins/builtin/account-management/password-dialog.tsx +1 -1
- package/src/plugins/builtin/alerts/cli.ts +313 -47
- package/src/plugins/builtin/alerts/events-pane.tsx +45 -7
- package/src/plugins/builtin/alerts/events.ts +23 -2
- package/src/plugins/builtin/alerts/history-pane.tsx +7 -2
- package/src/plugins/builtin/alerts/history.ts +2 -0
- package/src/plugins/builtin/alerts/index.tsx +41 -9
- package/src/plugins/builtin/alerts/pane.tsx +8 -0
- package/src/plugins/builtin/alerts/research-builder.ts +8 -3
- package/src/plugins/builtin/alerts/research-rules.ts +18 -2
- package/src/plugins/builtin/alerts/scheduled-check.ts +122 -0
- package/src/plugins/builtin/alerts/scheduled-sources.ts +25 -0
- package/src/plugins/builtin/alerts/scheduled.ts +254 -0
- package/src/plugins/builtin/alerts/targets.ts +92 -0
- package/src/plugins/builtin/analytics/index.tsx +4 -2
- package/src/plugins/builtin/analytics/risk-headless.ts +30 -12
- package/src/plugins/builtin/analytics/risk-math.ts +91 -27
- package/src/plugins/builtin/analytics/risk-model.ts +35 -5
- package/src/plugins/builtin/analytics/risk-pane.tsx +15 -8
- package/src/plugins/builtin/attention/index.tsx +2 -0
- package/src/plugins/builtin/attention/pane.tsx +3 -1
- package/src/plugins/builtin/attention/series.ts +26 -0
- package/src/plugins/builtin/awards/index.tsx +2 -0
- package/src/plugins/builtin/awards/pane.tsx +3 -1
- package/src/plugins/builtin/awards/series.ts +29 -0
- package/src/plugins/builtin/bond-calculator/model.ts +2 -1
- package/src/plugins/builtin/catalysts/pane.tsx +3 -1
- package/src/plugins/builtin/cds/client.ts +70 -13
- package/src/plugins/builtin/cds/headless.ts +116 -19
- package/src/plugins/builtin/cds/index.tsx +3 -1
- package/src/plugins/builtin/cds/model.ts +193 -31
- package/src/plugins/builtin/cds/pane.tsx +56 -14
- package/src/plugins/builtin/cds/series.ts +19 -0
- package/src/plugins/builtin/central-bank-rates/index.tsx +2 -0
- package/src/plugins/builtin/central-bank-rates/series.ts +42 -0
- package/src/plugins/builtin/chart-composer/catalog-inventory.ts +192 -255
- package/src/plugins/builtin/chart-composer/data-catalog-pane.tsx +84 -46
- package/src/plugins/builtin/chart-composer/editor.tsx +5 -4
- package/src/plugins/builtin/chart-composer/field-series.ts +40 -0
- package/src/plugins/builtin/chart-composer/headless.ts +8 -3
- package/src/plugins/builtin/chart-composer/index.tsx +9 -2
- package/src/plugins/builtin/chart-composer/series-catalog.ts +58 -50
- package/src/plugins/builtin/chart-composer/series-expression.ts +18 -10
- package/src/plugins/builtin/chart-composer/use-series-catalog.ts +59 -3
- package/src/plugins/builtin/chart-composer/user-series.ts +84 -0
- package/src/plugins/builtin/chat/content/new-dm-dialog.tsx +10 -2
- package/src/plugins/builtin/chat/controller/index.ts +2 -0
- package/src/plugins/builtin/cloud/askg/controller.ts +111 -19
- package/src/plugins/builtin/cloud/askg/executor.ts +57 -3
- package/src/plugins/builtin/cloud/askg/manifest.ts +32 -7
- package/src/plugins/builtin/cloud/askg/model.ts +27 -8
- package/src/plugins/builtin/cloud/askg/protocol.ts +10 -1
- package/src/plugins/builtin/cloud/askg/tool-display.ts +3 -0
- package/src/plugins/builtin/cloud/askg/undo.ts +2 -0
- package/src/plugins/builtin/cloud/auth-actions.tsx +1 -1
- package/src/plugins/builtin/cloud/auth-commands.ts +1 -1
- package/src/plugins/builtin/cloud/auth-dialog.tsx +3 -3
- package/src/plugins/builtin/cloud/company-picker.tsx +1 -1
- package/src/plugins/builtin/cloud/mcp-connect/dialog.tsx +3 -0
- package/src/plugins/builtin/cloud/terminal-relay/engine.ts +77 -9
- package/src/plugins/builtin/cloud/terminal-relay/manifest.ts +6 -1
- package/src/plugins/builtin/cloud/terminal-relay/policy.ts +9 -0
- package/src/plugins/builtin/cloud/terminal-relay/prompts.tsx +35 -11
- package/src/plugins/builtin/cloud/thesis/exposure.ts +1 -1
- package/src/plugins/builtin/cloud/thesis/prompts.tsx +2 -1
- package/src/plugins/builtin/company-attention/app-rank.tsx +1 -1
- package/src/plugins/builtin/company-attention/headless.ts +19 -5
- package/src/plugins/builtin/company-attention/index.tsx +2 -0
- package/src/plugins/builtin/company-attention/model.ts +26 -7
- package/src/plugins/builtin/company-attention/pane.tsx +12 -9
- package/src/plugins/builtin/company-attention/series.ts +52 -0
- package/src/plugins/builtin/company-kpis/pane.tsx +4 -2
- package/src/plugins/builtin/composite-plugins.ts +19 -13
- package/src/plugins/builtin/cot/index.tsx +3 -1
- package/src/plugins/builtin/cot/model.ts +40 -11
- package/src/plugins/builtin/cot/series.ts +27 -0
- package/src/plugins/builtin/credit-boards/index.tsx +2 -0
- package/src/plugins/builtin/credit-boards/series.ts +66 -0
- package/src/plugins/builtin/credit-conditions/index.tsx +2 -0
- package/src/plugins/builtin/credit-conditions/series.ts +26 -0
- package/src/plugins/builtin/credit-documents/headless.ts +31 -1
- package/src/plugins/builtin/credit-documents/pane.tsx +3 -1
- package/src/plugins/builtin/crypto-board/headless.ts +2 -3
- package/src/plugins/builtin/crypto-board/index.tsx +2 -0
- package/src/plugins/builtin/crypto-board/model.ts +12 -0
- package/src/plugins/builtin/crypto-board/pane.tsx +19 -12
- package/src/plugins/builtin/crypto-board/series.ts +48 -0
- package/src/plugins/builtin/custom-view/live-quotes.ts +2 -2
- package/src/plugins/builtin/debt-maturities/index.tsx +2 -0
- package/src/plugins/builtin/debt-maturities/series.ts +45 -0
- package/src/plugins/builtin/dividend-yield/headless.ts +2 -2
- package/src/plugins/builtin/dividend-yield/index.tsx +2 -0
- package/src/plugins/builtin/dividend-yield/series.ts +20 -0
- package/src/plugins/builtin/docs/blocks.tsx +181 -0
- package/src/plugins/builtin/docs/index.tsx +68 -0
- package/src/plugins/builtin/docs/pane.tsx +426 -0
- package/src/plugins/builtin/docs/targets.ts +72 -0
- package/src/plugins/builtin/docs/use-docs.ts +60 -0
- package/src/plugins/builtin/doe/index.tsx +2 -0
- package/src/plugins/builtin/doe/series.ts +62 -0
- package/src/plugins/builtin/earnings/client.ts +3 -2
- package/src/plugins/builtin/earnings/format.ts +1 -5
- package/src/plugins/builtin/earnings/headless.ts +58 -6
- package/src/plugins/builtin/earnings/history-model.ts +15 -1
- package/src/plugins/builtin/earnings/history-table.ts +13 -2
- package/src/plugins/builtin/earnings/history.tsx +7 -3
- package/src/plugins/builtin/econ/fred-catalog.ts +189 -0
- package/src/plugins/builtin/econ/fred-series-map.ts +0 -46
- package/src/plugins/builtin/econ/index.tsx +2 -0
- package/src/plugins/builtin/econ-statistics/defs.ts +5 -0
- package/src/plugins/builtin/econ-statistics/headless.ts +19 -4
- package/src/plugins/builtin/econ-statistics/stats.ts +1 -0
- package/src/plugins/builtin/equity-screener/pane.tsx +4 -11
- package/src/plugins/builtin/exposure/holdings.ts +1 -1
- package/src/plugins/builtin/exposure/pane.tsx +3 -1
- package/src/plugins/builtin/fear-greed/index.tsx +4 -0
- package/src/plugins/builtin/fear-greed/series.ts +52 -0
- package/src/plugins/builtin/futures/index.tsx +43 -3
- package/src/plugins/builtin/futures/model.ts +1 -1
- package/src/plugins/builtin/futures/returns.ts +1 -1
- package/src/plugins/builtin/futures/series.ts +13 -0
- package/src/plugins/builtin/futures/table.tsx +1 -1
- package/src/plugins/builtin/futures/use-front-returns.ts +1 -1
- package/src/plugins/builtin/futures-curve/client.ts +12 -3
- package/src/plugins/builtin/futures-curve/headless.ts +70 -9
- package/src/plugins/builtin/futures-curve/index.tsx +1 -1
- package/src/plugins/builtin/futures-curve/model.ts +66 -11
- package/src/plugins/builtin/futures-curve/pane.tsx +52 -18
- package/src/plugins/builtin/fx-matrix/index.tsx +1 -1
- package/src/plugins/builtin/gpu/board.tsx +13 -10
- package/src/plugins/builtin/gpu/changes.tsx +4 -4
- package/src/plugins/builtin/gpu/client.ts +19 -1
- package/src/plugins/builtin/gpu/equities.tsx +14 -10
- package/src/plugins/builtin/gpu/headless.ts +56 -25
- package/src/plugins/builtin/gpu/history.tsx +3 -3
- package/src/plugins/builtin/gpu/index.tsx +2 -0
- package/src/plugins/builtin/gpu/model.ts +101 -16
- package/src/plugins/builtin/gpu/pane.tsx +28 -12
- package/src/plugins/builtin/gpu/series.ts +38 -0
- package/src/plugins/builtin/help/function-card.tsx +25 -6
- package/src/plugins/builtin/help/index.tsx +17 -8
- package/src/plugins/builtin/holders/beneficial-model.ts +90 -3
- package/src/plugins/builtin/holders/beneficial-report.ts +57 -5
- package/src/plugins/builtin/holders/beneficial-view.tsx +55 -11
- package/src/plugins/builtin/holders/client.ts +22 -3
- package/src/plugins/builtin/holders/format.ts +18 -3
- package/src/plugins/builtin/holders/headless.ts +36 -133
- package/src/plugins/builtin/holders/pane.tsx +11 -4
- package/src/plugins/builtin/holders/report-header.ts +40 -5
- package/src/plugins/builtin/holders/report-rows.ts +240 -0
- package/src/plugins/builtin/insider/client.ts +35 -20
- package/src/plugins/builtin/insider/headless.ts +41 -11
- package/src/plugins/builtin/insider/index.tsx +26 -9
- package/src/plugins/builtin/insider/insider-data.ts +10 -0
- package/src/plugins/builtin/insider/issuer.ts +49 -0
- package/src/plugins/builtin/insider/model.ts +3 -0
- package/src/plugins/builtin/iv-history/client.ts +14 -4
- package/src/plugins/builtin/iv-history/headless.ts +7 -4
- package/src/plugins/builtin/iv-history/index.tsx +2 -0
- package/src/plugins/builtin/iv-history/model.ts +111 -7
- package/src/plugins/builtin/iv-history/screen-pane.tsx +5 -9
- package/src/plugins/builtin/iv-history/series.ts +29 -0
- package/src/plugins/builtin/jobs/headless.ts +28 -3
- package/src/plugins/builtin/jobs/index.tsx +3 -1
- package/src/plugins/builtin/jobs/series.ts +19 -0
- package/src/plugins/builtin/kelly-sizer/pane.tsx +2 -1
- package/src/plugins/builtin/kelly-sizer/portfolio.ts +0 -39
- package/src/plugins/builtin/macro-day/client.ts +44 -3
- package/src/plugins/builtin/macro-day/headless.ts +13 -10
- package/src/plugins/builtin/macro-day/model.ts +56 -10
- package/src/plugins/builtin/macro-day/pane.tsx +30 -20
- package/src/plugins/builtin/market-heatmap/model.ts +19 -11
- package/src/plugins/builtin/market-heatmap/portfolio.ts +2 -2
- package/src/plugins/builtin/market-movers/client.ts +7 -5
- package/src/plugins/builtin/market-movers/index.tsx +3 -2
- package/src/plugins/builtin/market-movers/model.ts +30 -0
- package/src/plugins/builtin/market-movers/screener.ts +31 -0
- package/src/plugins/builtin/market-valuation/chart-series.ts +29 -69
- package/src/plugins/builtin/market-valuation/index.tsx +3 -3
- package/src/plugins/builtin/market-valuation/indicators.ts +0 -5
- package/src/plugins/builtin/members/headless.ts +7 -2
- package/src/plugins/builtin/members/model.ts +31 -3
- package/src/plugins/builtin/members/pane.tsx +3 -6
- package/src/plugins/builtin/mna/headless.ts +15 -3
- package/src/plugins/builtin/money-markets/index.tsx +2 -0
- package/src/plugins/builtin/money-markets/series.ts +41 -0
- package/src/plugins/builtin/notes/cli.ts +12 -7
- package/src/plugins/builtin/options/view.tsx +1 -1
- package/src/plugins/builtin/options-calculator/inputs.ts +2 -1
- package/src/plugins/builtin/options-positioning/client.ts +7 -3
- package/src/plugins/builtin/options-positioning/headless.ts +1 -0
- package/src/plugins/builtin/options-positioning/pane.tsx +2 -2
- package/src/plugins/builtin/options-scenario/client.ts +2 -1
- package/src/plugins/builtin/options-scenario/headless.ts +1 -0
- package/src/plugins/builtin/options-scenario/hedge.ts +2 -1
- package/src/plugins/builtin/perps/client.ts +40 -6
- package/src/plugins/builtin/perps/equity-row.tsx +33 -11
- package/src/plugins/builtin/perps/freshness.ts +66 -0
- package/src/plugins/builtin/perps/headless.ts +45 -30
- package/src/plugins/builtin/perps/index.tsx +18 -1
- package/src/plugins/builtin/perps/model.ts +20 -5
- package/src/plugins/builtin/perps/pane.tsx +76 -20
- package/src/plugins/builtin/perps/series.ts +76 -0
- package/src/plugins/builtin/plugin-marketplace/pane.tsx +67 -61
- package/src/plugins/builtin/plugin-module.ts +3 -0
- package/src/plugins/builtin/portfolio-list/account-metrics.ts +1 -1
- package/src/plugins/builtin/portfolio-list/cli/bulk-symbols.ts +273 -0
- package/src/plugins/builtin/portfolio-list/cli/import-13f.ts +109 -0
- package/src/plugins/builtin/portfolio-list/cli/portfolio-command.ts +331 -65
- package/src/plugins/builtin/portfolio-list/cli/render.ts +200 -31
- package/src/plugins/builtin/portfolio-list/cli/shared.ts +24 -0
- package/src/plugins/builtin/portfolio-list/cli/watchlist-command.ts +120 -47
- package/src/plugins/builtin/portfolio-list/column-values.ts +1 -1
- package/src/plugins/builtin/portfolio-list/grid.tsx +1 -1
- package/src/plugins/builtin/portfolio-list/headless.ts +34 -4
- package/src/plugins/builtin/portfolio-list/imported-from.ts +8 -0
- package/src/plugins/builtin/portfolio-list/live-valuation.ts +6 -2
- package/src/plugins/builtin/portfolio-list/pane/index.tsx +6 -1
- package/src/plugins/builtin/portfolio-list/quick-add/index.tsx +17 -1
- package/src/plugins/builtin/portfolio-list/summary/totals.ts +1 -1
- package/src/plugins/builtin/portfolio-list/table.tsx +7 -1
- package/src/plugins/builtin/power/client.ts +16 -0
- package/src/plugins/builtin/power/evidence.ts +6 -2
- package/src/plugins/builtin/power/headless.ts +71 -7
- package/src/plugins/builtin/power/index.tsx +4 -1
- package/src/plugins/builtin/power/model.ts +72 -1
- package/src/plugins/builtin/power/pane.tsx +32 -9
- package/src/plugins/builtin/rate-path/headless.ts +11 -3
- package/src/plugins/builtin/realized-vol/headless.ts +5 -0
- package/src/plugins/builtin/research/corporate-actions-pane.tsx +5 -2
- package/src/plugins/builtin/research/event-model.ts +68 -24
- package/src/plugins/builtin/research/events-headless.ts +2 -1
- package/src/plugins/builtin/research/headless.ts +2 -1
- package/src/plugins/builtin/seasonality/client.ts +15 -7
- package/src/plugins/builtin/seasonality/headless.ts +36 -12
- package/src/plugins/builtin/seasonality/index.tsx +2 -2
- package/src/plugins/builtin/seasonality/model.ts +119 -0
- package/src/plugins/builtin/seasonality/pane.tsx +108 -37
- package/src/plugins/builtin/series-inventory.ts +91 -0
- package/src/plugins/builtin/shared/cloud-upgrade.ts +1 -1
- package/src/plugins/builtin/shared/command-tab.ts +30 -12
- package/src/plugins/builtin/shared/earnings-report.ts +55 -0
- package/src/plugins/builtin/shared/fred-points.ts +20 -0
- package/src/plugins/builtin/shared/fx-rate-freshness.ts +101 -0
- package/src/plugins/builtin/shared/open-description.ts +29 -0
- package/src/plugins/builtin/shared/report-freshness.ts +9 -0
- package/src/plugins/builtin/shared/series-warning.ts +5 -0
- package/src/plugins/builtin/short-interest/headless.ts +1 -0
- package/src/plugins/builtin/short-interest/index.tsx +2 -0
- package/src/plugins/builtin/short-interest/series.ts +36 -0
- package/src/plugins/builtin/short-interest/watch-headless.ts +1 -0
- package/src/plugins/builtin/short-interest/watch-model.ts +9 -5
- package/src/plugins/builtin/short-volume/headless.ts +1 -0
- package/src/plugins/builtin/short-volume/index.tsx +2 -0
- package/src/plugins/builtin/short-volume/series.ts +23 -0
- package/src/plugins/builtin/social-mentions/index.tsx +2 -0
- package/src/plugins/builtin/social-mentions/series.ts +23 -0
- package/src/plugins/builtin/supply-chain/graph-pane.tsx +3 -2
- package/src/plugins/builtin/supply-chain/pane.tsx +3 -1
- package/src/plugins/builtin/thirteenf/api.ts +1 -0
- package/src/plugins/builtin/thirteenf/data.ts +6 -4
- package/src/plugins/builtin/thirteenf/headless.ts +217 -36
- package/src/plugins/builtin/thirteenf/model.ts +39 -1
- package/src/plugins/builtin/thirteenf/overlap.ts +75 -0
- package/src/plugins/builtin/thirteenf/pane.tsx +10 -1
- package/src/plugins/builtin/thirteenf/report-notes.ts +103 -1
- package/src/plugins/builtin/thirteenf/types.ts +2 -0
- package/src/plugins/builtin/ticker-detail/index.tsx +3 -0
- package/src/plugins/builtin/ticker-detail/overview/components.tsx +1 -1
- package/src/plugins/builtin/ticker-detail/overview/futures-contract.ts +31 -0
- package/src/plugins/builtin/ticker-detail/overview/model.ts +3 -3
- package/src/plugins/builtin/ticker-detail/overview/pane.tsx +2 -1
- package/src/plugins/builtin/ticker-detail/overview-tab.tsx +48 -4
- package/src/plugins/builtin/ticker-detail/quote-monitor/index.tsx +13 -3
- package/src/plugins/builtin/time-sales/headless.ts +1 -0
- package/src/plugins/builtin/treasury-auctions/headless.ts +16 -2
- package/src/plugins/builtin/treasury-auctions/index.tsx +1 -0
- package/src/plugins/builtin/treasury-auctions/model.ts +8 -0
- package/src/plugins/builtin/vol-surface/headless.ts +1 -0
- package/src/plugins/builtin/volatility/index.tsx +2 -0
- package/src/plugins/builtin/volatility/series.ts +84 -0
- package/src/plugins/builtin/world-venue-map/geo-series.ts +26 -1
- package/src/plugins/builtin/world-venue-map/headless.ts +4 -1
- package/src/plugins/builtin/world-venue-map/index.ts +2 -1
- package/src/plugins/builtin/world-venue-map/layered-pane.tsx +8 -4
- package/src/plugins/builtin/world-venue-map/layers.ts +29 -0
- package/src/plugins/builtin/yield-curve/chart.ts +2 -2
- package/src/plugins/builtin/yield-curve/curves.ts +21 -8
- package/src/plugins/builtin/yield-curve/headless.ts +71 -18
- package/src/plugins/builtin/yield-curve/index.tsx +3 -1
- package/src/plugins/builtin/yield-curve/series.ts +86 -0
- package/src/plugins/catalog-browser.ts +2 -1
- package/src/plugins/registry/index.ts +89 -4
- package/src/{plugins/builtin/portfolio-list → portfolio}/position-metrics.ts +6 -6
- package/src/portfolio/position-value.ts +40 -0
- package/src/public/__snapshots__/public-api.test.ts.snap +7 -0
- package/src/public/time-series.ts +17 -0
- package/src/react/auto-refresh.ts +13 -3
- package/src/remote/app-host.tsx +20 -4
- package/src/remote/confirm-change.tsx +85 -0
- package/src/remote/controller-utils.ts +8 -1
- package/src/remote/controller.ts +123 -6
- package/src/remote/pane-screenshot.ts +47 -0
- package/src/remote/schema.ts +62 -0
- package/src/remote/types.ts +30 -0
- package/src/remote/watchlist.ts +306 -0
- package/src/renderers/browser/main.tsx +3 -2
- package/src/renderers/cloudflare/worker.ts +1 -1
- package/src/renderers/dom/data-table/frozen-column.ts +3 -1
- package/src/renderers/dom/data-table/index.tsx +33 -6
- package/src/renderers/dom/data-table/row.tsx +27 -1
- package/src/renderers/dom/desktop/control-styles.ts +63 -1
- package/src/renderers/dom/desktop/controls.tsx +30 -23
- package/src/renderers/dom/desktop/dialog-actions.tsx +170 -0
- package/src/renderers/dom/desktop/icons.tsx +7 -0
- package/src/renderers/dom/dom-ui-host.tsx +3 -0
- package/src/renderers/dom/host/box.tsx +3 -0
- package/src/renderers/dom/host/chart-surface.tsx +6 -2
- package/src/renderers/dom/host/live-frame.ts +6 -2
- package/src/renderers/dom/host/overflow-fade.ts +14 -1
- package/src/renderers/dom/host/size-observer.ts +26 -0
- package/src/renderers/dom/host/surface-3d.tsx +7 -2
- package/src/renderers/dom/host/text.tsx +1 -1
- package/src/renderers/dom/styles.css +61 -0
- package/src/renderers/electrobun/view/cli-pane-shot-entry.tsx +17 -2
- package/src/renderers/electrobun/view/cli-pane-shot-frame.tsx +19 -11
- package/src/renderers/electrobun/view/cli-pane-shot-health.ts +10 -26
- package/src/renderers/electrobun/view/main.tsx +2 -0
- package/src/series/capability.ts +75 -0
- package/src/series/csv.ts +160 -0
- package/src/series/files.ts +107 -0
- package/src/series/registry.ts +198 -0
- package/src/series/resolve.ts +107 -0
- package/src/series/standalone.ts +48 -0
- package/src/series/types.ts +145 -0
- package/src/series/validate.ts +171 -0
- package/src/sources/gloomberb-cloud/index.ts +7 -7
- package/src/sources/gloomberb-cloud/normalizers.ts +1 -0
- package/src/sources/history-result.ts +1 -0
- package/src/sources/listing-symbols.ts +4 -1
- package/src/sources/provider-router/batches.ts +4 -1
- package/src/sources/provider-router/cache.ts +4 -2
- package/src/sources/provider-router/cached-routes.ts +1 -1
- package/src/sources/provider-router/financial-routes.ts +1 -0
- package/src/sources/provider-router/financials.ts +13 -0
- package/src/sources/provider-router/history.ts +43 -25
- package/src/sources/provider-router/search.ts +1 -0
- package/src/sync/core-contributors.ts +1 -0
- package/src/tickers/company-name.ts +75 -0
- package/src/tickers/instrument-kind.ts +25 -0
- package/src/tickers/open-target.ts +3 -2
- package/src/tickers/search/index.ts +45 -7
- package/src/tickers/search/ranking.ts +33 -17
- package/src/tickers/search/types.ts +7 -1
- package/src/tickers/us-listing.ts +34 -0
- package/src/time-series/hooks.ts +9 -0
- package/src/time-series/resolve.ts +95 -16
- package/src/time-series/types.ts +4 -2
- package/src/time-series/use-chart-resolution.ts +32 -0
- package/src/types/config.ts +6 -0
- package/src/types/data-provider.ts +5 -0
- package/src/types/financials.ts +52 -1
- package/src/types/headless.ts +61 -0
- package/src/types/plugin.ts +19 -0
- package/src/types/price-history.ts +7 -0
- package/src/types/ticker.ts +14 -0
- package/src/ui/host.tsx +18 -0
- package/src/ui/live-resize.ts +81 -0
- package/src/ui/live-stretch.ts +121 -0
- package/src/ui/measured-cells.ts +58 -0
- package/src/ui/pane-fill.ts +11 -0
- package/src/utils/basis-points.ts +17 -0
- package/src/utils/cli-output.ts +7 -1
- package/src/utils/concurrency.ts +25 -0
- package/src/utils/crypto-pair.ts +20 -0
- package/src/utils/currency-pair.ts +19 -0
- package/src/utils/decimal-comma.ts +19 -0
- package/src/utils/dom-screenshot-css.ts +265 -0
- package/src/utils/dom-screenshot-rasters.ts +276 -0
- package/src/utils/dom-screenshot.ts +437 -52
- package/src/utils/exchange-rate-snapshot.ts +6 -2
- package/src/utils/exchanges.ts +107 -1
- package/src/utils/format.ts +16 -3
- package/src/utils/fundamentals.ts +66 -0
- package/src/utils/futures-generic.ts +6 -12
- package/src/utils/fx-market-hours.ts +15 -5
- package/src/utils/price-history.ts +99 -42
- package/src/utils/sec-eps-basis.ts +24 -11
- package/src/utils/sec.ts +61 -7
- package/src/utils/utc-time.ts +51 -4
- package/src/plugins/builtin/fx-matrix/freshness.ts +0 -65
- /package/src/{plugins/builtin/cloud → tickers}/starter-symbols.ts +0 -0
|
@@ -2,14 +2,16 @@ import { join } from "path";
|
|
|
2
2
|
import { VERSION } from "../../version";
|
|
3
3
|
import { saveConfig } from "../../data/config/store";
|
|
4
4
|
import { builtinPluginGroupMembers } from "../../plugins/ownership";
|
|
5
|
-
import type { TelemetryConfig } from "../../types/config";
|
|
5
|
+
import type { AppConfig, TelemetryConfig } from "../../types/config";
|
|
6
|
+
import { canonicalTimeZone } from "../../utils/utc-time";
|
|
6
7
|
import type { CliCommandDef } from "../../types/plugin";
|
|
7
|
-
import { withCliServices, withConfigData } from "../context";
|
|
8
|
+
import { resolveCliDataDir, withCliServices, withConfigData } from "../context";
|
|
8
9
|
import { CLI_COMMAND_GROUPS } from "../help";
|
|
9
10
|
import { dryRunNote, formatBytes, formatStatusCell } from "../helpers";
|
|
10
11
|
import { cliStyles, cliTerminalWidth, renderSection, renderTable, wrapText } from "../../utils/cli-output";
|
|
11
12
|
import { getThemeIds } from "../../theme/themes";
|
|
12
13
|
import { requireArg } from "./command-utils";
|
|
14
|
+
import { fail } from "../errors";
|
|
13
15
|
import { describeThemeId, requireThemeId, themeListNote, themeListRows, themeName } from "./themes";
|
|
14
16
|
import {
|
|
15
17
|
applyKeybindingCliSet,
|
|
@@ -27,6 +29,10 @@ const TELEMETRY_CONFIG_KEYS = {
|
|
|
27
29
|
type TelemetryConfigKey = keyof typeof TELEMETRY_CONFIG_KEYS;
|
|
28
30
|
/** The one-time GitHub star line in the terminal's status bar. */
|
|
29
31
|
const STAR_PROMPT_CONFIG_KEY = "starPrompt.enabled";
|
|
32
|
+
/** The zone CLI text shows local times in, beside UTC. */
|
|
33
|
+
const TIMEZONE_CONFIG_KEY = "timezone";
|
|
34
|
+
/** What `config set timezone` takes to go back to UTC alone. */
|
|
35
|
+
const NO_TIMEZONE = "none";
|
|
30
36
|
const EDITABLE_CONFIG_KEYS = [
|
|
31
37
|
"baseCurrency",
|
|
32
38
|
"refreshIntervalMinutes",
|
|
@@ -34,6 +40,7 @@ const EDITABLE_CONFIG_KEYS = [
|
|
|
34
40
|
"valueFlashingEnabled",
|
|
35
41
|
...Object.keys(TELEMETRY_CONFIG_KEYS),
|
|
36
42
|
STAR_PROMPT_CONFIG_KEY,
|
|
43
|
+
TIMEZONE_CONFIG_KEY,
|
|
37
44
|
];
|
|
38
45
|
|
|
39
46
|
function isTelemetryConfigKey(key: string): key is TelemetryConfigKey {
|
|
@@ -44,6 +51,19 @@ function isBooleanConfigKey(key: string): boolean {
|
|
|
44
51
|
return key === "valueFlashingEnabled" || key === STAR_PROMPT_CONFIG_KEY || isTelemetryConfigKey(key);
|
|
45
52
|
}
|
|
46
53
|
|
|
54
|
+
/** The canonical zone name `config set timezone` stores, or null to clear it; fails on a name that is not a zone. */
|
|
55
|
+
function parseTimezoneSetting(value: string): string | null {
|
|
56
|
+
if (value.trim().toLowerCase() === NO_TIMEZONE) return null;
|
|
57
|
+
return canonicalTimeZone(value) ?? fail(
|
|
58
|
+
`"${value.trim()}" is not a time zone name.`,
|
|
59
|
+
`Use an IANA zone name, Region/City, such as Asia/Tokyo, or ${NO_TIMEZONE} for UTC alone.`,
|
|
60
|
+
);
|
|
61
|
+
}
|
|
62
|
+
|
|
63
|
+
function describeTimezone(value: unknown): string {
|
|
64
|
+
return typeof value === "string" && value ? value : "not set, times print in UTC alone";
|
|
65
|
+
}
|
|
66
|
+
|
|
47
67
|
function describeConfigValue(value: unknown): string {
|
|
48
68
|
if (value == null) return "nothing";
|
|
49
69
|
if (Array.isArray(value)) return value.length > 0 ? value.join(", ") : "nothing";
|
|
@@ -51,6 +71,11 @@ function describeConfigValue(value: unknown): string {
|
|
|
51
71
|
return String(value);
|
|
52
72
|
}
|
|
53
73
|
|
|
74
|
+
function withTimezone(config: AppConfig, timezone: string | null): AppConfig {
|
|
75
|
+
const { timezone: _previous, ...rest } = config;
|
|
76
|
+
return timezone ? { ...rest, timezone } : rest;
|
|
77
|
+
}
|
|
78
|
+
|
|
54
79
|
function summarizeKeybindings(value: unknown): string {
|
|
55
80
|
const described = value as { actions?: Record<string, unknown>; commands?: Record<string, unknown>; issues?: unknown[] };
|
|
56
81
|
const parts = [
|
|
@@ -122,9 +147,11 @@ export function createSystemCliCommands(): CliCommandDef[] {
|
|
|
122
147
|
description: "Print the version, runtime, and data folder",
|
|
123
148
|
help: { group: CLI_COMMAND_GROUPS.app, usage: ["version"] },
|
|
124
149
|
execute: async (_args, ctx) => {
|
|
150
|
+
// Where the data lives, or will once a command or the app first runs:
|
|
151
|
+
// printing the version never creates the folder.
|
|
125
152
|
let dataDir: string | null = null;
|
|
126
153
|
try {
|
|
127
|
-
dataDir = await
|
|
154
|
+
dataDir = await resolveCliDataDir();
|
|
128
155
|
} catch {
|
|
129
156
|
dataDir = null;
|
|
130
157
|
}
|
|
@@ -148,7 +175,11 @@ export function createSystemCliCommands(): CliCommandDef[] {
|
|
|
148
175
|
const checks: Array<{ check: string; status: string; detail: string }> = [];
|
|
149
176
|
try {
|
|
150
177
|
await withCliServices(ctx, async (services) => {
|
|
151
|
-
checks.push({
|
|
178
|
+
checks.push({
|
|
179
|
+
check: "config",
|
|
180
|
+
status: "ok",
|
|
181
|
+
detail: services.createdDataDir ? `${services.dataDir} (created now)` : services.dataDir,
|
|
182
|
+
});
|
|
152
183
|
checks.push({ check: "database", status: "ok", detail: join(services.dataDir, ".gloomberb-cache.db") });
|
|
153
184
|
checks.push({ check: "plugins", status: "ok", detail: String(services.services.pluginRegistry.allPlugins.size) });
|
|
154
185
|
checks.push({ check: "capabilities", status: "ok", detail: String(services.services.pluginRegistry.capabilities.manifests().length) });
|
|
@@ -187,6 +218,7 @@ export function createSystemCliCommands(): CliCommandDef[] {
|
|
|
187
218
|
"config set telemetry.crashReports false",
|
|
188
219
|
"config set telemetry.usage false",
|
|
189
220
|
"config set starPrompt.enabled false",
|
|
221
|
+
"config set timezone <Region/City>|none",
|
|
190
222
|
"config get keybindings",
|
|
191
223
|
"config set keybindings.actions.<action> <keys>|null|default",
|
|
192
224
|
"config set keybindings.commands.<keys> <command>|null",
|
|
@@ -194,6 +226,11 @@ export function createSystemCliCommands(): CliCommandDef[] {
|
|
|
194
226
|
sections: [{
|
|
195
227
|
title: "Editable keys",
|
|
196
228
|
lines: [`${EDITABLE_CONFIG_KEYS.join(", ")}, and keybindings.*`],
|
|
229
|
+
}, {
|
|
230
|
+
title: "Time zone",
|
|
231
|
+
lines: [
|
|
232
|
+
"Times print in UTC. timezone takes an IANA zone name such as Asia/Tokyo or America/New_York, and CLI text and function reports then show your local time beside every UTC time. Trading days keep their market's date. none goes back to UTC alone. JSON and CSV keep the raw values.",
|
|
233
|
+
],
|
|
197
234
|
}, {
|
|
198
235
|
title: "Themes",
|
|
199
236
|
lines: [
|
|
@@ -205,6 +242,7 @@ export function createSystemCliCommands(): CliCommandDef[] {
|
|
|
205
242
|
"config themes",
|
|
206
243
|
"config set theme colorblind",
|
|
207
244
|
"config set baseCurrency EUR",
|
|
245
|
+
"config set timezone Asia/Tokyo",
|
|
208
246
|
"config get keybindings",
|
|
209
247
|
"config set keybindings.actions.ticker-search \"Ctrl+T\"",
|
|
210
248
|
"config set keybindings.commands.Alt+1 \"DES AAPL\"",
|
|
@@ -248,6 +286,7 @@ export function createSystemCliCommands(): CliCommandDef[] {
|
|
|
248
286
|
"telemetry.usage": context.config.telemetry?.usage !== false,
|
|
249
287
|
"telemetry.attention": context.config.telemetry?.attention === true,
|
|
250
288
|
[STAR_PROMPT_CONFIG_KEY]: context.config.starPrompt?.enabled !== false,
|
|
289
|
+
[TIMEZONE_CONFIG_KEY]: context.config.timezone ?? null,
|
|
251
290
|
};
|
|
252
291
|
|
|
253
292
|
if (action === "list") {
|
|
@@ -257,6 +296,7 @@ export function createSystemCliCommands(): CliCommandDef[] {
|
|
|
257
296
|
header: key,
|
|
258
297
|
...(key === KEYBINDINGS_CONFIG_KEY ? { format: summarizeKeybindings } : {}),
|
|
259
298
|
...(key === "theme" ? { format: (value: unknown) => describeThemeId(String(value)) } : {}),
|
|
299
|
+
...(key === TIMEZONE_CONFIG_KEY ? { format: describeTimezone } : {}),
|
|
260
300
|
})),
|
|
261
301
|
});
|
|
262
302
|
return;
|
|
@@ -274,7 +314,8 @@ export function createSystemCliCommands(): CliCommandDef[] {
|
|
|
274
314
|
return;
|
|
275
315
|
}
|
|
276
316
|
ctx.printResult({ data: { key, value: safeConfig[key] } }, {
|
|
277
|
-
text: (data) => key === KEYBINDINGS_CONFIG_KEY ? renderKeybindings(data.value)
|
|
317
|
+
text: (data) => key === KEYBINDINGS_CONFIG_KEY ? renderKeybindings(data.value)
|
|
318
|
+
: key === TIMEZONE_CONFIG_KEY ? describeTimezone(data.value) : describeConfigValue(data.value),
|
|
278
319
|
});
|
|
279
320
|
return;
|
|
280
321
|
}
|
|
@@ -309,7 +350,9 @@ export function createSystemCliCommands(): CliCommandDef[] {
|
|
|
309
350
|
// A display name may come unquoted: config set theme White Phosphor.
|
|
310
351
|
const parsedValue = key === "theme"
|
|
311
352
|
? requireThemeId(args.slice(2).join(" "))
|
|
312
|
-
: key ===
|
|
353
|
+
: key === TIMEZONE_CONFIG_KEY
|
|
354
|
+
? parseTimezoneSetting(value)
|
|
355
|
+
: key === "refreshIntervalMinutes"
|
|
313
356
|
? Number(value)
|
|
314
357
|
: isBooleanConfigKey(key)
|
|
315
358
|
? value === "true"
|
|
@@ -318,7 +361,9 @@ export function createSystemCliCommands(): CliCommandDef[] {
|
|
|
318
361
|
? { ...context.config, telemetry: { ...context.config.telemetry, [TELEMETRY_CONFIG_KEYS[key]]: parsedValue as boolean } }
|
|
319
362
|
: key === STAR_PROMPT_CONFIG_KEY
|
|
320
363
|
? { ...context.config, starPrompt: { ...context.config.starPrompt, enabled: parsedValue as boolean } }
|
|
321
|
-
:
|
|
364
|
+
: key === TIMEZONE_CONFIG_KEY
|
|
365
|
+
? withTimezone(context.config, parsedValue as string | null)
|
|
366
|
+
: { ...context.config, [key]: parsedValue };
|
|
322
367
|
if (!ctx.cliOptions.dryRun) await saveConfig(nextConfig);
|
|
323
368
|
ctx.printResult({
|
|
324
369
|
data: {
|
|
@@ -329,7 +374,9 @@ export function createSystemCliCommands(): CliCommandDef[] {
|
|
|
329
374
|
...(key === "theme" ? { name: themeName(String(parsedValue)) } : {}),
|
|
330
375
|
},
|
|
331
376
|
}, {
|
|
332
|
-
text: (data) =>
|
|
377
|
+
text: (data) => key === TIMEZONE_CONFIG_KEY && data.value == null
|
|
378
|
+
? `Cleared timezone: times print in UTC alone.${dryRunNote(data.dryRun)}`
|
|
379
|
+
: `Set ${key} to ${key === "theme" ? describeThemeId(String(data.value)) : describeConfigValue(data.value)}.${dryRunNote(data.dryRun)}`,
|
|
333
380
|
});
|
|
334
381
|
return;
|
|
335
382
|
}
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
import { formatShortDate, parseDisplayDate } from "../../utils/datetime-format";
|
|
2
2
|
import { formatReportedMoney } from "../../utils/reported-money";
|
|
3
|
-
import { fundamentalsCurrency, reportedEnterpriseValue } from "../../utils/fundamentals";
|
|
3
|
+
import { convertedPriceEarningsNote, epsConversionNote, fundamentalsCurrency, reportedEnterpriseValue, ttmConversionNote } from "../../utils/fundamentals";
|
|
4
4
|
import { latestFinancialPeriod } from "../../utils/latest-financial-period";
|
|
5
5
|
import { exportedFundamentals, formatPriceEarnings, priceEarningsOnEarnings } from "../../utils/price-earnings";
|
|
6
6
|
import { describeFundamentalMarketCap, selectMarketCapitalization } from "../../utils/market-capitalization";
|
|
@@ -29,14 +29,17 @@ import {
|
|
|
29
29
|
getRegularSessionDisplay,
|
|
30
30
|
marketStateLabel,
|
|
31
31
|
} from "../../market-data/market/status";
|
|
32
|
+
import type { FuturesContractTermsPayload } from "../../api-client/futures-curve";
|
|
33
|
+
import { futuresContractLines, futuresSettleText, isFuturesInstrument, loadFuturesContractTerms } from "../../market-data/futures-contract";
|
|
32
34
|
import type { AppConfig } from "../../types/config";
|
|
33
35
|
import type { FinancialStatement, TickerFinancials } from "../../types/financials";
|
|
34
36
|
import { computeTickerPriceReturns } from "../../market-data/ticker-price-returns";
|
|
37
|
+
import { instrumentTypeLabel, isCryptoVenuePerpetual } from "../../tickers/instrument-kind";
|
|
35
38
|
import type { SecFilingItem } from "../../types/data-provider";
|
|
36
39
|
import type { NewsArticle } from "../../news/types";
|
|
37
40
|
import type { TickerRecord } from "../../types/ticker";
|
|
38
41
|
import type { CliCommandContext } from "../../types/plugin";
|
|
39
|
-
import { getPortfolioPositionMetrics, getPortfolioQuoteDisplay, resolvePortfolioMarketValue, resolvePortfolioPositionPnl } from "../../
|
|
42
|
+
import { getPortfolioPositionMetrics, getPortfolioQuoteDisplay, resolvePortfolioMarketValue, resolvePortfolioPositionPnl } from "../../portfolio/position-metrics";
|
|
40
43
|
import { createBaseConverter } from "../base-converter";
|
|
41
44
|
import { initMarketData, withMarketData } from "../context";
|
|
42
45
|
import { fail } from "../errors";
|
|
@@ -53,7 +56,9 @@ import {
|
|
|
53
56
|
import { NotesFiles } from "../../plugins/builtin/notes/files";
|
|
54
57
|
import { isKnownNonUsListing } from "../../utils/sec";
|
|
55
58
|
import { canonicalExchange, exchangeLabel, isKnownExchangeCode } from "../../utils/exchanges";
|
|
56
|
-
import {
|
|
59
|
+
import {
|
|
60
|
+
failIfNotTraded, ListingArgError, listingChoiceNotes, listingIdentity, loadBareVenues, resolveCliListing, type CliListing,
|
|
61
|
+
} from "../listing-arg";
|
|
57
62
|
import { isNotATickerMessage } from "../not-a-ticker";
|
|
58
63
|
import { sharesOutstandingInReceipts } from "../../utils/depositary-receipt";
|
|
59
64
|
import { cliFreshnessFooter } from "../result";
|
|
@@ -74,6 +79,25 @@ interface TickerCommandDependencies {
|
|
|
74
79
|
initMarketData?: () => Promise<MarketContext>;
|
|
75
80
|
fail?: (message: string, details?: string) => never;
|
|
76
81
|
printResult?: CliCommandContext["printResult"];
|
|
82
|
+
/** A futures symbol's contract terms and settlement; a failure leaves them out of the report. */
|
|
83
|
+
futuresContract?: (symbol: string) => Promise<FuturesContractTermsPayload | null>;
|
|
84
|
+
}
|
|
85
|
+
|
|
86
|
+
/**
|
|
87
|
+
* A futures symbol's contract terms and latest confirmed settlement. Any other
|
|
88
|
+
* symbol is not looked up, and a failed request leaves both out of the report.
|
|
89
|
+
*/
|
|
90
|
+
export async function cliFuturesContract(
|
|
91
|
+
symbol: string,
|
|
92
|
+
instrumentType: string | undefined,
|
|
93
|
+
load: (symbol: string) => Promise<FuturesContractTermsPayload | null> = loadFuturesContractTerms,
|
|
94
|
+
): Promise<FuturesContractTermsPayload | null> {
|
|
95
|
+
return isFuturesInstrument(symbol, instrumentType) ? load(symbol).catch(() => null) : null;
|
|
96
|
+
}
|
|
97
|
+
|
|
98
|
+
/** The Contract block as `ticker` and `quote` print it; a contract past first notice is in the warning colour. */
|
|
99
|
+
export function futuresContractMetrics(terms: FuturesContractTermsPayload, symbol: string): Array<[string, string]> {
|
|
100
|
+
return futuresContractLines(terms, symbol).map((line) => [line.label, line.warning ? cliStyles.warning(line.value) : line.value]);
|
|
77
101
|
}
|
|
78
102
|
|
|
79
103
|
function appendMetricSection(lines: string[], title: string, metrics: Array<[string, string]>) {
|
|
@@ -316,7 +340,7 @@ function fundamentalsMetrics(
|
|
|
316
340
|
{ label: "Forward P/E", ...multipleFigure(priceEarningsOnEarnings(fundamentals?.forwardPE, fundamentals?.forwardEps)) },
|
|
317
341
|
{ label: "PEG", ...multipleFigure(fundamentals?.pegRatio) },
|
|
318
342
|
// The flows and EPS are one trailing-twelve-month block, the same twelve months for each line.
|
|
319
|
-
{ label: "EPS (TTM)", ...reportedMoney(fundamentals?.eps, reportingCurrency, true) },
|
|
343
|
+
{ label: "EPS (TTM)", ...reportedMoney(fundamentals?.eps, fundamentals?.epsCurrency?.trim() || reportingCurrency, true) },
|
|
320
344
|
{
|
|
321
345
|
label: `Dividend Yield${fundamentals?.dividendYieldBasis ? ` (${fundamentals.dividendYieldBasis})` : ""}`,
|
|
322
346
|
...percentFigure(fundamentals?.dividendYield, formatFractionPercentCell),
|
|
@@ -345,6 +369,26 @@ function metricLines(metrics: readonly FundamentalsMetric[]): Array<[string, str
|
|
|
345
369
|
return metrics.map((metric) => [metric.label, metric.text]);
|
|
346
370
|
}
|
|
347
371
|
|
|
372
|
+
const TRAILING_MONEY_METRICS = new Set(["EPS (TTM)", "Revenue (TTM)", "Net Income (TTM)", "Operating Cash Flow (TTM)", "Free Cash Flow (TTM)"]);
|
|
373
|
+
|
|
374
|
+
/**
|
|
375
|
+
* The unit notes under shown fundamentals: what a converted TTM block was converted from, an EPS in another
|
|
376
|
+
* currency than the amounts beside it, and what a P/E on such an EPS divides.
|
|
377
|
+
*/
|
|
378
|
+
function trailingConversionNotes(
|
|
379
|
+
fundamentals: TickerFinancials["fundamentals"],
|
|
380
|
+
metrics: readonly FundamentalsMetric[],
|
|
381
|
+
quoteCurrency: string | undefined,
|
|
382
|
+
): string[] {
|
|
383
|
+
const shown = (label: string) => metrics.some((metric) => metric.label === label && metric.text !== "—");
|
|
384
|
+
const conversion = [...TRAILING_MONEY_METRICS].some(shown) ? ttmConversionNote(fundamentals) : undefined;
|
|
385
|
+
const eps = shown("EPS (TTM)") ? epsConversionNote(fundamentals) : undefined;
|
|
386
|
+
const priceEarnings = metrics.some((metric) => metric.label === "P/E (TTM)" && typeof metric.value === "number")
|
|
387
|
+
? convertedPriceEarningsNote(fundamentals, quoteCurrency)
|
|
388
|
+
: undefined;
|
|
389
|
+
return [conversion, eps, priceEarnings].filter((note): note is string => !!note);
|
|
390
|
+
}
|
|
391
|
+
|
|
348
392
|
const VALUATION_METRICS = new Set(["Market Cap", "Enterprise Value", "P/E (TTM)", "Forward P/E", "PEG", "EPS (TTM)"]);
|
|
349
393
|
|
|
350
394
|
type FundamentalsReportData = TickerFinancials & { symbol: string; exchange?: string };
|
|
@@ -381,8 +425,10 @@ export function renderFundamentalsReport(
|
|
|
381
425
|
if (profileParts.length > 0) lines.push(cliStyles.muted(profileParts.join(METADATA_SEPARATOR)));
|
|
382
426
|
|
|
383
427
|
const before = lines.length;
|
|
384
|
-
|
|
428
|
+
const metrics = fundamentalsReportMetrics(financials, view);
|
|
429
|
+
appendMetricSection(lines, view === "valuation" ? "Valuation" : "Fundamentals", metricLines(metrics));
|
|
385
430
|
if (lines.length === before) lines.push("", cliStyles.muted(`No ${view} reported for ${financials.symbol}.`));
|
|
431
|
+
for (const note of trailingConversionNotes(financials.fundamentals, metrics, quote?.currency)) lines.push(cliStyles.muted(note));
|
|
386
432
|
if (view === "fundamentals") appendTextSection(lines, "Description", profile?.description);
|
|
387
433
|
return lines.join("\n");
|
|
388
434
|
}
|
|
@@ -418,7 +464,9 @@ export function fundamentalsReportTables(
|
|
|
418
464
|
tables,
|
|
419
465
|
footer: reportFooterLines({
|
|
420
466
|
freshness,
|
|
421
|
-
notes: metrics.length === 0
|
|
467
|
+
notes: metrics.length === 0
|
|
468
|
+
? [`No ${view} reported for ${financials.symbol}.`]
|
|
469
|
+
: trailingConversionNotes(financials.fundamentals, metrics, financials.quote?.currency),
|
|
422
470
|
}),
|
|
423
471
|
};
|
|
424
472
|
}
|
|
@@ -444,12 +492,16 @@ export async function buildTickerReport({
|
|
|
444
492
|
toBase,
|
|
445
493
|
notes,
|
|
446
494
|
quoteNote,
|
|
495
|
+
listingNote,
|
|
447
496
|
recentNews = [],
|
|
448
497
|
recentSecFilings = [],
|
|
498
|
+
futuresContract = null,
|
|
449
499
|
}: {
|
|
450
500
|
symbol: string;
|
|
451
501
|
/** The exchange the command named, as a canonical code. */
|
|
452
502
|
listingExchange?: string;
|
|
503
|
+
/** A futures symbol's contract terms and latest confirmed settlement. */
|
|
504
|
+
futuresContract?: FuturesContractTermsPayload | null;
|
|
453
505
|
tickerFile: TickerRecord | null;
|
|
454
506
|
financials: TickerFinancials;
|
|
455
507
|
config: AppConfig;
|
|
@@ -457,6 +509,8 @@ export async function buildTickerReport({
|
|
|
457
509
|
notes?: string;
|
|
458
510
|
/** Why there is no quote, when a source said; "Quote unavailable." otherwise. */
|
|
459
511
|
quoteNote?: string;
|
|
512
|
+
/** "CAR = Avis Budget Group, NASDAQ (also XETRA, ASX)", for a bare symbol several companies list. */
|
|
513
|
+
listingNote?: string;
|
|
460
514
|
recentNews?: NewsArticle[];
|
|
461
515
|
recentSecFilings?: SecFilingItem[];
|
|
462
516
|
}): Promise<string> {
|
|
@@ -483,10 +537,11 @@ export async function buildTickerReport({
|
|
|
483
537
|
if (summaryParts.length > 0) {
|
|
484
538
|
lines.push(cliStyles.muted(summaryParts.join(METADATA_SEPARATOR)));
|
|
485
539
|
}
|
|
540
|
+
if (listingNote) lines.push(cliStyles.muted(listingNote));
|
|
486
541
|
|
|
487
|
-
const instrumentType = quote?.instrumentType?.trim()
|
|
542
|
+
const instrumentType = instrumentTypeLabel(quote?.instrumentType?.trim()
|
|
488
543
|
|| financials.quoteMetadata?.instrumentType?.trim()
|
|
489
|
-
|| tickerFile?.metadata.assetCategory;
|
|
544
|
+
|| tickerFile?.metadata.assetCategory, name, { detail: true });
|
|
490
545
|
const metadataParts = [
|
|
491
546
|
instrumentType ? `Type ${instrumentType}` : undefined,
|
|
492
547
|
(tickerFile?.metadata.sector || profile?.sector) ? `Sector ${tickerFile?.metadata.sector || profile?.sector}` : undefined,
|
|
@@ -537,8 +592,12 @@ export async function buildTickerReport({
|
|
|
537
592
|
extended.change,
|
|
538
593
|
)
|
|
539
594
|
: "—";
|
|
595
|
+
// A futures price is its latest trade; the exchange settlement is its own row, dated by its session.
|
|
540
596
|
appendMetricSection(lines, "Quote", [
|
|
541
597
|
["Last", colorBySign(formatMarketPriceWithCurrency(session.price, quote.currency, quoteOptions), session.change)],
|
|
598
|
+
...futuresContract
|
|
599
|
+
? [["Settle", futuresSettleText(futuresContract, quote)] as [string, string]]
|
|
600
|
+
: [],
|
|
542
601
|
["Change", colorBySign(`${formatMarketChangeWithCurrency(session.change, quote.currency, quoteOptions, session.price)} (${formatPercentRaw(session.changePercent)})`, session.change)],
|
|
543
602
|
["Open", quote.open != null ? formatMarketPriceWithCurrency(quote.open, quote.currency, quoteOptions) : "—"],
|
|
544
603
|
["Day Range", quote.low != null || quote.high != null
|
|
@@ -548,17 +607,23 @@ export async function buildTickerReport({
|
|
|
548
607
|
? formatPriceRange(quote.low52w, quote.high52w, quote.currency, quoteOptions)
|
|
549
608
|
: "—"],
|
|
550
609
|
["Bid / Ask", formatBidAsk(quote.bid, quote.ask, quote.bidSize, quote.askSize, quote.currency, quoteOptions)],
|
|
551
|
-
|
|
610
|
+
// A perpetual's price comes with no volume; its 0 means not reported, not no trades.
|
|
611
|
+
["Volume", quote.volume != null && !(quote.volume === 0 && isCryptoVenuePerpetual(quote.instrumentType, quote.name))
|
|
612
|
+
? formatNumber(quote.volume, 0) : "—"],
|
|
552
613
|
["Updated", formatTimestamp(quote.lastUpdated)],
|
|
553
614
|
]);
|
|
554
615
|
|
|
616
|
+
if (futuresContract) appendMetricSection(lines, "Contract", futuresContractMetrics(futuresContract, quote.symbol ?? symbol));
|
|
617
|
+
|
|
555
618
|
appendMetricSection(lines, "Extended Hours", [
|
|
556
619
|
[EXTENDED_SESSION_LABELS.PRE, extendedRow("PRE")],
|
|
557
620
|
[EXTENDED_SESSION_LABELS.POST, extendedRow("POST")],
|
|
558
621
|
]);
|
|
559
622
|
}
|
|
560
623
|
|
|
561
|
-
|
|
624
|
+
const metrics = fundamentalsMetrics(quote, fundamentals, profile, { text: marketCapText }, priceReturns, fundamentalsCurrency(financials), { text: enterpriseValueText });
|
|
625
|
+
appendMetricSection(lines, "Fundamentals", metricLines(metrics));
|
|
626
|
+
for (const note of trailingConversionNotes(fundamentals, metrics, quote?.currency)) lines.push(cliStyles.muted(note));
|
|
562
627
|
|
|
563
628
|
if (capitalization?.provenance.kind === "fundamentals") {
|
|
564
629
|
lines.push(cliStyles.muted(`Market cap: ${describeFundamentalMarketCap(capitalization.provenance)}.`));
|
|
@@ -623,9 +688,11 @@ function buildTickerStructuredData({
|
|
|
623
688
|
notes,
|
|
624
689
|
recentNews,
|
|
625
690
|
recentSecFilings,
|
|
691
|
+
futuresContract,
|
|
626
692
|
}: {
|
|
627
693
|
symbol: string;
|
|
628
694
|
listing: CliListing;
|
|
695
|
+
futuresContract: FuturesContractTermsPayload | null;
|
|
629
696
|
tickerFile: TickerRecord | null;
|
|
630
697
|
financials: TickerFinancials;
|
|
631
698
|
config: AppConfig;
|
|
@@ -657,6 +724,8 @@ function buildTickerStructuredData({
|
|
|
657
724
|
lastUpdated: quote.lastUpdated ? new Date(quote.lastUpdated).toISOString() : "",
|
|
658
725
|
} : null,
|
|
659
726
|
quoteMetadata: financials.quoteMetadata,
|
|
727
|
+
// Only for futures: the contract the symbol prices, its terms and its latest confirmed settlement.
|
|
728
|
+
...futuresContract ? { futuresContract } : {},
|
|
660
729
|
ticker: tickerFile ? {
|
|
661
730
|
ticker: tickerFile.metadata.ticker,
|
|
662
731
|
name: tickerFile.metadata.name ?? "",
|
|
@@ -725,6 +794,8 @@ export async function ticker(symbol: string, dependencies: TickerCommandDependen
|
|
|
725
794
|
const tickerFile = listing.saved;
|
|
726
795
|
const { symbol: requestSymbol, exchange } = listing.request;
|
|
727
796
|
const toBase = createBaseConverter(dataProvider, config.baseCurrency);
|
|
797
|
+
// A bare symbol's venues load beside its research, to name the company it was read as when several list it.
|
|
798
|
+
const venues = loadBareVenues(listing, { store, dataProvider });
|
|
728
799
|
|
|
729
800
|
let financials: TickerFinancials | null = null;
|
|
730
801
|
try {
|
|
@@ -778,6 +849,7 @@ export async function ticker(symbol: string, dependencies: TickerCommandDependen
|
|
|
778
849
|
: Promise.resolve([]),
|
|
779
850
|
]);
|
|
780
851
|
|
|
852
|
+
const futuresContract = await cliFuturesContract(quote?.symbol ?? requestSymbol, quote?.instrumentType, dependencies.futuresContract);
|
|
781
853
|
const notes = notesResult.status === "fulfilled" ? notesResult.value : "";
|
|
782
854
|
const recentNews = newsResult.status === "fulfilled" ? newsResult.value : [];
|
|
783
855
|
const recentSecFilings = secFilingsResult.status === "fulfilled" ? secFilingsResult.value : [];
|
|
@@ -785,10 +857,12 @@ export async function ticker(symbol: string, dependencies: TickerCommandDependen
|
|
|
785
857
|
// The quote is the feed in this report; without one, the fundamentals date it.
|
|
786
858
|
const freshness = quote ? quotesFreshness([quote]) : fundamentalsFreshness(resolvedFinancials);
|
|
787
859
|
const quoteNote = quote ? undefined : await quoteUnavailableNote(dataProvider, requestSymbol, exchange);
|
|
860
|
+
const [listingNote] = await listingChoiceNotes(listing, { store, dataProvider }, quote, venues);
|
|
788
861
|
if (dependencies.printResult) {
|
|
862
|
+
const warnings = [listingNote, quoteNote].filter((note): note is string => !!note);
|
|
789
863
|
dependencies.printResult({
|
|
790
864
|
freshness,
|
|
791
|
-
warnings:
|
|
865
|
+
warnings: warnings.length > 0 ? warnings : undefined,
|
|
792
866
|
data: buildTickerStructuredData({
|
|
793
867
|
symbol: normalized,
|
|
794
868
|
listing,
|
|
@@ -798,6 +872,7 @@ export async function ticker(symbol: string, dependencies: TickerCommandDependen
|
|
|
798
872
|
notes,
|
|
799
873
|
recentNews,
|
|
800
874
|
recentSecFilings,
|
|
875
|
+
futuresContract,
|
|
801
876
|
}),
|
|
802
877
|
});
|
|
803
878
|
return;
|
|
@@ -812,8 +887,10 @@ export async function ticker(symbol: string, dependencies: TickerCommandDependen
|
|
|
812
887
|
toBase,
|
|
813
888
|
notes,
|
|
814
889
|
quoteNote,
|
|
890
|
+
listingNote,
|
|
815
891
|
recentNews,
|
|
816
892
|
recentSecFilings,
|
|
893
|
+
futuresContract,
|
|
817
894
|
}));
|
|
818
895
|
if (freshness) console.log(`\n${cliFreshnessFooter(freshness)}`);
|
|
819
896
|
});
|
package/src/cli/context.ts
CHANGED
|
@@ -1,6 +1,7 @@
|
|
|
1
1
|
import { join } from "path";
|
|
2
|
-
import { existsSync } from "fs";
|
|
3
|
-
import { getDataDir, loadConfig } from "../data/config/store";
|
|
2
|
+
import { existsSync, readFileSync } from "fs";
|
|
3
|
+
import { getDataDir, initDataDir, loadConfig } from "../data/config/store";
|
|
4
|
+
import { getGloomberbDirs } from "../data/config/home";
|
|
4
5
|
import { AppPersistence } from "../data/app-persistence";
|
|
5
6
|
import { TickerRepository } from "../data/ticker-repository";
|
|
6
7
|
import { AssetDataRouter } from "../sources/provider-router";
|
|
@@ -9,6 +10,7 @@ import type { PluginCapability } from "../capabilities";
|
|
|
9
10
|
import type { AppConfig } from "../types/config";
|
|
10
11
|
import type { GloomPlugin } from "../types/plugin";
|
|
11
12
|
import { getLoadablePlugins } from "../plugins/catalog";
|
|
13
|
+
import { standaloneSeriesInvoker } from "../series/standalone";
|
|
12
14
|
import type { PluginRegistry } from "../plugins/registry";
|
|
13
15
|
import type { LoadedExternalPlugin } from "../plugins/loader";
|
|
14
16
|
import { fail } from "./errors";
|
|
@@ -59,13 +61,45 @@ export async function loadCliConfigIfAvailable(): Promise<AppConfig | null> {
|
|
|
59
61
|
return loadConfig(dataDir);
|
|
60
62
|
}
|
|
61
63
|
|
|
62
|
-
|
|
63
|
-
|
|
64
|
-
|
|
65
|
-
|
|
64
|
+
function isUnreadableConfig(configFile: string): boolean {
|
|
65
|
+
try {
|
|
66
|
+
JSON.parse(readFileSync(configFile, "utf-8"));
|
|
67
|
+
return false;
|
|
68
|
+
} catch (error) {
|
|
69
|
+
return (error as NodeJS.ErrnoException).code !== "ENOENT";
|
|
66
70
|
}
|
|
71
|
+
}
|
|
72
|
+
|
|
73
|
+
/** The data folder this profile uses, whether or not anything has created it yet. Never writes. */
|
|
74
|
+
export async function resolveCliDataDir(): Promise<string> {
|
|
75
|
+
return await getDataDir() ?? getGloomberbDirs().data;
|
|
76
|
+
}
|
|
67
77
|
|
|
68
|
-
|
|
78
|
+
/**
|
|
79
|
+
* The data folder and config a command works with. The first command on a new
|
|
80
|
+
* profile creates them with the same `initDataDir` a first launch of the
|
|
81
|
+
* terminal or desktop app runs, so the CLI works before the app was ever
|
|
82
|
+
* opened. That config leaves onboarding unfinished, so the app's first launch
|
|
83
|
+
* still walks through it.
|
|
84
|
+
*
|
|
85
|
+
* A config.json that is there but does not parse would be replaced with
|
|
86
|
+
* defaults by that, so the command fails instead and leaves it for the user.
|
|
87
|
+
*/
|
|
88
|
+
async function openCliDataDir(): Promise<{ dataDir: string; config: AppConfig; created: boolean }> {
|
|
89
|
+
const recorded = await getDataDir();
|
|
90
|
+
if (recorded && existsSync(recorded)) {
|
|
91
|
+
return { dataDir: recorded, config: await loadConfig(recorded), created: false };
|
|
92
|
+
}
|
|
93
|
+
const { configFile, data } = getGloomberbDirs();
|
|
94
|
+
if (!recorded && isUnreadableConfig(configFile)) {
|
|
95
|
+
fail(`Could not read ${configFile}.`, "Fix the file or move it aside; the next command creates a fresh one.");
|
|
96
|
+
}
|
|
97
|
+
const dataDir = recorded ?? data;
|
|
98
|
+
return { dataDir, config: await initDataDir(dataDir), created: true };
|
|
99
|
+
}
|
|
100
|
+
|
|
101
|
+
export async function initConfigData(): Promise<ConfigContext> {
|
|
102
|
+
const { dataDir, config } = await openCliDataDir();
|
|
69
103
|
const persistence = new AppPersistence(join(dataDir, ".gloomberb-cache.db"));
|
|
70
104
|
const store = new TickerRepository(persistence.tickers);
|
|
71
105
|
return { config, persistence, store, dataDir };
|
|
@@ -83,16 +117,12 @@ export async function initMarketData(options: CliContextOptions = {}): Promise<M
|
|
|
83
117
|
dataProvider.attachRegistry(registryAdapter as PluginRegistry);
|
|
84
118
|
dataProvider.setConfigAccessor(() => context.config);
|
|
85
119
|
dataProvider.setBackgroundRevalidation(false);
|
|
86
|
-
|
|
120
|
+
const seriesCapabilities = standaloneSeriesInvoker(plugins, context.dataDir, context.config.disabledPlugins);
|
|
121
|
+
return { ...context, dataProvider, seriesCapabilities };
|
|
87
122
|
}
|
|
88
123
|
|
|
89
124
|
export async function initCliServices(options: CliServicesOptions = {}) {
|
|
90
|
-
const dataDir = await
|
|
91
|
-
if (!dataDir || !existsSync(dataDir)) {
|
|
92
|
-
fail("No data directory configured.", "Run gloomberb once to initialize your local data.");
|
|
93
|
-
}
|
|
94
|
-
|
|
95
|
-
const config = await loadConfig(dataDir);
|
|
125
|
+
const { dataDir, config, created } = await openCliDataDir();
|
|
96
126
|
const services = createAppServices({
|
|
97
127
|
config,
|
|
98
128
|
plugins: getLoadablePlugins(options.externalPlugins ?? []),
|
|
@@ -104,6 +134,7 @@ export async function initCliServices(options: CliServicesOptions = {}) {
|
|
|
104
134
|
return {
|
|
105
135
|
config,
|
|
106
136
|
dataDir,
|
|
137
|
+
createdDataDir: created,
|
|
107
138
|
services,
|
|
108
139
|
dataProvider: services.providerRouter,
|
|
109
140
|
persistence: services.persistence,
|