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
|
@@ -22,6 +22,7 @@ import {
|
|
|
22
22
|
type PaneHint,
|
|
23
23
|
} from "../../../components";
|
|
24
24
|
import { loadingErrorFooterInfo } from "../../../components/data-table/table-pane";
|
|
25
|
+
import { useRowNotes } from "../../../components/ui/row-notes";
|
|
25
26
|
import { colors } from "../../../theme/colors";
|
|
26
27
|
import { t, tf } from "../../../i18n";
|
|
27
28
|
import type { PaneProps } from "../../../types/plugin";
|
|
@@ -68,6 +69,7 @@ import {
|
|
|
68
69
|
versionLabel,
|
|
69
70
|
type MarketplaceEntry,
|
|
70
71
|
type MarketplaceRow,
|
|
72
|
+
type MarketplaceStatus,
|
|
71
73
|
type MarketplaceStatusKind,
|
|
72
74
|
type RegistryPlugin,
|
|
73
75
|
} from "../../marketplace/model";
|
|
@@ -165,7 +167,7 @@ function renderCell(
|
|
|
165
167
|
row: MarketplaceRow,
|
|
166
168
|
column: Column,
|
|
167
169
|
rowState: { selected: boolean },
|
|
168
|
-
|
|
170
|
+
rowStatus: (entry: MarketplaceEntry) => MarketplaceStatus,
|
|
169
171
|
facts: (entry: MarketplaceEntry) => EntryFacts,
|
|
170
172
|
): DataTableCell {
|
|
171
173
|
if (row.type === "header") return { text: "" };
|
|
@@ -192,8 +194,7 @@ function renderCell(
|
|
|
192
194
|
case "tagline":
|
|
193
195
|
return { text: entry.tagline, color: selected ?? colors.textDim };
|
|
194
196
|
case "status": {
|
|
195
|
-
|
|
196
|
-
const status = statusOf(entry);
|
|
197
|
+
const status = rowStatus(entry);
|
|
197
198
|
return { text: status.text, color: selected ?? STATUS_COLORS[status.kind] };
|
|
198
199
|
}
|
|
199
200
|
}
|
|
@@ -212,14 +213,21 @@ function describeContributions(entry: MarketplaceEntry, host: MarketplaceHost |
|
|
|
212
213
|
return parts;
|
|
213
214
|
}
|
|
214
215
|
|
|
215
|
-
function EntryDetail({ entry, width, host
|
|
216
|
+
function EntryDetail({ entry, width, host, status, failure }: {
|
|
217
|
+
entry: MarketplaceEntry;
|
|
218
|
+
width: number;
|
|
219
|
+
host: MarketplaceHost | null;
|
|
220
|
+
/** The row's STATUS. */
|
|
221
|
+
status: MarketplaceStatus;
|
|
222
|
+
/** What the last action on this plugin ran into, said in full. */
|
|
223
|
+
failure: ActionFailure | null;
|
|
224
|
+
}) {
|
|
216
225
|
const contributes = describeContributions(entry, host);
|
|
217
226
|
const live = entry.installed && host ? host.contributions(entry.id) : null;
|
|
218
227
|
const opensWith = live
|
|
219
228
|
? live.templates.map((template) => template.prefix ?? template.label).filter(Boolean)
|
|
220
229
|
: [];
|
|
221
230
|
const rowWidth = Math.max(1, width - 2);
|
|
222
|
-
const status = statusOf(entry);
|
|
223
231
|
|
|
224
232
|
return (
|
|
225
233
|
<ScrollBox flexDirection="column" width={width} flexGrow={1} flexBasis={0} minHeight={0} paddingLeft={1} paddingRight={1} scrollY focusable={false}>
|
|
@@ -236,6 +244,12 @@ function EntryDetail({ entry, width, host }: { entry: MarketplaceEntry; width: n
|
|
|
236
244
|
</Box>
|
|
237
245
|
) : null}
|
|
238
246
|
|
|
247
|
+
{failure ? (
|
|
248
|
+
<Box paddingTop={1} flexDirection="column">
|
|
249
|
+
<Text fg={STATUS_COLORS[failure.kind ?? "failed"]} wrapText>{failure.text}</Text>
|
|
250
|
+
</Box>
|
|
251
|
+
) : null}
|
|
252
|
+
|
|
239
253
|
<Box paddingTop={1} flexDirection="column">
|
|
240
254
|
{contributes.length > 0 ? <KeyValueRow labelWidth={10} width={rowWidth} emphasis={false} label="Adds" value={contributes.join(", ")} /> : null}
|
|
241
255
|
{opensWith.length > 0 ? <KeyValueRow labelWidth={10} width={rowWidth} emphasis={false} label="Opens with" value={opensWith.join(", ")} /> : null}
|
|
@@ -246,7 +260,7 @@ function EntryDetail({ entry, width, host }: { entry: MarketplaceEntry; width: n
|
|
|
246
260
|
*/}
|
|
247
261
|
{entry.hosts.length > 0 ? <KeyValueRow labelWidth={10} width={rowWidth} emphasis={false} label="Declares" value={entry.hosts.join(", ")} /> : null}
|
|
248
262
|
{entry.repo ? <KeyValueRow labelWidth={10} width={rowWidth} emphasis={false} label="Source" value={`github.com/${entry.repo}`} /> : null}
|
|
249
|
-
{entry.minGloomberb ? <KeyValueRow labelWidth={10} width={rowWidth} emphasis={false} label="Requires" value={requiredGloomberb(entry.minGloomberb) ? `
|
|
263
|
+
{entry.minGloomberb ? <KeyValueRow labelWidth={10} width={rowWidth} emphasis={false} label="Requires" value={requiredGloomberb(entry.minGloomberb) ? `Gloom ${entry.minGloomberb}, this is ${VERSION}` : `Gloom ${entry.minGloomberb}`} /> : null}
|
|
250
264
|
{entry.linked ? <KeyValueRow labelWidth={10} width={rowWidth} emphasis={false} label="Linked" value={entry.directory ?? "local checkout"} /> : null}
|
|
251
265
|
{entry.installedCommit ? <KeyValueRow labelWidth={10} width={rowWidth} emphasis={false} label="Commit" value={entry.installedCommit.slice(0, 7)} /> : null}
|
|
252
266
|
{!entry.installed && entry.availableCommit ? <KeyValueRow labelWidth={10} width={rowWidth} emphasis={false} label="Pinned" value={`${entry.availableVersion ?? ""} ${entry.availableCommit.slice(0, 7)}`.trim()} /> : null}
|
|
@@ -259,7 +273,7 @@ function EntryDetail({ entry, width, host }: { entry: MarketplaceEntry; width: n
|
|
|
259
273
|
runsExternalPlugins() ? (
|
|
260
274
|
<Box paddingTop={1} flexDirection="column">
|
|
261
275
|
<Text fg={colors.textDim}>Runs with your full permissions. Read the source first.</Text>
|
|
262
|
-
<Text fg={colors.textBright}>{`
|
|
276
|
+
<Text fg={colors.textBright}>{`gloom install ${entry.repo}`}</Text>
|
|
263
277
|
</Box>
|
|
264
278
|
) : (
|
|
265
279
|
// No shell here, so the install command would be a dead end. Say
|
|
@@ -321,7 +335,7 @@ function BuiltinDetail({ entry, width, facts, scrollRef }: {
|
|
|
321
335
|
<RemoteImage
|
|
322
336
|
key={code}
|
|
323
337
|
src={functionShotUrl(code)}
|
|
324
|
-
alt={`${code} in
|
|
338
|
+
alt={`${code} in Gloom`}
|
|
325
339
|
label={code}
|
|
326
340
|
width={shotWidth}
|
|
327
341
|
height={Math.max(8, Math.floor(shotWidth * 0.3))}
|
|
@@ -400,6 +414,25 @@ function PackChangeBody({ change, name }: { change: PackChange; name: (id: strin
|
|
|
400
414
|
|
|
401
415
|
type Busy = { id: string; verb: "installing" | "updating" | "removing" } | null;
|
|
402
416
|
|
|
417
|
+
/**
|
|
418
|
+
* What the last action on one plugin ran into, said on its row: `status` in
|
|
419
|
+
* STATUS, `text` in its detail. It stands while the row's own status is what
|
|
420
|
+
* it was when the failure first showed, and goes when that moves: a toggle,
|
|
421
|
+
* a restart, a later install.
|
|
422
|
+
*/
|
|
423
|
+
interface ActionFailure {
|
|
424
|
+
status: string;
|
|
425
|
+
text: string;
|
|
426
|
+
/** STATUS's tone; a failure by default. */
|
|
427
|
+
kind?: MarketplaceStatusKind;
|
|
428
|
+
}
|
|
429
|
+
|
|
430
|
+
function statusKey(entry: MarketplaceEntry): string {
|
|
431
|
+
const status = statusOf(entry);
|
|
432
|
+
return `${status.kind}:${status.text}`;
|
|
433
|
+
}
|
|
434
|
+
const entryId = (entry: MarketplaceEntry) => entry.id;
|
|
435
|
+
|
|
403
436
|
export function PluginMarketplacePane({ focused, width, height }: PaneProps) {
|
|
404
437
|
const dialog = useDialog();
|
|
405
438
|
const { createPaneFromTemplate, showPane, openPluginCommandWorkflow, notify } = usePluginAppActions();
|
|
@@ -419,14 +452,15 @@ export function PluginMarketplacePane({ focused, width, height }: PaneProps) {
|
|
|
419
452
|
// Bumped after any local change so the list is re-read from the host.
|
|
420
453
|
const [localRevision, setLocalRevision] = useState(0);
|
|
421
454
|
const [busy, setBusy] = useState<Busy>(null);
|
|
422
|
-
const [lastError, setLastError] = useState<string | null>(null);
|
|
423
455
|
// Remote heads for plugins the registry does not pin, so a private or
|
|
424
456
|
// side-loaded install can report an update like every other row.
|
|
425
457
|
const [remoteHeads, setRemoteHeads] = useState<Record<string, string>>({});
|
|
426
458
|
const [checkingRemotes, setCheckingRemotes] = useState(false);
|
|
427
|
-
const
|
|
459
|
+
const [remoteCheckError, setRemoteCheckError] = useState<string | null>(null);
|
|
460
|
+
const [remoteRevision, setRemoteRevision] = useState(0);
|
|
428
461
|
|
|
429
462
|
const refresh = useCallback((force: boolean) => {
|
|
463
|
+
if (force) setRemoteRevision((value) => value + 1);
|
|
430
464
|
setStatus((current) => (current === "ready" ? current : "loading"));
|
|
431
465
|
void loadRegistry({ force }).then((result) => {
|
|
432
466
|
setRegistry(result.plugins);
|
|
@@ -461,12 +495,22 @@ export function PluginMarketplacePane({ focused, width, height }: PaneProps) {
|
|
|
461
495
|
return facts;
|
|
462
496
|
};
|
|
463
497
|
}, [entries, host]);
|
|
498
|
+
// By plugin id, until the next action on the plugin. A failure takes the
|
|
499
|
+
// row's status as the list shows it after the action, and goes once that
|
|
500
|
+
// status moves on.
|
|
501
|
+
const { noteFor: failureFor, setNote: setFailure } = useRowNotes<MarketplaceEntry, ActionFailure>(entries, { key: entryId, signature: statusKey });
|
|
502
|
+
// What an action on one plugin is doing, or ran into, is said on its row.
|
|
503
|
+
const rowStatus = useCallback((entry: MarketplaceEntry): MarketplaceStatus => {
|
|
504
|
+
if (busy?.id === entry.id) return { kind: "none", text: busy.verb };
|
|
505
|
+
const failure = failureFor(entry);
|
|
506
|
+
return failure ? { kind: failure.kind ?? "failed", text: failure.status } : statusOf(entry);
|
|
507
|
+
}, [busy, failureFor]);
|
|
464
508
|
const renderRow = useCallback((
|
|
465
509
|
row: MarketplaceRow,
|
|
466
510
|
column: Column,
|
|
467
511
|
_index: number,
|
|
468
512
|
rowState: { selected: boolean },
|
|
469
|
-
) => renderCell(row, column, rowState,
|
|
513
|
+
) => renderCell(row, column, rowState, rowStatus, factsFor), [factsFor, rowStatus]);
|
|
470
514
|
|
|
471
515
|
// Keyed by the folders themselves: the entries array is rebuilt whenever an
|
|
472
516
|
// answer lands, and re-running the check on its own result would never stop.
|
|
@@ -477,24 +521,42 @@ export function PluginMarketplacePane({ focused, width, height }: PaneProps) {
|
|
|
477
521
|
const unlistedKey = unlistedDirectories.join(",");
|
|
478
522
|
|
|
479
523
|
useEffect(() => {
|
|
524
|
+
const directories = unlistedKey ? unlistedKey.split(",") : [];
|
|
525
|
+
const eligible = new Set(directories);
|
|
526
|
+
// Forget removed or newly pinned/linked installs, including the last one.
|
|
527
|
+
setRemoteHeads((previous) => {
|
|
528
|
+
const retained = Object.entries(previous).filter(([directory]) => eligible.has(directory));
|
|
529
|
+
return retained.length === Object.keys(previous).length ? previous : Object.fromEntries(retained);
|
|
530
|
+
});
|
|
531
|
+
setRemoteCheckError(null);
|
|
480
532
|
const check = manager?.remoteHeads;
|
|
481
|
-
if (!check ||
|
|
533
|
+
if (!check || directories.length === 0) {
|
|
534
|
+
setCheckingRemotes(false);
|
|
535
|
+
return;
|
|
536
|
+
}
|
|
482
537
|
let cancelled = false;
|
|
483
538
|
setCheckingRemotes(true);
|
|
484
|
-
void
|
|
485
|
-
|
|
486
|
-
|
|
487
|
-
.catch(logFailure("plugin-marketplace.pane", "Check installed plugin remote heads failed", {}))
|
|
488
|
-
.then((heads) => {
|
|
539
|
+
void (async () => {
|
|
540
|
+
try {
|
|
541
|
+
const heads = await check(directories);
|
|
489
542
|
if (cancelled) return;
|
|
490
|
-
|
|
491
|
-
|
|
492
|
-
|
|
493
|
-
|
|
494
|
-
|
|
495
|
-
|
|
496
|
-
|
|
497
|
-
|
|
543
|
+
// An omitted folder is unanswered, not proof that it is up to date.
|
|
544
|
+
const answers = directories.filter((directory) => !!heads[directory]);
|
|
545
|
+
setRemoteHeads((previous) => ({
|
|
546
|
+
...previous,
|
|
547
|
+
...Object.fromEntries(answers.map((directory) => [directory, heads[directory]!])),
|
|
548
|
+
}));
|
|
549
|
+
setRemoteCheckError(answers.length < directories.length ? "Update check incomplete" : null);
|
|
550
|
+
} catch (error) {
|
|
551
|
+
if (cancelled) return;
|
|
552
|
+
logFailure("plugin-marketplace.pane", "Check installed plugin remote heads failed")(error);
|
|
553
|
+
setRemoteCheckError("Plugin update check failed");
|
|
554
|
+
} finally {
|
|
555
|
+
if (!cancelled) setCheckingRemotes(false);
|
|
556
|
+
}
|
|
557
|
+
})();
|
|
558
|
+
return () => { cancelled = true; };
|
|
559
|
+
}, [manager, unlistedKey, localRevision, remoteRevision]);
|
|
498
560
|
|
|
499
561
|
const visible = useMemo(
|
|
500
562
|
() => filterEntries(entries, { query, category, showBuiltin }),
|
|
@@ -546,16 +608,23 @@ export function PluginMarketplacePane({ focused, width, height }: PaneProps) {
|
|
|
546
608
|
/**
|
|
547
609
|
* The registry's code for this plugin needs a newer Gloomberb. Installing or
|
|
548
610
|
* updating would land it anyway and it would then fail to compile, so say
|
|
549
|
-
* what to do instead
|
|
550
|
-
*
|
|
551
|
-
*
|
|
611
|
+
* what to do instead, on the row: its STATUS already says `needs …` unless
|
|
612
|
+
* something outranks it there (`failed`, `needs restart`). Also leaves a
|
|
613
|
+
* working older checkout alone, and does not update one that already needs
|
|
614
|
+
* a newer Gloomberb: updates only move forward, so that would not help either.
|
|
552
615
|
*/
|
|
553
616
|
const refuseTooNew = useCallback((entry: MarketplaceEntry): boolean => {
|
|
554
617
|
const required = requiredGloomberb(entry.minGloomberb) ?? entry.needsGloomberb;
|
|
555
618
|
if (!required) return false;
|
|
556
|
-
|
|
619
|
+
if (statusOf(entry).kind !== "needs-gloomberb") {
|
|
620
|
+
setFailure(entry.id, {
|
|
621
|
+
kind: "needs-gloomberb",
|
|
622
|
+
status: `needs ${required}`,
|
|
623
|
+
text: `${entry.name} needs Gloom ${required}. Update Gloom first.`,
|
|
624
|
+
});
|
|
625
|
+
}
|
|
557
626
|
return true;
|
|
558
|
-
}, [
|
|
627
|
+
}, [setFailure]);
|
|
559
628
|
|
|
560
629
|
const installSelected = useCallback(async () => {
|
|
561
630
|
if (!selected || !isInstallable(selected) || !manager || !host || busy) return;
|
|
@@ -577,12 +646,11 @@ export function PluginMarketplacePane({ focused, width, height }: PaneProps) {
|
|
|
577
646
|
|
|
578
647
|
const entry = selected;
|
|
579
648
|
setBusy({ id: entry.id, verb: "installing" });
|
|
580
|
-
|
|
649
|
+
setFailure(entry.id, null);
|
|
581
650
|
const result = await manager.install(repo, pin);
|
|
582
651
|
if (!result.ok) {
|
|
583
652
|
setBusy(null);
|
|
584
|
-
|
|
585
|
-
notify({ body: `Could not install ${entry.name}: ${result.error}`, type: "error" });
|
|
653
|
+
setFailure(entry.id, { status: "install failed", text: `Could not install ${entry.name}: ${result.error}` });
|
|
586
654
|
return;
|
|
587
655
|
}
|
|
588
656
|
const activated = await activateInstall(result, host, manager);
|
|
@@ -590,8 +658,8 @@ export function PluginMarketplacePane({ focused, width, height }: PaneProps) {
|
|
|
590
658
|
bump();
|
|
591
659
|
if (activated.ok && activated.restart) notify({ body: `Restart to finish installing ${entry.name}.`, type: "info" });
|
|
592
660
|
else if (activated.ok) announceAdded(activated.pluginId, activated.name, "Installed", host);
|
|
593
|
-
else
|
|
594
|
-
}, [announceAdded, bump, busy, confirmWidth, dialog, host, manager, notify, refuseTooNew, selected]);
|
|
661
|
+
else setFailure(entry.id, { status: "load failed", text: `${entry.name} installed but did not load: ${activated.error}` });
|
|
662
|
+
}, [announceAdded, bump, busy, confirmWidth, dialog, host, manager, notify, refuseTooNew, selected, setFailure]);
|
|
595
663
|
|
|
596
664
|
const updateSelected = useCallback(async () => {
|
|
597
665
|
if (!selected || !isManaged(selected) || !manager || !host || busy || selected.linked) return;
|
|
@@ -600,12 +668,11 @@ export function PluginMarketplacePane({ focused, width, height }: PaneProps) {
|
|
|
600
668
|
const entry = selected;
|
|
601
669
|
const reinstall = !!entry.loadError;
|
|
602
670
|
setBusy({ id: entry.id, verb: "updating" });
|
|
603
|
-
|
|
671
|
+
setFailure(entry.id, null);
|
|
604
672
|
const result = await manager.update(directory, registryPin(entry));
|
|
605
673
|
if (!result.ok) {
|
|
606
674
|
setBusy(null);
|
|
607
|
-
|
|
608
|
-
notify({ body: `Could not update ${entry.name}: ${result.error}`, type: "error" });
|
|
675
|
+
setFailure(entry.id, { status: "update failed", text: `Could not update ${entry.name}: ${result.error}` });
|
|
609
676
|
return;
|
|
610
677
|
}
|
|
611
678
|
if (result.kept) {
|
|
@@ -621,9 +688,21 @@ export function PluginMarketplacePane({ focused, width, height }: PaneProps) {
|
|
|
621
688
|
} else if (activated.ok) {
|
|
622
689
|
announceAdded(activated.pluginId, activated.name, reinstall ? "Reloaded" : "Updated", host);
|
|
623
690
|
} else {
|
|
624
|
-
|
|
691
|
+
setFailure(entry.id, { status: "load failed", text: `${entry.name} updated but did not load: ${activated.error}` });
|
|
625
692
|
}
|
|
626
|
-
}, [announceAdded, bump, busy, host, manager, notify, refuseTooNew, selected]);
|
|
693
|
+
}, [announceAdded, bump, busy, host, manager, notify, refuseTooNew, selected, setFailure]);
|
|
694
|
+
|
|
695
|
+
/**
|
|
696
|
+
* A removal that failed is said on the plugin's row while the list still
|
|
697
|
+
* has one. A stopped plugin can leave the list, files and all; then only a
|
|
698
|
+
* toast is left to say it.
|
|
699
|
+
*/
|
|
700
|
+
const failRemoval = useCallback((entry: MarketplaceEntry, failure: ActionFailure) => {
|
|
701
|
+
const installed = host?.listInstalled() ?? [];
|
|
702
|
+
const listed = mergeCatalog({ registry, installed, target, remoteHeads }).some((candidate) => candidate.id === entry.id);
|
|
703
|
+
if (listed) setFailure(entry.id, failure);
|
|
704
|
+
else notify({ body: failure.text, type: "error" });
|
|
705
|
+
}, [host, notify, registry, remoteHeads, setFailure, target]);
|
|
627
706
|
|
|
628
707
|
const removeSelected = useCallback(async () => {
|
|
629
708
|
if (!selected || !isManaged(selected) || !manager || !host || busy) return;
|
|
@@ -638,18 +717,27 @@ export function PluginMarketplacePane({ focused, width, height }: PaneProps) {
|
|
|
638
717
|
});
|
|
639
718
|
if (!confirmed) return;
|
|
640
719
|
setBusy({ id: entry.id, verb: "removing" });
|
|
641
|
-
|
|
642
|
-
|
|
643
|
-
|
|
644
|
-
|
|
645
|
-
|
|
646
|
-
|
|
647
|
-
|
|
648
|
-
|
|
649
|
-
|
|
650
|
-
notify({ body: `
|
|
720
|
+
setFailure(entry.id, null);
|
|
721
|
+
let removalStarted = false;
|
|
722
|
+
try {
|
|
723
|
+
// Stop the native side first: a successful view stop drops its catalog
|
|
724
|
+
// entry, so it must remain available if the native stop fails.
|
|
725
|
+
await manager.deactivate?.(entry.id);
|
|
726
|
+
await host.deactivate(entry.id, entry.directory);
|
|
727
|
+
removalStarted = true;
|
|
728
|
+
const result = await manager.remove(entry.directory!);
|
|
729
|
+
if (result.ok) notify({ body: `Removed ${entry.name}.`, type: "success" });
|
|
730
|
+
else failRemoval(entry, { status: "remove failed", text: `Could not remove ${entry.name}: ${result.error}` });
|
|
731
|
+
} catch (error) {
|
|
732
|
+
logFailure("plugin-marketplace.pane", "Remove plugin failed")(error);
|
|
733
|
+
failRemoval(entry, removalStarted
|
|
734
|
+
? { status: "remove failed", text: `Could not remove ${entry.name}. Removal failed. Restart and try again.` }
|
|
735
|
+
: { status: "stop failed", text: `Could not remove ${entry.name}. Plugin could not be stopped. Files kept. Restart before removing it.` });
|
|
736
|
+
} finally {
|
|
737
|
+
setBusy(null);
|
|
738
|
+
bump();
|
|
651
739
|
}
|
|
652
|
-
}, [bump, busy, confirmWidth, dialog, host, manager, notify, selected]);
|
|
740
|
+
}, [bump, busy, confirmWidth, dialog, failRemoval, host, manager, notify, selected]);
|
|
653
741
|
|
|
654
742
|
const toggleSelected = useCallback(async () => {
|
|
655
743
|
if (!host || !selected || !selected.installed || !selected.toggleable || selected.loadError) return;
|
|
@@ -828,11 +916,7 @@ export function PluginMarketplacePane({ focused, width, height }: PaneProps) {
|
|
|
828
916
|
const info = loadingErrorFooterInfo(status === "loading", status === "error" ? "catalog unavailable" : null);
|
|
829
917
|
if (stale) info.push({ id: "stale", parts: [{ text: "stale catalog", tone: "warning" }] });
|
|
830
918
|
if (checkingRemotes) info.push({ id: "remote-check", parts: [{ text: "checking unlisted plugins", tone: "muted" }] });
|
|
831
|
-
if (
|
|
832
|
-
const name = entries.find((entry) => entry.id === busy.id)?.name ?? busy.id;
|
|
833
|
-
info.push({ id: "busy", parts: [{ text: `${busy.verb} ${name}`, tone: "muted" }] });
|
|
834
|
-
}
|
|
835
|
-
if (lastError && !busy) info.push({ id: "op-error", parts: [{ text: lastError, tone: "warning" }] });
|
|
919
|
+
if (remoteCheckError) info.push({ id: "remote-error", parts: [{ text: remoteCheckError, tone: "warning" }] });
|
|
836
920
|
const restartCount = entries.filter((entry) => entry.needsRestart).length;
|
|
837
921
|
if (restartCount > 0 && !busy) {
|
|
838
922
|
info.push({ id: "restart", parts: [{ text: "restart to finish loading", tone: "warning" }] });
|
|
@@ -869,8 +953,8 @@ export function PluginMarketplacePane({ focused, width, height }: PaneProps) {
|
|
|
869
953
|
|
|
870
954
|
const fit = useMemo(() => ({
|
|
871
955
|
functions: Math.min(16, Math.max(9, ...visible.map((entry) => factsFor(entry).codes.join(" ").length))),
|
|
872
|
-
status: Math.min(14, Math.max(7, ...visible.map((entry) =>
|
|
873
|
-
}), [factsFor, visible]);
|
|
956
|
+
status: Math.min(14, Math.max(7, ...visible.map((entry) => rowStatus(entry).text.length))),
|
|
957
|
+
}), [factsFor, rowStatus, visible]);
|
|
874
958
|
const columns = useMemo(() => buildColumns(width, fit), [fit, width]);
|
|
875
959
|
// The pick is saved with the pane, so keep it listed (and resettable) even
|
|
876
960
|
// when the catalog no longer has plugins in it.
|
|
@@ -918,7 +1002,7 @@ export function PluginMarketplacePane({ focused, width, height }: PaneProps) {
|
|
|
918
1002
|
detailContent={selected
|
|
919
1003
|
? selected.bundled
|
|
920
1004
|
? <BuiltinDetail entry={selected} width={width} facts={factsFor(selected)} scrollRef={detailScrollRef} />
|
|
921
|
-
: <EntryDetail entry={selected} width={width} host={host} />
|
|
1005
|
+
: <EntryDetail entry={selected} width={width} host={host} status={rowStatus(selected)} failure={failureFor(selected)} />
|
|
922
1006
|
: null}
|
|
923
1007
|
detailTitle={selected?.name}
|
|
924
1008
|
rootBefore={(
|
|
@@ -1,10 +1,11 @@
|
|
|
1
1
|
import type { CliCommandContext } from "../../../../types/plugin";
|
|
2
2
|
import type { TickerRecord } from "../../../../types/ticker";
|
|
3
3
|
import type { MarketContext } from "../../../../cli/types";
|
|
4
|
-
import { listingFields,
|
|
4
|
+
import { listingFields, loadSavedListingOf, savedListingCandidates, savedListingName } from "../../../../cli/listing-arg";
|
|
5
5
|
import { withSuggestion } from "../../../../cli/listing-suggestion";
|
|
6
6
|
import { StagedTickerRepository } from "../../../../cli/staged-tickers";
|
|
7
|
-
import { splitSymbolWords, symbolInputKey } from "../../../../cli/symbol-args";
|
|
7
|
+
import { splitSymbolArgs, splitSymbolWords, symbolInputKey } from "../../../../cli/symbol-args";
|
|
8
|
+
import { notASymbolError } from "../../../../cli/symbol-cells";
|
|
8
9
|
import { readSymbolList, SymbolListError } from "../../../../cli/symbol-list";
|
|
9
10
|
import { cliStyles } from "../../../../utils/cli-output";
|
|
10
11
|
import { dryRunNote } from "../../../../cli/helpers";
|
|
@@ -37,23 +38,35 @@ export const FILE_OPTION = {
|
|
|
37
38
|
export const SYMBOL_LIST_HELP = {
|
|
38
39
|
title: "Several symbols",
|
|
39
40
|
lines: [
|
|
40
|
-
"add and remove take any number of symbols split by spaces, commas or newlines, a --file, or piped input (or -). An entry of a list with commas, semicolons or newlines that has spaces in it is a company's name when search finds one (philip morris intl is PM), read as its US listing first with a line under it saying which, else the symbols it holds when each is written as a symbol or has a quote (AAPL MSFT), and otherwise a name not found. A file or piped list reads each line as such an entry. A CSV is read from its Symbol, Ticker or Code column, else its Name or Company column as names. Without that header every cell is a symbol, unless names, prices or weights sit beside them: then the first column is read and the cells left out are named. Quote a list name with spaces.",
|
|
41
|
-
"Each symbol gets a line, then a summary. Exit status 0 when at least one symbol was added (or removed) or already was, 1 when none resolved or the usage is wrong.",
|
|
42
|
-
"A bare US-style symbol is not added when the listing it matched stopped trading, is abroad (DFS as DFS:LSE) or was taken by another company in the last two years (BRKL), or when nothing lists under it now and its company trades as another. Those are listed under Needs a choice, with the add for what their company trades as now and the listing that matched, which naming keeps; one symbol alone fails with the same. A symbol another company took longer ago says so under its line.",
|
|
41
|
+
"add and remove take any number of symbols split by spaces, commas or newlines, a --file, or piped input (or -). An entry of a list with commas, semicolons or newlines that has spaces in it is a company's name when search finds one (philip morris intl is PM), read as its US listing first with a line under it saying which, else the symbols it holds when each is written as a symbol or has a quote (AAPL MSFT), and otherwise a name not found. A file or piped list reads each line as such an entry. A CSV is read from its Symbol, Ticker or Code column, else its Name or Company column as names. Without that header every cell is a symbol, unless names, prices or weights sit beside them: then the first column is read and the cells left out are named. Each line is split by its own tab, semicolon, comma or spaces, and a price is never a symbol, written either way (2.582,52 or 1,899.21). A comma between plain digits (0700,25) splits them unless the line also has a tab, a semicolon or spaces between cells. Quote a list name with spaces.",
|
|
42
|
+
"Each symbol gets a line, then a summary. An entry that cannot be a symbol (N/A, $$$, --, a price alone) is named as not a symbol without a lookup. Symbols Gloom Cloud did not answer for are listed together with one command that adds them again. Exit status 0 when at least one symbol was added (or removed) or already was, 1 when none resolved or the usage is wrong.",
|
|
43
|
+
"A bare US-style symbol is not added when the listing it matched stopped trading, is abroad while the symbol also names a US listing (DFS as DFS:LSE, Discover's old symbol) or was taken by another company in the last two years (BRKL), or when nothing lists under it now and its company trades as another. Those are listed under Needs a choice, with the add for what their company trades as now and the listing that matched, which naming keeps; one symbol alone fails with the same. A symbol another company took longer ago says so under its line, and one listed only abroad (GARAN) is added with a line naming its venue and currency.",
|
|
44
|
+
"A vendor's suffix is the venue it names: GARAN.IS is stored as GARAN:BIST, the same row GARAN:BIST and GARAN add to.",
|
|
43
45
|
"add --dry-run looks every symbol up and prints the same lines without saving.",
|
|
44
46
|
],
|
|
45
47
|
};
|
|
46
48
|
|
|
49
|
+
/**
|
|
50
|
+
* One word of a command line as a shell reads it back: as written when it
|
|
51
|
+
* holds nothing a shell treats specially (`NVDA`, `SAN:EPA`, `BRK.B`), else
|
|
52
|
+
* in single quotes (`'Altria Group'`, `'$nvda'`, `'AT&T'`).
|
|
53
|
+
*/
|
|
54
|
+
export function shellWord(word: string): string {
|
|
55
|
+
return /^[\p{L}\p{N}._:@%+,/][\p{L}\p{N}._:@%+,/=-]*$/u.test(word) ? word : `'${word.replaceAll("'", "'\\''")}'`;
|
|
56
|
+
}
|
|
57
|
+
|
|
47
58
|
/**
|
|
48
59
|
* A row's line, and under it the listing a company's name was read as, the
|
|
49
|
-
* company that had the symbol before the listing added,
|
|
50
|
-
*
|
|
60
|
+
* company that had the symbol before the listing added, the venue and
|
|
61
|
+
* currency of a bare symbol added on its only listing, abroad, and the coin
|
|
62
|
+
* hint when a bare coin ticker was read as something else.
|
|
51
63
|
*/
|
|
52
64
|
function rowLines(row: SymbolRow, verb: Verb): string {
|
|
53
65
|
return [
|
|
54
66
|
rowLine(row, verb),
|
|
55
67
|
...row.readAs ? [` ${cliStyles.muted(row.readAs)}`] : [],
|
|
56
68
|
...row.changeNote ? [` ${cliStyles.warning(row.changeNote)}`] : [],
|
|
69
|
+
...row.abroad ? [` ${cliStyles.warning(row.abroad)}`] : [],
|
|
57
70
|
...row.hint ? [` ${cliStyles.warning(row.hint)}`] : [],
|
|
58
71
|
].join("\n");
|
|
59
72
|
}
|
|
@@ -71,9 +84,28 @@ function rowLine(row: SymbolRow, verb: Verb): string {
|
|
|
71
84
|
case "not_found": return cliStyles.danger(`Not found: ${typed}${row.message && !NO_MATCH.test(row.message) ? ` (${reason(row.message, typed)})` : ""}${row.suggestion ? `; did you mean ${row.suggestion}?` : ""}`);
|
|
72
85
|
case "needs_choice": return cliStyles.warning(` ${row.message ?? typed}`);
|
|
73
86
|
case "failed": return cliStyles.danger(`Not ${verb === "add" ? "added" : "removed"}: ${typed} (${failedReason(row, typed)})`);
|
|
87
|
+
// Named as written (`$$$`), and a figure says it is one.
|
|
88
|
+
case "not_a_symbol": return cliStyles.warning(`Not a symbol: ${row.input.trim()}${row.message?.includes("a number") ? " (a number)" : ""}`);
|
|
89
|
+
case "not_looked_up": return cliStyles.danger(`Not looked up: ${typed}`);
|
|
74
90
|
}
|
|
75
91
|
}
|
|
76
92
|
|
|
93
|
+
/**
|
|
94
|
+
* The symbols of an add Gloom Cloud did not answer for, after the other
|
|
95
|
+
* lines: one line naming them as they were written, and one command that adds
|
|
96
|
+
* them all again, each entry one shell word (`'philip morris intl'`).
|
|
97
|
+
*/
|
|
98
|
+
function unansweredLines(rows: readonly SymbolRow[], retry: ((keys: string) => string) | undefined): string[] {
|
|
99
|
+
const unanswered = rows.filter((row) => row.status === "not_looked_up").map((row) => row.input.trim());
|
|
100
|
+
if (unanswered.length === 0) return [];
|
|
101
|
+
const count = unanswered.length === 1 ? "1 symbol" : `${unanswered.length} symbols`;
|
|
102
|
+
return [
|
|
103
|
+
"",
|
|
104
|
+
cliStyles.danger(`Gloom Cloud did not answer for ${count}, so ${unanswered.length === 1 ? "it was" : "they were"} not looked up: ${unanswered.join(", ")}`),
|
|
105
|
+
...retry ? [`Try again in a minute: ${retry(unanswered.map(shellWord).join(" "))}`] : [],
|
|
106
|
+
];
|
|
107
|
+
}
|
|
108
|
+
|
|
77
109
|
/**
|
|
78
110
|
* What symbols that need a choice offer: the add that takes the companies
|
|
79
111
|
* they trade as now, and the add that keeps each match as it is by naming its
|
|
@@ -82,7 +114,7 @@ function rowLine(row: SymbolRow, verb: Verb): string {
|
|
|
82
114
|
function choiceOffers(choices: readonly SymbolRow[], retry: ((keys: string) => string) | undefined): { successors: string | null; matches: string | null } {
|
|
83
115
|
const successors = [...new Set(choices.flatMap((row) => row.tradesAs ? [row.tradesAs] : []))];
|
|
84
116
|
const matches = [...new Set(choices.flatMap((row) => row.listing ? [row.listing] : []))];
|
|
85
|
-
const command = (keys: string[]) => retry ? retry(keys.join(" ")) : keys.join(" ");
|
|
117
|
+
const command = (keys: string[]) => retry ? retry(keys.map(shellWord).join(" ")) : keys.join(" ");
|
|
86
118
|
const one = choices.length === 1;
|
|
87
119
|
return {
|
|
88
120
|
successors: successors.length > 0 ? `Add what ${one ? "it trades" : "they trade"} as now: ${command(successors)}` : null,
|
|
@@ -131,18 +163,21 @@ export function printSymbolRows(
|
|
|
131
163
|
): void {
|
|
132
164
|
const summary = `${collection.kind === "watchlist" ? "Watchlist" : "Portfolio"} "${collection.name}": ${summarizeSymbolRows(rows, verb, repeated)}`;
|
|
133
165
|
const count = (status: SymbolStatus) => rows.filter((row) => row.status === status).length;
|
|
166
|
+
const extra = (key: string, status: SymbolStatus) => count(status) > 0 ? { [key]: count(status) } : {};
|
|
134
167
|
const counts = verb === "add"
|
|
135
168
|
? { added: count("added"), alreadyListed: count("already_listed"), notFound: count("not_found"), notAdded: count("failed"),
|
|
136
|
-
...
|
|
137
|
-
: { removed: count("removed"), notListed: count("not_listed"), notFound: count("not_found"), notRemoved: count("failed")
|
|
169
|
+
...extra("needsChoice", "needs_choice"), ...extra("notLookedUp", "not_looked_up"), ...extra("notASymbol", "not_a_symbol") }
|
|
170
|
+
: { removed: count("removed"), notListed: count("not_listed"), notFound: count("not_found"), notRemoved: count("failed"),
|
|
171
|
+
...extra("notASymbol", "not_a_symbol") };
|
|
138
172
|
ctx.printResult({
|
|
139
173
|
data: rows,
|
|
140
174
|
metadata: { [collection.kind]: collection.name, ...counts, repeated, summary, ...dryRun ? { dryRun } : {} },
|
|
141
175
|
...notes.length > 0 ? { warnings: [...notes] } : {},
|
|
142
176
|
}, {
|
|
143
177
|
text: () => [
|
|
144
|
-
...rows.filter((row) => row.status !== "needs_choice").map((row) => rowLines(row, verb)),
|
|
178
|
+
...rows.filter((row) => row.status !== "needs_choice" && row.status !== "not_looked_up").map((row) => rowLines(row, verb)),
|
|
145
179
|
...choiceLines(rows, retry),
|
|
180
|
+
...unansweredLines(rows, retry),
|
|
146
181
|
"",
|
|
147
182
|
`${summary}${dryRunNote(dryRun)}`,
|
|
148
183
|
].join("\n"),
|
|
@@ -155,16 +190,18 @@ export function printSymbolRows(
|
|
|
155
190
|
/**
|
|
156
191
|
* `watchlist add` and `portfolio add` given one symbol: added as a symbol of a
|
|
157
192
|
* list is (`addSymbol`), and said as one listing, added or already there with
|
|
158
|
-
* its notes as warnings
|
|
193
|
+
* its notes as warnings, after `notes` on what was left out of the input (the
|
|
194
|
+
* price of `ED 2.582,52`). A symbol a list would leave for a choice fails the
|
|
159
195
|
* command, saying why, with what a list offers under the error; any other
|
|
160
196
|
* failure fails it as the lookup's error, a busy service's to retry.
|
|
161
197
|
*/
|
|
162
198
|
export async function addOneSymbol(
|
|
163
199
|
ctx: CliCommandContext,
|
|
164
200
|
market: MarketContext,
|
|
165
|
-
{ symbol, exchange, collection, retry, reject, add }: {
|
|
201
|
+
{ symbol, exchange, collection, notes: inputNotes = [], retry, reject, add }: {
|
|
166
202
|
symbol: string;
|
|
167
203
|
exchange: string | undefined;
|
|
204
|
+
notes?: readonly string[];
|
|
168
205
|
collection: CollectionRef;
|
|
169
206
|
/** The add of one listing, for the choices a failure names. */
|
|
170
207
|
retry: (key: string) => string;
|
|
@@ -189,7 +226,8 @@ export async function addOneSymbol(
|
|
|
189
226
|
const { change, formerIssuer, notes } = lookup;
|
|
190
227
|
const data = { changed, ...listingFields(saved), [collection.kind]: collection.name,
|
|
191
228
|
...change ? { tickerChange: change } : {}, ...formerIssuer ? { formerIssuer } : {}, ...dryRun ? { dryRun } : {} };
|
|
192
|
-
const
|
|
229
|
+
const said = [...inputNotes, ...notes, ...row.abroad ? [row.abroad] : []];
|
|
230
|
+
const warnings = said.length > 0 ? said : undefined;
|
|
193
231
|
ctx.printResult({ data, warnings }, {
|
|
194
232
|
text: () => changed
|
|
195
233
|
? `${cliStyles.success(`Added ${saved.label} to "${collection.name}".`)}${dryRunNote(dryRun)}`
|
|
@@ -208,7 +246,9 @@ export function retryNotice(ctx: CliCommandContext): (count: number, waitMs: num
|
|
|
208
246
|
/**
|
|
209
247
|
* The symbols an add or remove was given, failing the command when there are
|
|
210
248
|
* none or the file cannot be read. An add reads a typed company's name with
|
|
211
|
-
* `readNameEntries`; without it (a remove) every entry is its words.
|
|
249
|
+
* `readNameEntries`; without it (a remove) every entry is its words. `single`
|
|
250
|
+
* is the one symbol typed alone, and `notes` what the single command says
|
|
251
|
+
* beside it: none when it goes as typed, else what was left out of it.
|
|
212
252
|
*/
|
|
213
253
|
export async function requireSymbolList(
|
|
214
254
|
ctx: CliCommandContext,
|
|
@@ -225,12 +265,16 @@ export async function requireSymbolList(
|
|
|
225
265
|
typed ??= read;
|
|
226
266
|
return read;
|
|
227
267
|
} });
|
|
228
|
-
|
|
268
|
+
// Only numbers or strays says what it left out, not only how to call the command.
|
|
269
|
+
if (list.symbols.length === 0) ctx.fail(list.notes.length > 0 ? ["No symbols.", ...list.notes].join(" ") : usage, list.notes.length > 0 ? usage : undefined);
|
|
229
270
|
// One symbol typed alone keeps the single-symbol output and errors. It goes as typed, so a separator
|
|
230
|
-
// left on it (`UPST;`) is named by the listing it resolves to
|
|
271
|
+
// left on it (`UPST;`) is named by the listing it resolves to; without the figure typed beside it
|
|
272
|
+
// (`ED 2.582,52`), which the notes name.
|
|
231
273
|
const entries: string[] = typed ?? [];
|
|
232
|
-
const
|
|
233
|
-
|
|
274
|
+
const split = splitSymbolArgs(args);
|
|
275
|
+
const asTyped = args.length === 1 && split.length === 1 && split[0] === entries[0];
|
|
276
|
+
const single = file == null && !args.includes("-") && entries.length === 1 ? (asTyped ? args[0]!.trim() : entries[0]!) : null;
|
|
277
|
+
return { ...list, single, notes: single && asTyped ? [] : list.notes };
|
|
234
278
|
} catch (error) {
|
|
235
279
|
if (error instanceof SymbolListError) ctx.fail(error.message, usage);
|
|
236
280
|
throw error;
|
|
@@ -248,29 +292,33 @@ export async function removeSymbols({
|
|
|
248
292
|
exchange,
|
|
249
293
|
store,
|
|
250
294
|
reject,
|
|
295
|
+
holds,
|
|
251
296
|
remove,
|
|
252
297
|
}: BulkSymbolsOptions & {
|
|
253
298
|
reject?: (input: string) => Error | null;
|
|
299
|
+
/** Whether the list being changed holds the row: of two a symbol may be saved as (GARAN:BIST and GARAN.IS), the one it holds. */
|
|
300
|
+
holds?: (ticker: TickerRecord) => boolean;
|
|
254
301
|
remove: (ticker: TickerRecord) => { changed: boolean; ticker: TickerRecord; extra?: Record<string, unknown> };
|
|
255
302
|
}): Promise<SymbolRow[]> {
|
|
256
303
|
const staged = new StagedTickerRepository(store);
|
|
257
304
|
const rows: SymbolRow[] = [];
|
|
258
305
|
for (const input of symbols) {
|
|
259
|
-
const refusal = reject?.(input);
|
|
306
|
+
const refusal = notASymbolError(input) ?? reject?.(input);
|
|
260
307
|
if (refusal) {
|
|
261
308
|
rows.push(failedRow(input, refusal));
|
|
262
309
|
continue;
|
|
263
310
|
}
|
|
264
|
-
let
|
|
311
|
+
let listings;
|
|
265
312
|
try {
|
|
266
|
-
|
|
313
|
+
// GARAN.IS is the row of GARAN:BIST, else a row still saved under that key (a broker's).
|
|
314
|
+
listings = savedListingCandidates(input, exchange, { ownExchangeWins: true });
|
|
267
315
|
} catch (error) {
|
|
268
316
|
rows.push(failedRow(input, error instanceof Error ? error : new Error(String(error))));
|
|
269
317
|
continue;
|
|
270
318
|
}
|
|
271
|
-
const ticker =
|
|
319
|
+
const ticker = listings[0]!.symbol ? (await loadSavedListingOf(staged, listings, holds))?.ticker : null;
|
|
272
320
|
if (!ticker) {
|
|
273
|
-
rows.push(failedRow(input, new Error(`Ticker "${
|
|
321
|
+
rows.push(failedRow(input, new Error(`Ticker "${listings[0]!.key}" was not found in your local data.`), "not_found"));
|
|
274
322
|
continue;
|
|
275
323
|
}
|
|
276
324
|
const result = remove(ticker);
|