@gloom-sh/terminal 0.19.1 → 0.19.3
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 +7 -1
- package/package.json +2 -1
- package/patches/electrobun@1.18.1.patch +108 -1
- package/src/account/upgrade-dialog.tsx +4 -23
- package/src/api-client/coalesce.ts +118 -0
- package/src/api-client/credit-boards.ts +13 -0
- package/src/api-client/crypto-etf-flows.ts +6 -0
- package/src/api-client/crypto-markets.ts +40 -0
- package/src/api-client/data.ts +201 -14
- package/src/api-client/equity-screener.ts +10 -0
- package/src/api-client/errors.ts +58 -0
- package/src/api-client/gpu.ts +29 -0
- package/src/api-client/index.ts +5 -2
- package/src/api-client/plan-access.ts +10 -1
- package/src/api-client/plan-rules.ts +35 -0
- package/src/api-client/research-activity.ts +1 -32
- package/src/api-client/types.ts +21 -1
- package/src/app/attention-notice.tsx +94 -0
- package/src/app/runtime/startup.ts +3 -1
- package/src/app.tsx +23 -1
- package/src/architecture/core-builtin-allowlist.json +2 -1
- package/src/capabilities/chart-series.ts +2 -1
- package/src/capabilities/factories.ts +1 -0
- package/src/cli/ascii-output.ts +42 -0
- package/src/cli/base-converter.ts +10 -2
- package/src/cli/command-options.ts +16 -1
- package/src/cli/commands/crypto-hints.ts +23 -4
- package/src/cli/commands/market.ts +101 -27
- package/src/cli/commands/news-search.ts +24 -5
- package/src/cli/commands/overview.ts +14 -10
- package/src/cli/commands/search.ts +84 -25
- package/src/cli/commands/system.ts +22 -30
- package/src/cli/commands/ticker.ts +49 -9
- package/src/cli/commands/version.ts +33 -0
- package/src/cli/context.ts +6 -9
- package/src/cli/data-dir.ts +7 -0
- package/src/cli/desktop-pane-shot-api-policy.ts +85 -0
- package/src/cli/desktop-pane-shot-browser.ts +320 -0
- package/src/cli/desktop-pane-shot-routes.ts +26 -1
- package/src/cli/desktop-pane-shot.ts +196 -256
- package/src/cli/early-command.ts +42 -0
- package/src/cli/earnings-calendar.ts +9 -0
- package/src/cli/entry.ts +19 -13
- package/src/cli/errors.ts +12 -2
- package/src/cli/glossary.ts +2 -1
- package/src/cli/help.ts +1 -1
- package/src/cli/history-export.ts +22 -2
- package/src/cli/history-rows.ts +189 -11
- package/src/cli/index.ts +18 -1
- package/src/cli/known-gaps.ts +51 -5
- package/src/cli/listing-arg.ts +63 -10
- package/src/cli/options.ts +1 -1
- package/src/cli/output-file.ts +60 -13
- package/src/cli/pane-functions/catalog.ts +14 -3
- package/src/cli/pane-functions/data.ts +1 -1
- package/src/cli/pane-functions/dom.ts +45 -0
- package/src/cli/pane-functions/freshness.ts +46 -9
- package/src/cli/pane-functions/function-help.ts +17 -9
- package/src/cli/pane-functions/headless.ts +22 -14
- package/src/cli/pane-functions/index.ts +6 -2
- package/src/cli/pane-functions/options.ts +6 -2
- package/src/cli/pane-functions/resolver.ts +27 -5
- package/src/cli/pane-functions/screenshot-assessment.ts +33 -0
- package/src/cli/pane-functions/screenshot-bridge.ts +94 -13
- package/src/cli/pane-functions/screenshot-http.ts +70 -0
- package/src/cli/pane-functions/screenshot-render.ts +19 -5
- package/src/cli/quote-answer.ts +49 -6
- package/src/cli/registry.ts +41 -13
- package/src/cli/result.ts +12 -6
- package/src/cli/ticker-resolution.ts +2 -1
- package/src/cli/types.ts +2 -0
- package/src/components/chart/composite/format.ts +3 -0
- package/src/components/chart-table/header.tsx +1 -1
- package/src/components/chart-table/layout.ts +28 -11
- package/src/components/command-bar/action-runtime.ts +4 -0
- package/src/components/command-bar/commands/direct/index.ts +18 -33
- package/src/components/command-bar/commands/direct/runtime.ts +5 -0
- package/src/components/command-bar/commands/registry.ts +10 -1
- package/src/components/command-bar/routes/root/command-items.ts +9 -4
- package/src/components/command-bar/routes/root/runtime.ts +51 -6
- package/src/components/command-bar/selection-runtime.ts +12 -29
- package/src/components/command-bar/surface/index.tsx +9 -3
- package/src/components/company-logo.tsx +2 -1
- package/src/components/layout/detached-pane-shell.tsx +2 -2
- package/src/components/layout/header.tsx +10 -5
- package/src/components/layout/market-summary.ts +25 -7
- package/src/components/layout/pane/footer/index.tsx +8 -2
- package/src/components/layout/pane/footer/model.ts +73 -6
- package/src/components/layout/pane/header.tsx +2 -2
- package/src/components/layout/pane/status-footer.ts +2 -1
- package/src/components/market-board/index.tsx +3 -2
- package/src/components/onboarding/desks-step.tsx +12 -4
- package/src/components/onboarding/first-run-workspace.ts +81 -4
- package/src/components/onboarding/onboarding-frame.tsx +4 -2
- package/src/components/onboarding/onboarding-keyboard.ts +8 -5
- package/src/components/onboarding/onboarding-wizard.tsx +60 -26
- package/src/components/onboarding/portfolio-step/positions-panel.tsx +7 -2
- package/src/components/onboarding/run-setup-again.ts +24 -0
- package/src/components/onboarding/use-onboarding-progress.ts +33 -15
- package/src/components/onboarding/use-onboarding-upgrade.ts +2 -6
- package/src/components/onboarding/wizard-model.ts +57 -3
- package/src/components/onboarding/wizard-positions.ts +1 -1
- package/src/components/ui/delayed-mark.tsx +56 -0
- package/src/components/ui/display.tsx +16 -5
- package/src/components/ui/external-link.tsx +3 -6
- package/src/components/ui/icon.tsx +16 -3
- package/src/components/ui/logo-mark.tsx +8 -5
- package/src/components/ui/stat-grid.tsx +263 -19
- package/src/core/app-services.ts +11 -2
- package/src/data/app-persistence.ts +9 -7
- package/src/data/config/store/node.ts +11 -5
- package/src/data/config/store/normalize.ts +16 -3
- package/src/data/plugin-cache.ts +15 -0
- package/src/data/plugin-state-store.ts +81 -24
- package/src/data/profile-permissions.ts +47 -0
- package/src/data/resource-store.ts +165 -90
- package/src/data/session-store.ts +31 -8
- package/src/data/sqlite/access.ts +324 -0
- package/src/data/sqlite/checkpointer.ts +285 -0
- package/src/data/sqlite/database.ts +80 -4
- package/src/data/sqlite/retry.ts +50 -9
- package/src/data/ticker-store.ts +57 -23
- package/src/docs/snapshot.json +191 -78
- package/src/i18n/es.ts +18 -2
- package/src/i18n/ja.ts +18 -2
- package/src/i18n/ko.ts +18 -2
- package/src/i18n/zh-cn.ts +18 -2
- package/src/i18n/zh-tw.ts +18 -2
- package/src/layout/desk-keys.ts +4 -1
- package/src/layout/desks.ts +38 -5
- package/src/layout-marketplace/gallery-desktop.tsx +45 -16
- package/src/market-data/batched-reads.ts +16 -0
- package/src/market-data/coordinator/auxiliary.ts +4 -2
- package/src/market-data/coordinator/index.ts +11 -2
- package/src/market-data/futures-board.ts +1 -1
- package/src/market-data/futures-contract.ts +3 -1
- package/src/market-data/market/index-level.ts +6 -4
- package/src/market-data/published-apac-sessions.ts +6 -0
- package/src/market-data/realized-volatility.ts +4 -2
- package/src/news/aggregator.ts +7 -4
- package/src/news/news-model.ts +11 -0
- package/src/news/story-id.ts +22 -0
- package/src/news/ticker-symbols.ts +17 -1
- package/src/notifications/app-notifier.ts +35 -14
- package/src/plugins/auto-update-node.ts +10 -6
- package/src/plugins/builtin/account-management/form-components.tsx +1 -1
- package/src/plugins/builtin/account-management/index.tsx +2 -3
- package/src/plugins/builtin/account-management/model.ts +1 -1
- package/src/plugins/builtin/alerts/cli-forms.ts +15 -1
- package/src/plugins/builtin/alerts/events-pane.tsx +7 -5
- package/src/plugins/builtin/alerts/events.ts +10 -2
- package/src/plugins/builtin/alerts/index.tsx +5 -5
- package/src/plugins/builtin/alerts/research-builder.ts +5 -1
- package/src/plugins/builtin/alerts/research-rules.ts +18 -0
- package/src/plugins/builtin/alerts/targets.ts +4 -1
- package/src/plugins/builtin/attention/headless.ts +1 -1
- package/src/plugins/builtin/attention/index.tsx +2 -4
- package/src/plugins/builtin/attention/listing.ts +1 -1
- package/src/plugins/builtin/attention/series.ts +1 -1
- package/src/plugins/builtin/awards/index.tsx +1 -2
- package/src/plugins/builtin/backtest/client.ts +1 -0
- package/src/plugins/builtin/backtest/index.tsx +1 -2
- package/src/plugins/builtin/backtest/rules.ts +3 -1
- package/src/plugins/builtin/backtest/window.ts +8 -7
- package/src/plugins/builtin/broker-manager/detail.tsx +16 -3
- package/src/plugins/builtin/broker-manager/index.tsx +1 -1
- package/src/plugins/builtin/buildout/cells.tsx +5 -0
- package/src/plugins/builtin/buildout/company/flow.tsx +367 -0
- package/src/plugins/builtin/buildout/company/id.ts +2 -0
- package/src/plugins/builtin/buildout/company/model.ts +247 -0
- package/src/plugins/builtin/buildout/company/pane.tsx +317 -0
- package/src/plugins/builtin/buildout/data-runtime.ts +31 -10
- package/src/plugins/builtin/buildout/facilities.ts +309 -0
- package/src/plugins/builtin/buildout/format.ts +9 -0
- package/src/plugins/builtin/buildout/index.tsx +51 -5
- package/src/plugins/builtin/buildout/model/index.ts +62 -10
- package/src/plugins/builtin/buildout/model/normalizers.ts +5 -0
- package/src/plugins/builtin/buildout/model/types.ts +11 -2
- package/src/plugins/builtin/buildout/pane/index.tsx +91 -20
- package/src/plugins/builtin/buildout/pane/status.tsx +1 -1
- package/src/plugins/builtin/buildout/pane/themes.tsx +110 -0
- package/src/plugins/builtin/buildout/table-model.ts +26 -2
- package/src/plugins/builtin/builtin-plugin-meta.ts +16 -0
- package/src/plugins/builtin/cds/headless.ts +10 -2
- package/src/plugins/builtin/cds/model.ts +7 -3
- package/src/plugins/builtin/central-bank-rates/index.tsx +1 -2
- package/src/plugins/builtin/central-bank-rates/pane.tsx +2 -1
- package/src/plugins/builtin/central-bank-rates/series.ts +2 -3
- package/src/plugins/builtin/changelog/index.tsx +3 -2
- package/src/plugins/builtin/chart-composer/cli-options.ts +16 -0
- package/src/plugins/builtin/chart-composer/headless-schema.ts +10 -0
- package/src/plugins/builtin/chart-composer/headless.ts +88 -21
- package/src/plugins/builtin/chart-composer/index.tsx +2 -3
- package/src/plugins/builtin/chart-composer/pane.tsx +30 -2
- package/src/plugins/builtin/chart-composer/series-expression.ts +3 -2
- package/src/plugins/builtin/chart-composer/session-range.ts +5 -2
- package/src/plugins/builtin/chart-composer/studies.ts +1 -1
- package/src/plugins/builtin/chat/controller/index.ts +1 -1
- package/src/plugins/builtin/chat/controller/messages.ts +15 -4
- package/src/plugins/builtin/chat/ghost-user.ts +8 -0
- package/src/plugins/builtin/chat/index.tsx +5 -5
- package/src/plugins/builtin/clinical-trials/index.tsx +1 -2
- package/src/plugins/builtin/cloud/company-picker.tsx +1 -1
- package/src/plugins/builtin/cloud/index.tsx +1 -2
- package/src/plugins/builtin/cloud/plugin.tsx +6 -4
- package/src/plugins/builtin/cloud/team/module.tsx +1 -1
- package/src/plugins/builtin/cloud/thesis/module.tsx +1 -1
- package/src/plugins/builtin/cloud/trial-offer-status-widget.tsx +24 -1
- package/src/plugins/builtin/cloud/upgrade-status-widget.tsx +39 -15
- package/src/plugins/builtin/comment-letters/index.tsx +1 -2
- package/src/plugins/builtin/commodity-balances/client.ts +4 -1
- package/src/plugins/builtin/commodity-balances/index.tsx +3 -3
- package/src/plugins/builtin/commodity-balances/pane.tsx +2 -2
- package/src/plugins/builtin/congress-trades/aggregates.ts +13 -2
- package/src/plugins/builtin/congress-trades/detail.tsx +20 -4
- package/src/plugins/builtin/congress-trades/headless.ts +2 -0
- package/src/plugins/builtin/congress-trades/model.ts +92 -64
- package/src/plugins/builtin/congress-trades/table.tsx +14 -2
- package/src/plugins/builtin/connections/index.ts +2 -3
- package/src/plugins/builtin/cot/client.ts +28 -2
- package/src/plugins/builtin/cot/headless.ts +4 -1
- package/src/plugins/builtin/cot/index.tsx +5 -4
- package/src/plugins/builtin/cot/model.ts +58 -7
- package/src/plugins/builtin/cot/pane.tsx +6 -2
- package/src/plugins/builtin/cpi/client.ts +6 -5
- package/src/plugins/builtin/cpi/index.tsx +1 -2
- package/src/plugins/builtin/credit-boards/cdx-pane.tsx +2 -1
- package/src/plugins/builtin/credit-boards/client.ts +7 -2
- package/src/plugins/builtin/credit-boards/headless.ts +25 -12
- package/src/plugins/builtin/credit-boards/model.ts +29 -0
- package/src/plugins/builtin/credit-boards/series.ts +3 -4
- package/src/plugins/builtin/credit-boards/sovr-pane.tsx +9 -4
- package/src/plugins/builtin/credit-conditions/client.ts +22 -14
- package/src/plugins/builtin/crypto-board/bitcoin-network.ts +143 -0
- package/src/plugins/builtin/crypto-board/client.ts +5 -5
- package/src/plugins/builtin/crypto-board/headless.ts +4 -3
- package/src/plugins/builtin/crypto-board/index.tsx +4 -2
- package/src/plugins/builtin/crypto-board/series.ts +6 -4
- package/src/plugins/builtin/crypto-etf-flows/client.ts +9 -2
- package/src/plugins/builtin/crypto-etf-flows/headless.ts +61 -6
- package/src/plugins/builtin/crypto-etf-flows/index.tsx +1 -2
- package/src/plugins/builtin/crypto-etf-flows/model.ts +14 -1
- package/src/plugins/builtin/crypto-etf-flows/pane.tsx +8 -5
- package/src/plugins/builtin/debt-maturities/headless.ts +4 -3
- package/src/plugins/builtin/debt-maturities/model.ts +17 -1
- package/src/plugins/builtin/debt-maturities/pane.tsx +18 -4
- package/src/plugins/builtin/debt-maturities/series.ts +3 -3
- package/src/plugins/builtin/debug/index.tsx +1 -1
- package/src/plugins/builtin/dividend-yield/client.ts +32 -2
- package/src/plugins/builtin/dividend-yield/headless.ts +58 -33
- package/src/plugins/builtin/dividend-yield/index.tsx +37 -2
- package/src/plugins/builtin/dividend-yield/pane.tsx +32 -13
- package/src/plugins/builtin/dividend-yield/ranking-reads.ts +73 -0
- package/src/plugins/builtin/dividend-yield/ranking-view.tsx +163 -0
- package/src/plugins/builtin/dividend-yield/ranking.ts +1 -1
- package/src/plugins/builtin/dividend-yield/view.ts +21 -0
- package/src/plugins/builtin/docs/index.tsx +2 -3
- package/src/plugins/builtin/doe/client.ts +6 -5
- package/src/plugins/builtin/doe/headless.ts +16 -3
- package/src/plugins/builtin/doe/index.tsx +5 -4
- package/src/plugins/builtin/doe/prices.ts +2 -3
- package/src/plugins/builtin/doe/series.ts +4 -4
- package/src/plugins/builtin/earnings/board.tsx +2 -1
- package/src/plugins/builtin/earnings/history.tsx +2 -1
- package/src/plugins/builtin/earnings-calls/calendar.tsx +10 -2
- package/src/plugins/builtin/earnings-calls/data.ts +19 -11
- package/src/plugins/builtin/earnings-calls/pane.tsx +27 -14
- package/src/plugins/builtin/earnings-ripple/client.ts +32 -7
- package/src/plugins/builtin/earnings-ripple/index.tsx +1 -2
- package/src/plugins/builtin/econ/calendar-model.ts +29 -6
- package/src/plugins/builtin/econ/detail-view.tsx +16 -2
- package/src/plugins/builtin/econ-statistics/index.tsx +1 -2
- package/src/plugins/builtin/equity-screener/client.ts +1 -1
- package/src/plugins/builtin/equity-screener/headless.ts +1 -0
- package/src/plugins/builtin/equity-screener/ideas.ts +30 -1
- package/src/plugins/builtin/equity-screener/index.tsx +1 -2
- package/src/plugins/builtin/equity-screener/model.ts +28 -4
- package/src/plugins/builtin/equity-screener/pane.tsx +5 -0
- package/src/plugins/builtin/equity-screener/screen-check.ts +23 -1
- package/src/plugins/builtin/estimate-revisions/index.tsx +1 -2
- package/src/plugins/builtin/executives/data.ts +6 -1
- package/src/plugins/builtin/executives/pane.tsx +9 -21
- package/src/plugins/builtin/exposure/holdings.ts +35 -13
- package/src/plugins/builtin/exposure/index.tsx +1 -2
- package/src/plugins/builtin/fear-greed/cache.ts +4 -0
- package/src/plugins/builtin/fear-greed/cli.ts +44 -0
- package/src/plugins/builtin/fear-greed/index.tsx +5 -53
- package/src/plugins/builtin/fear-greed/pane.tsx +2 -1
- package/src/plugins/builtin/fear-greed/series.ts +6 -4
- package/src/plugins/builtin/fixed-income/index.tsx +1 -2
- package/src/plugins/builtin/futures/board-reads.ts +25 -0
- package/src/plugins/builtin/futures/coalesced-bump.ts +44 -0
- package/src/plugins/builtin/futures/index.tsx +15 -0
- package/src/plugins/builtin/futures/model.ts +14 -0
- package/src/plugins/builtin/futures/use-board-terms.ts +22 -15
- package/src/plugins/builtin/futures/use-front-returns.ts +20 -14
- package/src/plugins/builtin/futures-curve/headless.ts +6 -1
- package/src/plugins/builtin/futures-curve/index.tsx +1 -2
- package/src/plugins/builtin/fx-matrix/index.tsx +2 -2
- package/src/plugins/builtin/gpu/board.tsx +51 -12
- package/src/plugins/builtin/gpu/client.ts +19 -3
- package/src/plugins/builtin/gpu/equities.tsx +5 -2
- package/src/plugins/builtin/gpu/headless.ts +14 -2
- package/src/plugins/builtin/gpu/index.tsx +1 -2
- package/src/plugins/builtin/gpu/model.ts +20 -2
- package/src/plugins/builtin/gpu/pane.tsx +1 -1
- package/src/plugins/builtin/gpu/series.ts +2 -3
- package/src/plugins/builtin/help/index.tsx +1 -1
- package/src/plugins/builtin/holders/beneficial-view.tsx +1 -2
- package/src/plugins/builtin/holders/index-holders.ts +24 -12
- package/src/plugins/builtin/holders/index.tsx +2 -3
- package/src/plugins/builtin/ipo-calendar/index.tsx +1 -2
- package/src/plugins/builtin/iv-history/index.tsx +1 -2
- package/src/plugins/builtin/jodi/client.ts +4 -1
- package/src/plugins/builtin/jodi/index.tsx +1 -2
- package/src/plugins/builtin/kelly-sizer/index.tsx +1 -2
- package/src/plugins/builtin/layout-manager/index.tsx +9 -8
- package/src/plugins/builtin/macro-day/pane.tsx +4 -2
- package/src/plugins/builtin/market-halts/index.tsx +1 -2
- package/src/plugins/builtin/market-heatmap/index.tsx +11 -2
- package/src/plugins/builtin/market-movers/client.ts +1 -0
- package/src/plugins/builtin/market-movers/index.tsx +16 -5
- package/src/plugins/builtin/market-movers/screener.ts +23 -6
- package/src/plugins/builtin/market-movers/session-body.tsx +6 -2
- package/src/plugins/builtin/market-valuation/index.tsx +1 -2
- package/src/plugins/builtin/members/index.tsx +1 -2
- package/src/plugins/builtin/money-markets/index.tsx +1 -2
- package/src/plugins/builtin/money-markets/pane.tsx +2 -1
- package/src/plugins/builtin/money-markets/series.ts +3 -5
- package/src/plugins/builtin/news/headless.ts +7 -0
- package/src/plugins/builtin/news/wire/index.tsx +1 -1
- package/src/plugins/builtin/news/wire/news/pop-out.tsx +9 -3
- package/src/plugins/builtin/notes/index.tsx +3 -6
- package/src/plugins/builtin/openfda/index.tsx +1 -2
- package/src/plugins/builtin/options/view.tsx +6 -5
- package/src/plugins/builtin/options-calculator/index.tsx +1 -2
- package/src/plugins/builtin/options-positioning/index.tsx +1 -2
- package/src/plugins/builtin/options-scenario/index.tsx +2 -4
- package/src/plugins/builtin/perps/index.tsx +1 -2
- package/src/plugins/builtin/plugin-marketplace/index.tsx +2 -3
- package/src/plugins/builtin/plugin-marketplace/pane.tsx +2 -1
- package/src/plugins/builtin/plugin-module.ts +16 -2
- package/src/plugins/builtin/portfolio-list/cli/render.ts +53 -3
- package/src/plugins/builtin/portfolio-list/index.tsx +1 -2
- package/src/plugins/builtin/portfolio-list/pane/index.tsx +11 -0
- package/src/plugins/builtin/portfolio-list/quick-add/index.tsx +2 -2
- package/src/plugins/builtin/power/gas-client.ts +2 -1
- package/src/plugins/builtin/power/index.tsx +1 -2
- package/src/plugins/builtin/power/prices-client.ts +3 -2
- package/src/plugins/builtin/rate-path/index.tsx +1 -2
- package/src/plugins/builtin/realized-vol/headless.ts +2 -0
- package/src/plugins/builtin/realized-vol/index.tsx +1 -2
- package/src/plugins/builtin/realized-vol/model.ts +16 -2
- package/src/plugins/builtin/realized-vol/pane.tsx +3 -3
- package/src/plugins/builtin/relative-rotation/index.tsx +1 -2
- package/src/plugins/builtin/research/analyst-headless.ts +33 -6
- package/src/plugins/builtin/research/analyst-model.ts +37 -2
- package/src/plugins/builtin/research/analyst-pane.tsx +25 -5
- package/src/plugins/builtin/research/index.tsx +5 -8
- package/src/plugins/builtin/research-search/index.tsx +1 -2
- package/src/plugins/builtin/revenue-breakdown/headless.ts +22 -8
- package/src/plugins/builtin/revenue-breakdown/model.ts +23 -0
- package/src/plugins/builtin/reverse-dcf/pane.tsx +4 -2
- package/src/plugins/builtin/risk-factors/data.ts +8 -4
- package/src/plugins/builtin/risk-factors/index.tsx +3 -1
- package/src/plugins/builtin/risk-factors/pane.tsx +5 -8
- package/src/plugins/builtin/roadmap/index.tsx +2 -3
- package/src/plugins/builtin/roadmap/pane.tsx +49 -2
- package/src/plugins/builtin/scanner/hilo-model.ts +18 -1
- package/src/plugins/builtin/scanner/hilo-pane.tsx +12 -2
- package/src/plugins/builtin/scanner/live-pane.tsx +7 -4
- package/src/plugins/builtin/scanner/lock-note.ts +26 -3
- package/src/plugins/builtin/sec/filing-content.ts +38 -6
- package/src/plugins/builtin/sec/headless.ts +5 -1
- package/src/plugins/builtin/sec/index.tsx +4 -2
- package/src/plugins/builtin/sec/model.ts +2 -0
- package/src/plugins/builtin/sectors/index.tsx +11 -5
- package/src/plugins/builtin/series-inventory.ts +2 -0
- package/src/plugins/builtin/shared/cloud-resource.ts +73 -8
- package/src/plugins/builtin/shared/cloud-upgrade.ts +24 -1
- package/src/plugins/builtin/shared/forming-bars.ts +29 -0
- package/src/plugins/builtin/shared/fred-points.ts +6 -1
- package/src/plugins/builtin/shared/fx-rate-freshness.ts +17 -0
- package/src/plugins/builtin/shared/pro-lock-note.ts +23 -8
- package/src/plugins/builtin/shared/series-detail-chart.tsx +4 -2
- package/src/plugins/builtin/shared/series-warning.ts +13 -4
- package/src/plugins/builtin/shared/use-quote-board.ts +5 -0
- package/src/plugins/builtin/short-interest/publications-pane.tsx +2 -1
- package/src/plugins/builtin/short-volume/pane.tsx +2 -1
- package/src/plugins/builtin/short-volume/series.ts +2 -3
- package/src/plugins/builtin/social-mentions/client.ts +15 -10
- package/src/plugins/builtin/social-mentions/index.tsx +1 -2
- package/src/plugins/builtin/social-mentions/pane.tsx +2 -1
- package/src/plugins/builtin/social-mentions/series.ts +2 -3
- package/src/plugins/builtin/supply-chain/client.ts +22 -1
- package/src/plugins/builtin/supply-chain/graph-client.ts +22 -1
- package/src/plugins/builtin/supply-chain/index.tsx +1 -2
- package/src/plugins/builtin/thirteenf/api.ts +127 -29
- package/src/plugins/builtin/thirteenf/data.ts +165 -35
- package/src/plugins/builtin/thirteenf/index.tsx +2 -4
- package/src/plugins/builtin/thirteenf/model.ts +2 -0
- package/src/plugins/builtin/thirteenf/overlap-pane.tsx +5 -1
- package/src/plugins/builtin/thirteenf/pane.tsx +41 -16
- package/src/plugins/builtin/thirteenf/types.ts +14 -0
- package/src/plugins/builtin/ticker-detail/data-panes/historical-prices.tsx +22 -6
- package/src/plugins/builtin/ticker-detail/data-panes/returns-history.ts +81 -11
- package/src/plugins/builtin/ticker-detail/financials/model.ts +35 -2
- package/src/plugins/builtin/ticker-detail/financials/ratios.ts +53 -18
- package/src/plugins/builtin/ticker-detail/headless.ts +70 -11
- package/src/plugins/builtin/ticker-detail/index.tsx +5 -10
- package/src/plugins/builtin/ticker-detail/overview-tab.tsx +16 -6
- package/src/plugins/builtin/time-sales/index.tsx +1 -2
- package/src/plugins/builtin/time-sales/pane.tsx +3 -1
- package/src/plugins/builtin/trace-bonds/headless.ts +11 -2
- package/src/plugins/builtin/trace-bonds/model.ts +44 -10
- package/src/plugins/builtin/trace-bonds/pane.tsx +12 -7
- package/src/plugins/builtin/treasury-auctions/cache.ts +20 -8
- package/src/plugins/builtin/treasury-auctions/client.ts +3 -3
- package/src/plugins/builtin/treasury-auctions/headless.ts +3 -1
- package/src/plugins/builtin/treasury-auctions/pane.tsx +10 -4
- package/src/plugins/builtin/vol-surface/client.ts +18 -3
- package/src/plugins/builtin/vol-surface/index.tsx +1 -2
- package/src/plugins/builtin/volatility/client.ts +43 -16
- package/src/plugins/builtin/volatility/headless.ts +5 -2
- package/src/plugins/builtin/volatility/index.tsx +1 -2
- package/src/plugins/builtin/volatility/model.ts +17 -6
- package/src/plugins/builtin/volatility/pane.tsx +6 -2
- package/src/plugins/builtin/volatility/series.ts +2 -1
- package/src/plugins/builtin/world-indices/footer.ts +6 -1
- package/src/plugins/builtin/world-venue-map/client.ts +10 -1
- package/src/plugins/builtin/world-venue-map/index.ts +6 -2
- package/src/plugins/builtin/world-venue-map/layered-pane.tsx +48 -7
- package/src/plugins/builtin/world-venue-map/layers.ts +17 -0
- package/src/plugins/builtin/world-venue-map/local-layers.ts +141 -0
- package/src/plugins/builtin/world-venue-map/map-symbols.ts +18 -0
- package/src/plugins/builtin/world-venue-map/map.tsx +4 -2
- package/src/plugins/builtin/world-venue-map/scope.ts +63 -0
- package/src/plugins/builtin/yield-curve/client.ts +4 -6
- package/src/plugins/builtin/yield-curve/curves.ts +16 -2
- package/src/plugins/builtin/yield-curve/headless.ts +3 -3
- package/src/plugins/bundle.ts +52 -2
- package/src/plugins/catalog-browser.ts +2 -2
- package/src/plugins/catalog-cli.ts +20 -0
- package/src/plugins/host-link.ts +13 -1
- package/src/plugins/installer.ts +64 -42
- package/src/plugins/loader.ts +43 -11
- package/src/plugins/peer-imports.ts +201 -0
- package/src/plugins/peer-retry.ts +26 -29
- package/src/plugins/plugin-process.ts +128 -0
- package/src/plugins/redirection-guard.ts +45 -0
- package/src/remote/endpoint.ts +16 -3
- package/src/renderers/browser/main.tsx +3 -2
- package/src/renderers/cloudflare/http-proxy.ts +7 -123
- package/src/renderers/dom/desktop/icons.tsx +5 -2
- package/src/renderers/dom/host/image-surface.tsx +46 -21
- package/src/renderers/dom/styles.css +7 -0
- package/src/renderers/dom/toast-host.tsx +2 -0
- package/src/renderers/electrobun/bun/desktop/backend.ts +7 -1
- package/src/renderers/electrobun/bun/desktop/detached-windows.ts +23 -1
- package/src/renderers/electrobun/bun/desktop/initialization.ts +12 -3
- package/src/renderers/electrobun/bun/desktop/rpc-timing.ts +88 -0
- package/src/renderers/electrobun/bun/desktop/update.ts +20 -4
- package/src/renderers/electrobun/bun/desktop/view-ids.ts +8 -4
- package/src/renderers/electrobun/bun/external-plugins.ts +4 -0
- package/src/renderers/electrobun/bun/window/attention.ts +54 -0
- package/src/renderers/electrobun/bun/window/create.ts +6 -2
- package/src/renderers/electrobun/bun/window/native-timing.ts +48 -0
- package/src/renderers/electrobun/view/cli-pane-shot-entry.tsx +82 -4
- package/src/renderers/electrobun/view/cli-pane-shot-frame.tsx +13 -5
- package/src/renderers/electrobun/view/desktop/window/snapshot.ts +3 -0
- package/src/renderers/electrobun/view/main.tsx +7 -2
- package/src/renderers/electrobun/view/remote/asset-data-client.ts +1 -0
- package/src/renderers/electrobun/view/ui-host.tsx +9 -2
- package/src/renderers/opentui/browser-open.ts +10 -4
- package/src/renderers/opentui/image/surface.tsx +1 -1
- package/src/renderers/opentui/start.tsx +12 -6
- package/src/renderers/opentui/toast-host.tsx +2 -1
- package/src/series/registry.ts +18 -0
- package/src/series/resolve.ts +2 -1
- package/src/series/standalone.ts +10 -1
- package/src/series/types.ts +12 -0
- package/src/series/validate.ts +11 -2
- package/src/sources/gloomberb-cloud/fred-series.ts +5 -3
- package/src/sources/gloomberb-cloud/index.ts +28 -5
- package/src/sources/gloomberb-cloud/news.ts +24 -3
- package/src/sources/gloomberb-cloud/normalizers.ts +17 -2
- package/src/sources/provider-errors.ts +26 -3
- package/src/sources/provider-router/history.ts +5 -0
- package/src/sources/provider-router/index.ts +13 -0
- package/src/sync/core-contributors.ts +32 -0
- package/src/telemetry/attention-counts.ts +64 -6
- package/src/telemetry/attention-setting.ts +33 -0
- package/src/telemetry/crash-reports-node.ts +3 -1
- package/src/telemetry/stall-clocks.ts +93 -0
- package/src/telemetry/stall-reports-node.ts +25 -9
- package/src/telemetry/stall-reports.ts +218 -13
- package/src/test-support/outage.ts +8 -0
- package/src/test-support/preload.ts +9 -0
- package/src/tickers/company-name-listing.ts +59 -29
- package/src/tickers/company-name.ts +84 -1
- package/src/tickers/listing-fate.ts +14 -3
- package/src/tickers/saved-instrument.ts +17 -0
- package/src/tickers/search/home-listing.ts +104 -8
- package/src/tickers/search/index.ts +5 -2
- package/src/tickers/search/types.ts +6 -1
- package/src/time-series/bar-aggregation.ts +7 -1
- package/src/time-series/base-series.ts +3 -3
- package/src/time-series/chart-bounds.ts +1 -1
- package/src/time-series/chart-data.ts +5 -2
- package/src/time-series/chart-seed.ts +1 -1
- package/src/time-series/coin-session-close.ts +211 -0
- package/src/time-series/live-bars.ts +13 -2
- package/src/time-series/live-quotes.ts +1 -1
- package/src/time-series/market.ts +5 -3
- package/src/time-series/official-close.ts +159 -0
- package/src/time-series/price-comparison.ts +75 -8
- package/src/time-series/resolve.ts +32 -4
- package/src/time-series/series-presentation.ts +1 -1
- package/src/time-series/studies/formula.ts +205 -0
- package/src/time-series/studies/indicators.ts +299 -0
- package/src/time-series/studies/leverage.ts +75 -0
- package/src/time-series/studies/pair.ts +138 -0
- package/src/time-series/studies/resolve.ts +333 -0
- package/src/time-series/studies/shared.ts +141 -0
- package/src/time-series/studies/units.ts +243 -0
- package/src/time-series/studies/vwap.ts +274 -0
- package/src/time-series/types.ts +7 -0
- package/src/types/config.ts +18 -2
- package/src/types/data-provider.ts +23 -0
- package/src/types/financials.ts +40 -3
- package/src/types/headless.ts +42 -3
- package/src/types/plugin.ts +32 -3
- package/src/ui/host.tsx +17 -1
- package/src/ui/toast.tsx +26 -1
- package/src/utils/ascii-text.ts +140 -0
- package/src/utils/cli-output.ts +91 -18
- package/src/utils/concurrency.ts +24 -0
- package/src/utils/exchanges.ts +6 -0
- package/src/utils/external-url.ts +20 -7
- package/src/utils/financial-statements.ts +73 -16
- package/src/utils/fundamentals.ts +17 -5
- package/src/utils/futures-generic.ts +4 -4
- package/src/utils/http-proxy-upstream.ts +124 -0
- package/src/utils/lease-liabilities.ts +54 -0
- package/src/utils/main-thread-stall.ts +122 -5
- package/src/utils/perf-marks.ts +58 -12
- package/src/utils/price-history-integrity.ts +47 -1
- package/src/utils/private-files.ts +141 -0
- package/src/utils/public-address.ts +99 -0
- package/src/account/upgrade-personalization.ts +0 -57
- package/src/account/upgrade-tickers.ts +0 -124
- package/src/api-client/upgrade-experiment.ts +0 -91
- package/src/plugins/builtin/cloud/browser.tsx +0 -3
- package/src/time-series/studies.ts +0 -1628
|
@@ -3,6 +3,7 @@ import { isSubMinuteInterval, subMinuteDataMessage } from "../../../cli/known-ga
|
|
|
3
3
|
import { CHART_BAR_SIZE_PRESETS, parseChartBarSize } from "../../../time-series/resolution";
|
|
4
4
|
import { FINANCIAL_PERIOD_OPTION, FINANCIAL_PERIOD_COUNT_OPTION, HISTORY_RANGE_VALUES, RETURN_RANGE_VALUES } from "../shared/headless-options";
|
|
5
5
|
import { DATE_OPTION_EXAMPLES } from "../../../utils/calendar-date";
|
|
6
|
+
import { PRICE_WINDOW_FROM_HELP, PRICE_WINDOW_TO_HELP } from "../../../utils/price-window";
|
|
6
7
|
|
|
7
8
|
type PaneSchema = Pick<HeadlessPaneDefinition, "argument" | "options" | "discovery">;
|
|
8
9
|
|
|
@@ -51,6 +52,11 @@ export const paneSchemas = {
|
|
|
51
52
|
values: [{ value: "auto" }, ...BAR_SIZES],
|
|
52
53
|
normalize: (value) => normalizeBarSize(value, true),
|
|
53
54
|
},
|
|
55
|
+
{
|
|
56
|
+
key: "exchange",
|
|
57
|
+
description: "Exchange for every ticker that names none: fn G BDI --exchange TSX is fn G BDI:TSX.",
|
|
58
|
+
type: "string",
|
|
59
|
+
},
|
|
54
60
|
],
|
|
55
61
|
discovery: {
|
|
56
62
|
id: "chart-composer",
|
|
@@ -138,6 +144,10 @@ export const paneSchemas = {
|
|
|
138
144
|
],
|
|
139
145
|
defaultValue: "percent",
|
|
140
146
|
},
|
|
147
|
+
// A window of dates, measured from the close before it as RETURN is: --from 2026-10-19 compares since the 16th's close.
|
|
148
|
+
{ key: "from", type: "string", placeholder: "year|date", description: `${PRICE_WINDOW_FROM_HELP}; the returns are measured from the last close the tickers share before it, as RETURN measures`,
|
|
149
|
+
example: "--from 2019-12-31", replaces: ["rangePreset"] },
|
|
150
|
+
{ key: "to", type: "string", placeholder: "year|date", description: PRICE_WINDOW_TO_HELP },
|
|
141
151
|
{
|
|
142
152
|
key: "totalReturn",
|
|
143
153
|
description: "Reinvest each cash distribution at its ex-date close, so the returns are total returns, not price returns.",
|
|
@@ -31,9 +31,12 @@ import type { TickerFinancials, PricePoint, Quote } from "../../../types/financi
|
|
|
31
31
|
import { chartQuoteOverrideKeyForTarget, getLiveChartQuoteTargets } from "../../../time-series/live-quotes";
|
|
32
32
|
import { createChartSeriesResolver } from "../../../capabilities";
|
|
33
33
|
import { loadFuturesContractTerms, loadFuturesPriceUnit } from "../../../market-data/futures-contract";
|
|
34
|
-
import { isUsListingExchange, parsePublicTickerKey, publicTickerKey } from "../../../utils/exchanges";
|
|
34
|
+
import { canonicalExchange, isKnownExchangeCode, isUsListingExchange, parsePublicTickerKey, publicTickerKey } from "../../../utils/exchanges";
|
|
35
35
|
import { zonedDateTimeParts } from "../../../utils/zoned-date-time";
|
|
36
36
|
import { futuresSessionOpenMinute } from "../../../market-data/market/trading-sessions";
|
|
37
|
+
import { isAlwaysOpenExchange, isRegularSessionTime } from "../../../market-data/market/freshness";
|
|
38
|
+
import { isRoundTheClockCoin } from "../../../utils/crypto-pair";
|
|
39
|
+
import { isCurrencyPairListing } from "../../../utils/fx-market-hours";
|
|
37
40
|
import { cleanFloat32Price } from "../../../cli/history-rows";
|
|
38
41
|
import { parseChartSpec } from "./chart-spec";
|
|
39
42
|
import { paneSchemas } from "./headless-schema";
|
|
@@ -46,7 +49,8 @@ import { loadFundFacts } from "../sec/fund-facts";
|
|
|
46
49
|
import { comparedFundTickers, loadDailyObjectives, mayDrawDailyObjective, withLeverageOverlay } from "./leverage-overlay";
|
|
47
50
|
import { classifyInstrumentType } from "../../../tickers/instrument-kind";
|
|
48
51
|
import { priceComparisonEndsIntraday, type PriceComparison } from "../../../time-series/price-comparison";
|
|
49
|
-
import { LATEST_INTRADAY_TEXT } from "../../../market-data/market/period-return";
|
|
52
|
+
import { LATEST_INTRADAY_TEXT, periodDayText } from "../../../market-data/market/period-return";
|
|
53
|
+
import { CLOSING_PRINT_PENDING_TEXT, newestClosedSession, newestSessionClose, withOfficialCloses } from "../../../time-series/official-close";
|
|
50
54
|
|
|
51
55
|
export interface ChartPaneModel extends HeadlessSeriesResult {
|
|
52
56
|
/** The renderer consumes the full model; generic reports project series and metadata. */
|
|
@@ -368,10 +372,19 @@ function chartFreshness(
|
|
|
368
372
|
const coarsest = resolutions.reduce((worst, resolution) => (
|
|
369
373
|
order.indexOf(resolution!) > order.indexOf(worst!) ? resolution : worst
|
|
370
374
|
), resolutions[0]);
|
|
375
|
+
const closedDay = closedPriceBarDay(series);
|
|
376
|
+
// A window that ended before today (`--to 2026-10-23`) is the history asked for, which no later close makes stale:
|
|
377
|
+
// `daily closes through Fri 23 Oct`.
|
|
378
|
+
const windowEnd = spec.viewport.dateWindow?.end;
|
|
379
|
+
if (windowEnd && /^\d{4}-\d{2}-\d{2}$/.test(windowEnd) && windowEnd < new Date().toISOString().slice(0, 10)) {
|
|
380
|
+
const through = closedDay ?? series.flatMap((entry) => entry.points.at(-1)?.date ?? []).map((date) => new Date(date).toISOString().slice(0, 10)).sort().at(-1);
|
|
381
|
+
const basis = coarsest === "1d" ? "daily closes" : coarsest === "1wk" ? "weekly closes" : coarsest === "1mo" ? "monthly closes" : "intraday bars";
|
|
382
|
+
return { status: "not-a-feed", basis: through ? `${basis} through ${periodDayText(through, new Date().getUTCFullYear())}` : basis,
|
|
383
|
+
...(through && closedDay ? { asOf: through } : {}), oldest: null };
|
|
384
|
+
}
|
|
371
385
|
const forming = formingPriceBar(series);
|
|
372
386
|
// A history: its first bars are not stale data, so the line dates it by the bar still forming alone.
|
|
373
387
|
if (forming) return { ...barHistoryFreshness(coarsest), periodToDate: forming, oldest: null };
|
|
374
|
-
const closedDay = closedPriceBarDay(series);
|
|
375
388
|
// A comparison whose newest point is a session still trading is not a day's closes.
|
|
376
389
|
const basis = coarsest === "1d" && priceComparisonEndsIntraday(comparison) ? { basis: LATEST_INTRADAY_TEXT } : {};
|
|
377
390
|
// Daily bars are dated by the time of the newest point: a closed session's day, or when a session still trading was last quoted.
|
|
@@ -600,30 +613,34 @@ export function argumentWithListing(argument: string, symbol: string, key: strin
|
|
|
600
613
|
}
|
|
601
614
|
|
|
602
615
|
/**
|
|
603
|
-
* A
|
|
604
|
-
*
|
|
605
|
-
*
|
|
606
|
-
*
|
|
607
|
-
*
|
|
616
|
+
* A catalog series typed where a ticker goes, as its chart: a FRED series id
|
|
617
|
+
* (`fn G DFII10` is FRED:DFII10), or a word a series lists as an alias
|
|
618
|
+
* (`fn G hashrate` is CAP:bitcoin:hashrate), when the catalog lists it, no
|
|
619
|
+
* listing answers to it, and the quote source says it is not a ticker. A
|
|
620
|
+
* real ticker of the same letters, read as a listing or quoted, still charts
|
|
621
|
+
* as the ticker; null then, and for any other symbol.
|
|
608
622
|
*/
|
|
609
|
-
export async function
|
|
623
|
+
export async function bareCatalogSeries(
|
|
610
624
|
series: ChartSeriesSpec,
|
|
611
625
|
readListing: () => Promise<unknown>,
|
|
612
|
-
context: Pick<HeadlessPaneContext, "marketData" | "catalogSeriesName">,
|
|
626
|
+
context: Pick<HeadlessPaneContext, "marketData" | "catalogSeriesName" | "catalogSeriesNamed">,
|
|
613
627
|
): Promise<ChartSeriesSpec | null> {
|
|
614
628
|
const { source } = series;
|
|
615
629
|
if (source.kind !== "security" || source.instrument.exchange || source.instrument.instrument || source.fieldId !== CHART_FIELD_IDS.price) return null;
|
|
616
630
|
const id = source.instrument.symbol.trim().toUpperCase();
|
|
617
631
|
const expression = `FRED:${id}`;
|
|
618
|
-
const
|
|
632
|
+
const fredLabel = /^[A-Z0-9]+$/.test(id)
|
|
619
633
|
? context.catalogSeriesName?.(expression) ?? getSharedRegistry()?.series?.findByExpression(expression)?.definition.name
|
|
620
634
|
: undefined;
|
|
635
|
+
const named = fredLabel ? undefined : context.catalogSeriesNamed?.(id);
|
|
636
|
+
const parsed = named ? parseSeriesExpression(named.expression) : null;
|
|
637
|
+
const label = fredLabel ?? (parsed ? named?.name : undefined);
|
|
621
638
|
if (!label || await readListing()) return null;
|
|
622
639
|
const failure = await Promise.resolve().then(() => context.marketData.getQuote(id, ""))
|
|
623
640
|
.then((quote) => quote ? null : `Not a ticker: ${id}.`, (error: unknown) => error instanceof Error ? error.message : String(error));
|
|
624
641
|
if (!failure || !notATickerSymbol(failure)) return null;
|
|
625
|
-
const
|
|
626
|
-
return { ...
|
|
642
|
+
const spec = parsed ? buildSeriesSpec({ ...parsed, label }, 0) : buildSeriesSpec({ kind: "economic", provider: "fred", seriesId: id, label }, 0);
|
|
643
|
+
return { ...spec, id: series.id, transform: series.transform, axis: series.axis, panelId: series.panelId };
|
|
627
644
|
}
|
|
628
645
|
|
|
629
646
|
/**
|
|
@@ -646,14 +663,28 @@ async function possibleFundTickers(spec: ChartSpec, context: HeadlessPaneContext
|
|
|
646
663
|
});
|
|
647
664
|
}
|
|
648
665
|
|
|
666
|
+
/**
|
|
667
|
+
* `--exchange TSX`: every ticker series that names no venue, on that one, as
|
|
668
|
+
* `BDI:TSX` would be. A code the app does not know fails before any request.
|
|
669
|
+
*/
|
|
670
|
+
function onExchange(spec: ChartSpec, exchange: string): ChartSpec {
|
|
671
|
+
const code = exchange.trim().toUpperCase();
|
|
672
|
+
if (!isKnownExchangeCode(code)) throw new Error(`Unknown exchange "${exchange.trim()}". Write a venue code such as TSX, LSE or XETRA, or name it in the series: BDI:TSX.`);
|
|
673
|
+
return { ...spec, series: spec.series.map((series) => series.source.kind !== "security" || series.source.instrument.exchange || series.source.instrument.instrument
|
|
674
|
+
? series
|
|
675
|
+
: { ...series, source: { ...series.source, instrument: { ...series.source.instrument, exchange: canonicalExchange(code) } } }) };
|
|
676
|
+
}
|
|
677
|
+
|
|
649
678
|
export function chartHeadless(template: keyof typeof paneSchemas): HeadlessPaneDefinition<"series"> {
|
|
650
679
|
return {
|
|
651
680
|
...paneSchemas[template],
|
|
652
681
|
shape: "series",
|
|
653
682
|
async load(args, context) {
|
|
654
683
|
const intradayHistories: ChartPaneModel["snapshot"]["intradayHistories"] = [];
|
|
655
|
-
const
|
|
656
|
-
|
|
684
|
+
const closingPrintsPending: string[] = [];
|
|
685
|
+
const stored = parseChartSpec(context.settings?.chartSpec);
|
|
686
|
+
if (!stored) throw new Error("The chart specification is invalid.");
|
|
687
|
+
const saved = typeof args.options.exchange === "string" ? onExchange(stored, args.options.exchange) : stored;
|
|
657
688
|
// A leveraged or inverse fund compared with anything draws its daily objective beside it.
|
|
658
689
|
const parsed = template === "comparison-chart-pane" && mayDrawDailyObjective(saved)
|
|
659
690
|
? withLeverageOverlay(saved, await loadDailyObjectives(
|
|
@@ -680,9 +711,9 @@ export function chartHeadless(template: keyof typeof paneSchemas): HeadlessPaneD
|
|
|
680
711
|
series: await Promise.all(parsed.series.map(async (series) => {
|
|
681
712
|
if (series.source.kind !== "security" || series.source.instrument.exchange) return series;
|
|
682
713
|
const { symbol } = series.source.instrument;
|
|
683
|
-
// A FRED id no ticker answers to
|
|
684
|
-
const
|
|
685
|
-
if (
|
|
714
|
+
// A FRED id (DFII10) or a series alias (hashrate) no ticker answers to is that series; an intraday chart has none.
|
|
715
|
+
const catalog = template === "graph-intraday-price-pane" ? null : await bareCatalogSeries(series, () => readListing(symbol), context);
|
|
716
|
+
if (catalog) return catalog;
|
|
686
717
|
if (!reads.has(symbol)) reads.set(symbol, readSeriesListing(symbol));
|
|
687
718
|
const instrument = await reads.get(symbol)!;
|
|
688
719
|
return instrument ? { ...series, source: { ...series.source, instrument: { ...series.source.instrument, ...instrument } } } : series;
|
|
@@ -709,6 +740,37 @@ export function chartHeadless(template: keyof typeof paneSchemas): HeadlessPaneD
|
|
|
709
740
|
...await loadIntradayWindow({ provider: context.marketData, symbol: target.symbol, exchange: target.exchange ?? "", request, context: { brokerId: target.brokerId, brokerInstanceId: target.brokerInstanceId, instrument: target.instrument } }),
|
|
710
741
|
})));
|
|
711
742
|
context.signal.throwIfAborted();
|
|
743
|
+
// Once a session has closed, its last bar ends on the official close (the closing auction's print), as
|
|
744
|
+
// `history` and CMP give it, not on the last trade before it; until the quote has that close, the footer says so.
|
|
745
|
+
await Promise.all(histories.map(async (history) => {
|
|
746
|
+
// A future settles rather than closing on an auction print, and a coin or a currency pair has no session
|
|
747
|
+
// to close: their bars stay as traded, and no quote is read for them.
|
|
748
|
+
if (!history.points.length || futuresSessionOpenMinute(history.symbol, history.exchange) != null
|
|
749
|
+
|| isRoundTheClockCoin(history.symbol, history.exchange) || isCurrencyPairListing(history.symbol, history.exchange)) return;
|
|
750
|
+
const now = Date.now();
|
|
751
|
+
const known = history.exchange || history.quote?.listingExchangeName || history.quote?.exchangeName || undefined;
|
|
752
|
+
if (known && isAlwaysOpenExchange(known)) return;
|
|
753
|
+
// While the session trades, no session of the chart has closed since its bars were read.
|
|
754
|
+
if (history.quote?.marketState === "REGULAR" || (known && isRegularSessionTime(known, now) === true)) return;
|
|
755
|
+
if (known && !newestClosedSession(history.points, { venue: known, now })) return;
|
|
756
|
+
// A captured shot's source can have no quotes: its bars are drawn as captured.
|
|
757
|
+
const quote = history.quote ?? (typeof context.marketData.getQuote === "function"
|
|
758
|
+
? await Promise.resolve(context.marketData.getQuote(history.symbol, history.exchange,
|
|
759
|
+
{ brokerId: history.target.brokerId, brokerInstanceId: history.target.brokerInstanceId, instrument: history.target.instrument }))
|
|
760
|
+
.catch(logFailure("chart-composer.headless", "Read the official close of an intraday chart failed", null))
|
|
761
|
+
: null);
|
|
762
|
+
const venue = known || quote?.listingExchangeName || quote?.exchangeName || undefined;
|
|
763
|
+
const newest = newestClosedSession(history.points, { venue, now });
|
|
764
|
+
const decided = newest ? newestSessionClose(quote, { ...newest, venue }) : null;
|
|
765
|
+
if (!newest || !decided) return;
|
|
766
|
+
if ("pending" in decided) {
|
|
767
|
+
closingPrintsPending.push(history.symbol);
|
|
768
|
+
return;
|
|
769
|
+
}
|
|
770
|
+
const closes = new Map([[newest.date, decided.close]]);
|
|
771
|
+
history.points = withOfficialCloses(history.points, closes, { venue, now });
|
|
772
|
+
history.bufferedPoints = withOfficialCloses(history.bufferedPoints, closes, { venue, now });
|
|
773
|
+
}));
|
|
712
774
|
intradayHistories.push(...histories);
|
|
713
775
|
const starts = histories.flatMap(({ start }) => start ? [start.getTime()] : []);
|
|
714
776
|
const ends = histories.flatMap(({ end }) => end ? [end.getTime()] : []);
|
|
@@ -725,9 +787,11 @@ export function chartHeadless(template: keyof typeof paneSchemas): HeadlessPaneD
|
|
|
725
787
|
}, context.marketData) };
|
|
726
788
|
}
|
|
727
789
|
const model = await loadChartPaneModel(spec, context);
|
|
728
|
-
//
|
|
729
|
-
|
|
730
|
-
|
|
790
|
+
// What became of the company that had a bare symbol (GOGL), and a bare coin ticker charted as another listing
|
|
791
|
+
// (ETH, the Grayscale fund), are said as `quote` says them.
|
|
792
|
+
const readListings = await Promise.all(listings.values());
|
|
793
|
+
const listingNotes = [...readListings.flatMap((read) => read?.successorNote ?? []), ...readListings.flatMap((read) => read?.coinNote ?? [])];
|
|
794
|
+
if (listingNotes.length) model.warnings = [...model.warnings ?? [], ...listingNotes];
|
|
731
795
|
if (template === "graph-intraday-price-pane" && !intradayHistories.length && model.chart.viewport) {
|
|
732
796
|
const { start, end } = model.chart.viewport;
|
|
733
797
|
for (const { target, data } of [
|
|
@@ -782,6 +846,9 @@ export function chartHeadless(template: keyof typeof paneSchemas): HeadlessPaneD
|
|
|
782
846
|
model.metadata = { ...model.metadata, resolution: dropped.drop };
|
|
783
847
|
}
|
|
784
848
|
model.freshness = chartFreshness(model.series, model.spec, model.chart.priceComparison, chartQuoteTimes(model));
|
|
849
|
+
if (closingPrintsPending.length) {
|
|
850
|
+
model.freshness = { ...model.freshness, note: [model.freshness.note, CLOSING_PRINT_PENDING_TEXT].filter(Boolean).join(", ") };
|
|
851
|
+
}
|
|
785
852
|
const priceDomainFailures = intradayHistories.flatMap(({ symbol, exchange, priceDomainFailure }) =>
|
|
786
853
|
priceDomainFailure ? [{ symbol, exchange, ...priceDomainFailure }] : []);
|
|
787
854
|
if (priceDomainFailures.length) {
|
|
@@ -11,7 +11,6 @@ import { canonicalExchange, parsePublicTickerKey, publicTickerKey } from "../../
|
|
|
11
11
|
import { tickerInstrumentLabel } from "../../../tickers/instrument-label";
|
|
12
12
|
import type { ChartSpec } from "../../../time-series/types";
|
|
13
13
|
import { ChartComposerPane, ChartComposerResearchTab } from "./pane";
|
|
14
|
-
import { DataCatalogPane } from "./data-catalog-pane";
|
|
15
14
|
import { listFieldSeries } from "./field-series";
|
|
16
15
|
import { registeredSeriesName } from "./series-expression";
|
|
17
16
|
import {
|
|
@@ -404,7 +403,7 @@ const chartComposerTemplates: PaneTemplateDef[] = [
|
|
|
404
403
|
"positioning",
|
|
405
404
|
],
|
|
406
405
|
shortcut: { prefix: "CAT", argPlaceholder: "query", argKind: "text", argOptional: true },
|
|
407
|
-
reportFreshness: { status: "not-a-feed", basis: "series catalog" },
|
|
406
|
+
reportFreshness: { status: "not-a-feed", basis: "series catalog", local: true },
|
|
408
407
|
canCreate: () => true,
|
|
409
408
|
createInstance: (_context, options) => {
|
|
410
409
|
const query = options?.arg?.trim() ?? options?.values?.query?.trim() ?? "";
|
|
@@ -525,7 +524,7 @@ export const chartComposerModule: PluginModule = {
|
|
|
525
524
|
id: DATA_CATALOG_PANE_ID,
|
|
526
525
|
name: "Data Catalog",
|
|
527
526
|
icon: "C",
|
|
528
|
-
component: DataCatalogPane,
|
|
527
|
+
get component(): typeof import("./data-catalog-pane").DataCatalogPane { const { DataCatalogPane } = require("./data-catalog-pane"); return DataCatalogPane; },
|
|
529
528
|
defaultPosition: "right",
|
|
530
529
|
defaultMode: "floating",
|
|
531
530
|
defaultFloatingSize: { width: 110, height: 32 },
|
|
@@ -20,6 +20,7 @@ import {
|
|
|
20
20
|
type MultiSelectRowAction,
|
|
21
21
|
} from "../../../components/ui";
|
|
22
22
|
import { CompositeChart } from "../../../components/chart/composite";
|
|
23
|
+
import { savedCopyFooterInfo } from "../../../components/layout/pane/footer";
|
|
23
24
|
import { useChartViewReset, useChartViewResetListener } from "../../../components/chart/core/view-reset";
|
|
24
25
|
import { formatCompositeDatasetDate } from "../../../components/chart/composite/format";
|
|
25
26
|
import type { CompositeChartLevels, CompositeLevelEdit } from "../../../components/chart/composite/levels";
|
|
@@ -140,7 +141,10 @@ import { alertInstrument, syncAlertQuoteStream } from "../alerts/live";
|
|
|
140
141
|
import { getSharedMarketDataCoordinator } from "../../../market-data/coordinator";
|
|
141
142
|
import { useOptionChartRange } from "./option-range";
|
|
142
143
|
import { getActiveQuoteDisplay } from "../../../market-data/market/status";
|
|
143
|
-
import { resolveEntryData } from "../../../market-data/selectors";
|
|
144
|
+
import { buildQuoteKey, resolveEntryData } from "../../../market-data/selectors";
|
|
145
|
+
import { useQuoteEntries } from "../../../market-data/hooks";
|
|
146
|
+
import { usePlanAccess } from "../../../api-client/plan-access";
|
|
147
|
+
import { useQuoteDelayFooter } from "../shared/cloud-upgrade";
|
|
144
148
|
import { editPriceLevels, parsePriceLevels, PRICE_LEVELS_KEY, priceLevelTickerKey } from "./price-levels";
|
|
145
149
|
import { canonicalExchange } from "../../../utils/exchanges";
|
|
146
150
|
import { resolveInstrumentForPane } from "../../../core/state/app/instrument";
|
|
@@ -217,6 +221,8 @@ interface ChartComposerSurfaceProps {
|
|
|
217
221
|
onCapture?: (capturing: boolean) => void;
|
|
218
222
|
/** The legend names each series' company; a ticker's own research tab already does. */
|
|
219
223
|
nameSeries?: boolean;
|
|
224
|
+
/** The footer's delayed clock; a ticker's research tab says it in its quote footer instead. */
|
|
225
|
+
delayFooter?: boolean;
|
|
220
226
|
}
|
|
221
227
|
|
|
222
228
|
const QUICK_ADD_CAPTURE = "quick-add";
|
|
@@ -306,6 +312,7 @@ function ChartComposerSurface({
|
|
|
306
312
|
footerId,
|
|
307
313
|
onCapture,
|
|
308
314
|
nameSeries = true,
|
|
315
|
+
delayFooter = true,
|
|
309
316
|
}: ChartComposerSurfaceProps) {
|
|
310
317
|
const trade = useResearchTrading();
|
|
311
318
|
const dialog = useDialog();
|
|
@@ -1116,9 +1123,28 @@ function ChartComposerSurface({
|
|
|
1116
1123
|
}
|
|
1117
1124
|
return newest > end ? formatCompositeDatasetDate(new Date(newest), end) : null;
|
|
1118
1125
|
}, [activeRuntimeViewport, plottedSeries, spec, viewport]);
|
|
1126
|
+
// A series a failed refresh left on a saved copy says when that copy was saved, as every pane does.
|
|
1127
|
+
const savedAt = resolution.savedAt;
|
|
1128
|
+
// Signed out or free, a market series' latest bars are built from delayed quotes.
|
|
1129
|
+
const marketInstruments = useMemo(() => (delayFooter ? spec.series.flatMap((entry) => (
|
|
1130
|
+
entry.source.kind === "security" && isMarketFieldId(entry.source.fieldId) ? [entry.source.instrument] : []
|
|
1131
|
+
)) : []), [delayFooter, spec.series]);
|
|
1132
|
+
const marketQuotes = useQuoteEntries(marketInstruments);
|
|
1133
|
+
// Signed out no stream feeds a chart's quotes: without Pro the chart reads them once to know which are late.
|
|
1134
|
+
const { hasProAccess } = usePlanAccess();
|
|
1135
|
+
const marketQuoteKey = marketInstruments.map(buildQuoteKey).join("\u001f");
|
|
1136
|
+
useEffect(() => {
|
|
1137
|
+
const coordinator = getSharedMarketDataCoordinator();
|
|
1138
|
+
if (hasProAccess || !coordinator) return;
|
|
1139
|
+
for (const instrument of marketInstruments) {
|
|
1140
|
+
void coordinator.loadQuote(instrument).catch(logFailure("chart-composer.pane", "Loading a chart quote failed"));
|
|
1141
|
+
}
|
|
1142
|
+
}, [hasProAccess, marketQuoteKey]);
|
|
1143
|
+
const quoteDelay = useQuoteDelayFooter(Array.from(marketQuotes.values(), resolveEntryData), "chart-delay");
|
|
1119
1144
|
usePaneFooter(footerId, () => ({
|
|
1120
1145
|
info: [
|
|
1121
1146
|
...(delistingKey ? [{ id: "delisted", parts: [{ text: delistingKey, tone: "warning" as const }] }] : []),
|
|
1147
|
+
...savedCopyFooterInfo([savedAt]),
|
|
1122
1148
|
...(loading
|
|
1123
1149
|
? [{ id: "loading", parts: [{ text: "loading", tone: "muted" as const }] }]
|
|
1124
1150
|
: pickingAnchor
|
|
@@ -1126,6 +1152,7 @@ function ChartComposerSurface({
|
|
|
1126
1152
|
: newestBeyondView
|
|
1127
1153
|
? [{ id: "newest", asOf: true, parts: [{ text: `newest ${newestBeyondView}`, tone: "muted" as const }] }]
|
|
1128
1154
|
: []),
|
|
1155
|
+
...(quoteDelay ? [quoteDelay] : []),
|
|
1129
1156
|
],
|
|
1130
1157
|
hints: [
|
|
1131
1158
|
// One key opens the ticket, which chooses Buy or Sell; [s]eries keeps its key with trading on.
|
|
@@ -1136,7 +1163,7 @@ function ChartComposerSurface({
|
|
|
1136
1163
|
{ id: "resolution", key: "b", label: "ars", title: "Bar Size", onPress: footerResolution },
|
|
1137
1164
|
...(anchorable ? [{ id: "vwap-anchor", key: "v", label: "wap anchor", title: "Anchor VWAP", onPress: footerAnchor }] : []),
|
|
1138
1165
|
],
|
|
1139
|
-
}), [delistingKey, loading, pickingAnchor, newestBeyondView, footerSeries, openIndicators, indicatorsDisabled, openFormulas, formulasDisabled, footerResolution, anchorable, footerAnchor, trade]);
|
|
1166
|
+
}), [delistingKey, savedAt, loading, pickingAnchor, newestBeyondView, quoteDelay, footerSeries, openIndicators, indicatorsDisabled, openFormulas, formulasDisabled, footerResolution, anchorable, footerAnchor, trade]);
|
|
1140
1167
|
|
|
1141
1168
|
// A fixed window (a GIP session) highlights no range, so the bar names it.
|
|
1142
1169
|
const dateWindowLabel = useMemo(() => {
|
|
@@ -1472,6 +1499,7 @@ export function ChartComposerResearchTab({ focused, width, height, onCapture }:
|
|
|
1472
1499
|
footerId="chart-composer:research"
|
|
1473
1500
|
onCapture={onCapture}
|
|
1474
1501
|
nameSeries={false}
|
|
1502
|
+
delayFooter={false}
|
|
1475
1503
|
/>
|
|
1476
1504
|
);
|
|
1477
1505
|
}
|
|
@@ -8,8 +8,8 @@ import {
|
|
|
8
8
|
listTimeSeriesFields,
|
|
9
9
|
} from "../../../time-series/field-catalog";
|
|
10
10
|
import {
|
|
11
|
-
CANONICAL_EXCHANGE_ALIASES,
|
|
12
11
|
canonicalExchange,
|
|
12
|
+
isKnownExchangeCode,
|
|
13
13
|
publicTickerKey,
|
|
14
14
|
} from "../../../utils/exchanges";
|
|
15
15
|
import { MAX_CHART_COMPOSER_SERIES } from "./chart-spec";
|
|
@@ -73,7 +73,8 @@ export function normalizeInstrument(
|
|
|
73
73
|
if (parts.length !== 2) return null;
|
|
74
74
|
const symbol = normalizeBaseSymbol(parts[0]!);
|
|
75
75
|
const exchangeToken = parts[1]!.trim().toUpperCase();
|
|
76
|
-
|
|
76
|
+
// Every venue the app names, as a listing's key writes it (BDI:NEO, Cboe Canada), not only the spellings it reads as another.
|
|
77
|
+
const knownExchange = isKnownExchangeCode(exchangeToken);
|
|
77
78
|
if (!symbol || !/^[A-Z0-9._-]{1,24}$/.test(exchangeToken) || (!knownExchange && !allowUnknownExchange)) {
|
|
78
79
|
return null;
|
|
79
80
|
}
|
|
@@ -4,6 +4,7 @@ import { cleanFloat32Price } from "../../../cli/history-rows";
|
|
|
4
4
|
import { exportNumber } from "../../../cli/report-tables";
|
|
5
5
|
import { publicTickerKey } from "../../../utils/exchanges";
|
|
6
6
|
import { formatUtcTime } from "../../../utils/utc-time";
|
|
7
|
+
import { pricePointWicks } from "../../../utils/price-history-integrity";
|
|
7
8
|
|
|
8
9
|
interface SessionExtreme {
|
|
9
10
|
price: number;
|
|
@@ -26,8 +27,10 @@ function sessionRange(points: readonly PricePoint[]): SessionRange | null {
|
|
|
26
27
|
for (const point of points) {
|
|
27
28
|
const at = point.date;
|
|
28
29
|
if (!(at instanceof Date) || !Number.isFinite(at.getTime())) continue;
|
|
29
|
-
|
|
30
|
-
const
|
|
30
|
+
// A wick too far from the bar's body to have traded is not a price the bars traded.
|
|
31
|
+
const wicks = pricePointWicks(point);
|
|
32
|
+
const pointLow = finitePositive(wicks.low) ?? finitePositive(point.close);
|
|
33
|
+
const pointHigh = finitePositive(wicks.high) ?? finitePositive(point.close);
|
|
31
34
|
if (pointLow != null && (!low || pointLow < low.price)) low = { price: pointLow, at };
|
|
32
35
|
if (pointHigh != null && (!high || pointHigh > high.price)) high = { price: pointHigh, at };
|
|
33
36
|
}
|
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
import type { ChartSpec, ChartStudyKind, ChartStudySpec, ResolvedSeries } from "../../../time-series/types";
|
|
2
2
|
import { observationDate } from "../../../time-series/price-comparison";
|
|
3
3
|
import { zonedWallClockToUtcMs } from "../../../utils/zoned-date-time";
|
|
4
|
-
import { DEFAULT_PROFILE_ROWS, vwapAnchors, withVwapAnchors } from "../../../time-series/studies";
|
|
4
|
+
import { DEFAULT_PROFILE_ROWS, vwapAnchors, withVwapAnchors } from "../../../time-series/studies/vwap";
|
|
5
5
|
import { reconcilePanels } from "./chart-spec-edit";
|
|
6
6
|
import { CHART_FIELD_IDS } from "./series-expression";
|
|
7
7
|
|
|
@@ -916,7 +916,7 @@ export class ChatController {
|
|
|
916
916
|
const channel = this.ensureChannelState(channelId);
|
|
917
917
|
mergeChatMessages({
|
|
918
918
|
channel,
|
|
919
|
-
|
|
919
|
+
currentUser: this.session.user,
|
|
920
920
|
messages,
|
|
921
921
|
options,
|
|
922
922
|
viewActive: this.appActive && channel.focusedViewCount > 0,
|
|
@@ -1,5 +1,6 @@
|
|
|
1
1
|
import type { ChatAttachment, ChatMessage } from "../../../../api-client";
|
|
2
2
|
import { toTimestampMillis } from "../../../../utils/timestamp";
|
|
3
|
+
import { isGloomWire } from "../ghost-user";
|
|
3
4
|
import type { ChannelRuntimeState, MergeMessagesOptions } from "./state";
|
|
4
5
|
import { PENDING_RECONCILE_WINDOW_MS } from "./state";
|
|
5
6
|
import { chatMessageMentionsUsername, compareMessages, normalizeChatUsername } from "./utils";
|
|
@@ -186,16 +187,26 @@ function getMentionMessages(messages: ChatMessage[], user: CurrentChatUser): Cha
|
|
|
186
187
|
|
|
187
188
|
interface MergeChatMessagesOptions {
|
|
188
189
|
channel: ChannelRuntimeState;
|
|
189
|
-
|
|
190
|
+
currentUser?: CurrentChatUser;
|
|
190
191
|
messages: ChatMessage[];
|
|
191
192
|
options?: MergeMessagesOptions;
|
|
192
193
|
viewActive: boolean;
|
|
193
194
|
markViewed: (persist?: boolean) => void;
|
|
194
195
|
}
|
|
195
196
|
|
|
197
|
+
/**
|
|
198
|
+
* New messages from others count as unread, as the server counts them: a
|
|
199
|
+
* Gloom Wire post only when it mentions you.
|
|
200
|
+
*/
|
|
201
|
+
function countUnread(messages: ChatMessage[], user: CurrentChatUser): number {
|
|
202
|
+
const fromPeople = messages.filter((message) => !isGloomWire(message.user));
|
|
203
|
+
const wireMentions = getMentionMessages(messages.filter((message) => isGloomWire(message.user)), user);
|
|
204
|
+
return fromPeople.length + wireMentions.length;
|
|
205
|
+
}
|
|
206
|
+
|
|
196
207
|
export function mergeChatMessages({
|
|
197
208
|
channel,
|
|
198
|
-
|
|
209
|
+
currentUser,
|
|
199
210
|
messages,
|
|
200
211
|
options,
|
|
201
212
|
viewActive,
|
|
@@ -203,11 +214,11 @@ export function mergeChatMessages({
|
|
|
203
214
|
}: MergeChatMessagesOptions): void {
|
|
204
215
|
reconcilePendingMessages(channel, messages);
|
|
205
216
|
const freshIncoming = mergeStoredMessages(channel, messages)
|
|
206
|
-
.filter((message) => message.user.id !==
|
|
217
|
+
.filter((message) => message.user.id !== currentUser?.id);
|
|
207
218
|
if (viewActive) {
|
|
208
219
|
markViewed(false);
|
|
209
220
|
} else if (freshIncoming.length > 0 && options?.countUnread !== false) {
|
|
210
|
-
channel.unreadCount += freshIncoming
|
|
221
|
+
channel.unreadCount += countUnread(freshIncoming, currentUser);
|
|
211
222
|
}
|
|
212
223
|
}
|
|
213
224
|
|
|
@@ -16,6 +16,14 @@ export function isManagedBot(user: Pick<ChatUserSummary, "accountType"> | null |
|
|
|
16
16
|
return user?.accountType === "managed_llm";
|
|
17
17
|
}
|
|
18
18
|
|
|
19
|
+
/** Gloom Wire: the account that posts headlines, the day's calendar and pull requests into the topic channels. */
|
|
20
|
+
const GLOOM_WIRE_USER_ID = "managed-llm-gloomwire";
|
|
21
|
+
|
|
22
|
+
/** A Gloom Wire post: there to read, so unread only when it mentions you. */
|
|
23
|
+
export function isGloomWire(user: Pick<ChatUserSummary, "id"> | null | undefined): boolean {
|
|
24
|
+
return user?.id === GLOOM_WIRE_USER_ID;
|
|
25
|
+
}
|
|
26
|
+
|
|
19
27
|
/**
|
|
20
28
|
* A reply quotes its author by name only, so whether that author is a managed
|
|
21
29
|
* assistant comes from the users the pane has seen. A quoted announcement is
|
|
@@ -16,11 +16,9 @@ import { CHAT_KEEP_CONVERSATION_VALUE, createChatSearchProvider } from "./comman
|
|
|
16
16
|
import { chatController } from "./controller";
|
|
17
17
|
import { buildChatConversations, selectChatConversations } from "./conversations";
|
|
18
18
|
import { pickChatPaneToReuse } from "./pane-state";
|
|
19
|
-
import { ChatPane } from "./pane";
|
|
20
19
|
import { chatSidebarStore } from "./sidebar-store";
|
|
21
20
|
import { chatHandlePromptStore } from "./handle-prompt";
|
|
22
21
|
import { ChatStatusWidget } from "./status-widget";
|
|
23
|
-
import { UnreadInboxPane } from "./unread-inbox-pane";
|
|
24
22
|
import { installPaneChatSharing } from "./share/flow";
|
|
25
23
|
import { attachChatPaneLinkPanes } from "./pane-links/previews";
|
|
26
24
|
import { attachChatCommands, cachedChatFunctions, chatFunctionsChanged } from "./pane-links/commands";
|
|
@@ -62,9 +60,10 @@ let disposeUnreadBadge: (() => void) | undefined;
|
|
|
62
60
|
export const chatModule: PluginModule = {
|
|
63
61
|
panes: [{
|
|
64
62
|
id: "chat",
|
|
63
|
+
reportFreshness: { local: true },
|
|
65
64
|
name: "Chat",
|
|
66
65
|
icon: "C",
|
|
67
|
-
component: ChatPane,
|
|
66
|
+
get component(): typeof import("./pane").ChatPane { const { ChatPane } = require("./pane"); return ChatPane; },
|
|
68
67
|
defaultPosition: "right",
|
|
69
68
|
defaultMode: "floating",
|
|
70
69
|
defaultFloatingSize: { width: 80, height: 30 },
|
|
@@ -79,12 +78,12 @@ export const chatModule: PluginModule = {
|
|
|
79
78
|
},
|
|
80
79
|
}, {
|
|
81
80
|
id: UNREAD_INBOX_PANE_ID,
|
|
82
|
-
reportFreshness: { status: "not-a-feed", basis: "chat messages and missed alerts" },
|
|
81
|
+
reportFreshness: { status: "not-a-feed", basis: "chat messages and missed alerts", local: true },
|
|
83
82
|
name: "Unread",
|
|
84
83
|
// Mentions and replies from every conversation, DMs included.
|
|
85
84
|
personalData: "messages",
|
|
86
85
|
icon: "U",
|
|
87
|
-
component: UnreadInboxPane,
|
|
86
|
+
get component(): typeof import("./unread-inbox-pane").UnreadInboxPane { const { UnreadInboxPane } = require("./unread-inbox-pane"); return UnreadInboxPane; },
|
|
88
87
|
defaultPosition: "right",
|
|
89
88
|
defaultMode: "floating",
|
|
90
89
|
defaultFloatingSize: { width: 88, height: 16 },
|
|
@@ -96,6 +95,7 @@ export const chatModule: PluginModule = {
|
|
|
96
95
|
description: "Open the floating chat window for a channel",
|
|
97
96
|
keywords: ["new", "chat", "pane", "message"],
|
|
98
97
|
shortcut: { prefix: "CHAT", argPlaceholder: "channel", argKind: "text" },
|
|
98
|
+
catalogSettings: {},
|
|
99
99
|
createInstance: async (context, options) => {
|
|
100
100
|
const rawArg = options?.arg?.trim() ?? "";
|
|
101
101
|
// The command bar's New DM keeps the open pane on its conversation.
|
|
@@ -1,6 +1,5 @@
|
|
|
1
1
|
import type { GloomPlugin, PaneTemplateCreateOptions } from "../../../types/plugin";
|
|
2
2
|
import { normalizeTrialFilters, TRIAL_REPORT_OPTIONS, ALL } from "./model";
|
|
3
|
-
import { TrialsPane } from "./pane";
|
|
4
3
|
import { CLINICAL_TRIALS_PANE_ID, CLINICAL_TRIALS_PLUGIN_ID } from "./types";
|
|
5
4
|
|
|
6
5
|
function createTrialsPaneInstance(options?: PaneTemplateCreateOptions) {
|
|
@@ -40,7 +39,7 @@ export const clinicalTrialsPlugin: GloomPlugin = {
|
|
|
40
39
|
reportOptions: TRIAL_REPORT_OPTIONS,
|
|
41
40
|
name: "Trials",
|
|
42
41
|
icon: "C",
|
|
43
|
-
component: TrialsPane,
|
|
42
|
+
get component(): typeof import("./pane").TrialsPane { const { TrialsPane } = require("./pane"); return TrialsPane; },
|
|
44
43
|
defaultPosition: "right",
|
|
45
44
|
defaultMode: "floating",
|
|
46
45
|
defaultFloatingSize: { width: 100, height: 30 },
|
|
@@ -189,7 +189,7 @@ function LogoTile({ symbol, assetCategory, size }: { symbol: string; assetCatego
|
|
|
189
189
|
return <Box alignItems="center" justifyContent="center" style={tile}>{letter}</Box>;
|
|
190
190
|
}
|
|
191
191
|
return (
|
|
192
|
-
<ImageSurface src={src} alt={symbol} objectFit="contain" alignItems="center" justifyContent="center" style={tile}>
|
|
192
|
+
<ImageSurface src={src} alt={symbol} objectFit="contain" fallbackWhileLoading alignItems="center" justifyContent="center" style={tile}>
|
|
193
193
|
{letter}
|
|
194
194
|
</ImageSurface>
|
|
195
195
|
);
|
|
@@ -2,6 +2,7 @@ import type { GloomPlugin } from "../../../types/plugin";
|
|
|
2
2
|
import { apiClient } from "../../../api-client";
|
|
3
3
|
import { createGloomberbCloudCapabilities, createGloomberbCloudProvider } from "../../../sources/gloomberb-cloud";
|
|
4
4
|
import { accountManagementModule } from "../account-management";
|
|
5
|
+
import { buildoutModule } from "../buildout";
|
|
5
6
|
import { chatModule } from "../chat";
|
|
6
7
|
import {
|
|
7
8
|
CONGRESS_TRADES_PANE_ID,
|
|
@@ -88,8 +89,10 @@ const askgModule: PluginModule = {
|
|
|
88
89
|
},
|
|
89
90
|
panes: [{
|
|
90
91
|
id: ASKG_PANE_ID,
|
|
91
|
-
reportFreshness: { status: "not-a-feed", basis: "generated answer" },
|
|
92
|
+
reportFreshness: { status: "not-a-feed", basis: "generated answer", local: true },
|
|
92
93
|
reportLockNote: askgLockNote,
|
|
94
|
+
// Without a session the wall is all there is, so `fn ASKG` prints it at once.
|
|
95
|
+
signInWall: true,
|
|
93
96
|
name: "Ask Gloom",
|
|
94
97
|
personalData: "messages",
|
|
95
98
|
icon: "K",
|
|
@@ -177,8 +180,7 @@ const congressTradesModule: PluginModule = {
|
|
|
177
180
|
}],
|
|
178
181
|
};
|
|
179
182
|
|
|
180
|
-
|
|
181
|
-
export function createGloomberbCloudPlugin(extraModules: readonly PluginModule[] = []): GloomPlugin {
|
|
183
|
+
export function createGloomberbCloudPlugin(): GloomPlugin {
|
|
182
184
|
return composeBuiltinPlugin({
|
|
183
185
|
id: "gloomberb-cloud",
|
|
184
186
|
name: "Gloom Cloud",
|
|
@@ -195,7 +197,7 @@ export function createGloomberbCloudPlugin(extraModules: readonly PluginModule[]
|
|
|
195
197
|
cloudAccountModule,
|
|
196
198
|
askgModule,
|
|
197
199
|
terminalRelayModule,
|
|
198
|
-
|
|
200
|
+
buildoutModule,
|
|
199
201
|
congressTradesModule,
|
|
200
202
|
cloudTweetsModule,
|
|
201
203
|
],
|
|
@@ -24,7 +24,7 @@ export const teamModule: PluginModule = {
|
|
|
24
24
|
capabilities: [createCloudTeamCapability(), createCloudViewsCapability()],
|
|
25
25
|
panes: [{
|
|
26
26
|
id: TEAM_PANE_ID,
|
|
27
|
-
reportFreshness: { status: "not-a-feed", basis: "account data" },
|
|
27
|
+
reportFreshness: { status: "not-a-feed", basis: "account data", local: true },
|
|
28
28
|
name: "Team",
|
|
29
29
|
icon: "T",
|
|
30
30
|
personalData: "account",
|
|
@@ -12,7 +12,7 @@ import { ThesisTickerTab } from "./ticker-tab";
|
|
|
12
12
|
export const thesisModule: PluginModule = {
|
|
13
13
|
panes: [{
|
|
14
14
|
id: THESIS_PANE_ID,
|
|
15
|
-
reportFreshness: { source: "Your theses", status: "not-a-feed", basis: "your theses" },
|
|
15
|
+
reportFreshness: { source: "Your theses", status: "not-a-feed", basis: "your theses", local: true },
|
|
16
16
|
name: "Theses",
|
|
17
17
|
personalData: "holdings",
|
|
18
18
|
icon: "Θ",
|