gloomberb 0.18.2 → 0.18.4
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +8 -8
- package/README.zh-CN.md +11 -11
- package/bin/{gloomberb → gloom} +3 -1
- package/package.json +6 -2
- package/patches/electrobun@1.18.1.patch +106 -5
- package/src/account/checkout-handoff.tsx +225 -0
- package/src/account/device-signin-dialog.tsx +2 -2
- package/src/account/device-signin.ts +2 -2
- package/src/account/upgrade-dialog.tsx +1 -1
- package/src/api-client/askg.ts +2 -2
- package/src/api-client/auth.ts +2 -2
- package/src/api-client/central-bank-rates.ts +6 -0
- package/src/api-client/collections.ts +5 -1
- package/src/api-client/cot.ts +2 -0
- package/src/api-client/crypto-etf-flows.ts +37 -0
- package/src/api-client/crypto-markets.ts +60 -0
- package/src/api-client/data.ts +99 -5
- package/src/api-client/doe.ts +15 -0
- package/src/api-client/equity-screener.ts +28 -0
- package/src/api-client/exchange-announcements.ts +38 -0
- package/src/api-client/fund-facts.ts +39 -0
- package/src/api-client/futures-curve.ts +9 -1
- package/src/api-client/hiring.ts +301 -0
- package/src/api-client/index.ts +24 -5
- package/src/api-client/market-discovery.ts +14 -0
- package/src/api-client/members.ts +6 -0
- package/src/api-client/mna.ts +6 -0
- package/src/api-client/paths.ts +18 -1
- package/src/api-client/request.ts +26 -7
- package/src/api-client/short-side-publications.ts +37 -0
- package/src/api-client/socket.ts +64 -4
- package/src/api-client/swap-curve.ts +35 -0
- package/src/api-client/telemetry.ts +17 -0
- package/src/api-client/themes.ts +7 -1
- package/src/api-client/types.ts +90 -2
- package/src/app/global-shortcuts.ts +1 -16
- package/src/app/pane-runtime/plugin-bindings.ts +9 -2
- package/src/app/runtime/desktop-deeplink.ts +5 -5
- package/src/app/runtime/plugin-bindings.ts +2 -2
- package/src/app/runtime/startup.ts +13 -0
- package/src/app/runtime/update.ts +28 -8
- package/src/app/star-prompt/status-line.tsx +2 -2
- package/src/architecture/core-builtin-allowlist.json +5 -2
- package/src/architecture/pane-tabs-allowlist.json +65 -0
- package/src/architecture/ui-literals-allowlist.json +3 -3
- package/src/architecture/ui-tokens-allowlist.json +1 -1
- package/src/brokers/broker-portfolio-sync.ts +37 -0
- package/src/brokers/directory.ts +11 -0
- package/src/brokers/logos.ts +3 -1
- package/src/brokers/signed-in/adapter.ts +304 -26
- package/src/brokers/signed-in/client.ts +14 -2
- package/src/brokers/signed-in/connect.ts +10 -2
- package/src/brokers/sync-broker-instance.ts +9 -1
- package/src/capabilities/chart-series.ts +22 -6
- package/src/cli/bank-section.ts +1 -1
- package/src/cli/base-converter.ts +23 -14
- package/src/cli/central-bank-events.ts +1 -1
- package/src/cli/command-options.ts +59 -4
- package/src/cli/commands/api.ts +9 -6
- package/src/cli/commands/broker.ts +2 -2
- package/src/cli/commands/command-utils.ts +2 -2
- package/src/cli/commands/crypto-hints.ts +7 -20
- package/src/cli/commands/fred-series.ts +4 -2
- package/src/cli/commands/keybindings.ts +2 -2
- package/src/cli/commands/market.ts +1189 -296
- package/src/cli/commands/news-hints.ts +2 -2
- package/src/cli/commands/news-search.ts +59 -6
- package/src/cli/commands/options-leaps.ts +41 -26
- package/src/cli/commands/overview.ts +121 -48
- package/src/cli/commands/plugins.ts +9 -9
- package/src/cli/commands/remote.ts +13 -10
- package/src/cli/commands/search.ts +64 -44
- package/src/cli/commands/system.ts +27 -19
- package/src/cli/commands/themes.ts +1 -1
- package/src/cli/commands/ticker.ts +272 -70
- package/src/cli/context.ts +3 -2
- package/src/cli/desktop-pane-shot-view.ts +2 -2
- package/src/cli/desktop-pane-shot.ts +1 -1
- package/src/cli/earnings-calendar.ts +4 -4
- package/src/cli/entry.ts +18 -1
- package/src/cli/errors.ts +20 -2
- package/src/cli/exit-codes.ts +1 -1
- package/src/cli/export-source.ts +10 -4
- package/src/cli/freshness.ts +2 -8
- package/src/cli/fx-forward.ts +130 -0
- package/src/cli/fx-pair.ts +10 -9
- package/src/cli/glossary.ts +64 -20
- package/src/cli/help.ts +20 -14
- package/src/cli/history-export.ts +126 -0
- package/src/cli/history-rows.ts +196 -43
- package/src/cli/index-roots.ts +5 -45
- package/src/cli/index.ts +32 -18
- package/src/cli/issuer-membership.ts +103 -0
- package/src/cli/known-gaps.ts +118 -25
- package/src/cli/listing-arg.ts +315 -43
- package/src/cli/name-entries.ts +73 -22
- package/src/cli/native-smoke.ts +2 -0
- package/src/cli/not-a-ticker.ts +19 -9
- package/src/cli/opentui-libc.ts +5 -0
- package/src/cli/options.ts +12 -0
- package/src/cli/pane-functions/capabilities.ts +77 -20
- package/src/cli/pane-functions/catalog.ts +40 -23
- package/src/cli/pane-functions/discovery.ts +1 -1
- package/src/cli/pane-functions/dom.ts +12 -8
- package/src/cli/pane-functions/financial-ratio-shot.ts +2 -2
- package/src/cli/pane-functions/freshness.ts +174 -23
- package/src/cli/pane-functions/function-help.ts +66 -27
- package/src/cli/pane-functions/headless.ts +48 -16
- package/src/cli/pane-functions/index.ts +82 -21
- package/src/cli/pane-functions/options.ts +22 -2
- package/src/cli/pane-functions/report-notices.ts +12 -4
- package/src/cli/pane-functions/report.ts +5 -5
- package/src/cli/pane-functions/resolver.ts +65 -14
- package/src/cli/pane-functions/screenshot-assessment.ts +322 -0
- package/src/cli/pane-functions/screenshot-bridge.ts +152 -0
- package/src/cli/pane-functions/screenshot-chart-evidence.ts +396 -0
- package/src/cli/pane-functions/screenshot-data-evidence.ts +383 -0
- package/src/cli/pane-functions/screenshot-evidence.ts +1 -1
- package/src/cli/pane-functions/screenshot-payload.ts +453 -0
- package/src/cli/pane-functions/screenshot-render.ts +316 -0
- package/src/cli/pane-functions/screenshot-types.ts +162 -0
- package/src/cli/pane-functions/shot-options.ts +8 -3
- package/src/cli/peso-dollar-rates.ts +79 -0
- package/src/cli/quote-answer.ts +38 -3
- package/src/cli/report-tables.ts +190 -27
- package/src/cli/restore-plugins.ts +29 -14
- package/src/cli/result.ts +122 -25
- package/src/cli/series-search.ts +5 -5
- package/src/cli/statement-filings.ts +19 -0
- package/src/cli/suffixed-listing-rows.ts +49 -0
- package/src/cli/symbol-args.ts +50 -15
- package/src/cli/symbol-cells.ts +120 -0
- package/src/cli/symbol-list.ts +226 -60
- package/src/cli/symbol-rows.ts +131 -25
- package/src/cli/ticker-resolution.ts +108 -11
- package/src/cli/treasury-yields.ts +5 -5
- package/src/cli/types.ts +2 -0
- package/src/cli/uncovered-instrument.ts +3 -3
- package/src/cli/unknown-command.ts +6 -6
- package/src/components/chart/composite/chart-layout.ts +131 -0
- package/src/components/chart/composite/composite-chart.tsx +387 -21
- package/src/components/chart/composite/drawing-store.ts +26 -6
- package/src/components/chart/composite/interactions.ts +9 -3
- package/src/components/chart/composite/legend.tsx +75 -3
- package/src/components/chart/composite/levels.ts +5 -0
- package/src/components/chart/composite/panel-gestures.ts +41 -0
- package/src/components/chart/composite/panel-labels.ts +2 -1
- package/src/components/chart/composite/panel-surface.tsx +316 -11
- package/src/components/chart/composite/price-axis-labels.tsx +27 -3
- package/src/components/chart/composite/rasterizer.ts +44 -19
- package/src/components/chart/composite/scene.ts +16 -4
- package/src/components/chart/composite/text-renderer.ts +48 -21
- package/src/components/chart/composite/toolbar.tsx +52 -5
- package/src/components/chart/composite/types.ts +19 -0
- package/src/components/chart/composite/use-composite-chart-keyboard.ts +120 -13
- package/src/components/chart/composite/use-composite-value-scales.ts +44 -0
- package/src/components/chart/composite/use-composite-viewport.ts +12 -3
- package/src/components/chart/composite/value-scale.ts +149 -0
- package/src/components/chart/composite/volume-profile-paint.ts +6 -3
- package/src/components/chart/core/pointer.ts +2 -0
- package/src/components/chart-table/index.ts +2 -0
- package/src/components/chart-table/read.tsx +74 -0
- package/src/components/command-bar/commands/collection-list.ts +41 -19
- package/src/components/command-bar/commands/collection.ts +9 -3
- package/src/components/command-bar/commands/direct/index.ts +1 -1
- package/src/components/command-bar/commands/direct/runtime.ts +3 -2
- package/src/components/command-bar/pane-templates/items.ts +59 -6
- package/src/components/command-bar/pane-templates/workflow.ts +10 -1
- package/src/components/command-bar/routes/root/command-items.ts +32 -6
- package/src/components/command-bar/routes/root/plugin-install.ts +1 -1
- package/src/components/command-bar/routes/root/provider-search.ts +42 -11
- package/src/components/command-bar/routes/root/results.ts +18 -4
- package/src/components/command-bar/routes/root/runtime.ts +15 -3
- package/src/components/command-bar/routes/root/search-providers.ts +25 -2
- package/src/components/command-bar/routes/root/selection.ts +6 -1
- package/src/components/command-bar/routes/root/shortcut-feedback.ts +4 -1
- package/src/components/command-bar/routes/root/shortcuts.ts +30 -3
- package/src/components/command-bar/routes/ticker-search/results.ts +73 -4
- package/src/components/command-bar/selection-runtime.ts +50 -10
- package/src/components/command-bar/surface/index.tsx +24 -2
- package/src/components/command-bar/view-model.ts +7 -0
- package/src/components/command-bar/workflow/broker.ts +2 -2
- package/src/components/command-bar/workflow/collection-actions.ts +46 -7
- package/src/components/command-bar/workflow/collection-ticker.ts +32 -4
- package/src/components/command-bar/workflow/fields.ts +8 -2
- package/src/components/command-bar/workflow/ops.ts +18 -4
- package/src/components/command-bar/workflow/portfolio-position.ts +53 -4
- package/src/components/command-bar/workflow/submit.ts +3 -2
- package/src/components/command-bar/workflow/tickers.ts +5 -1
- package/src/components/company-logo.tsx +39 -0
- package/src/components/data-table/sections.ts +4 -2
- package/src/components/data-table/view.tsx +23 -3
- package/src/components/form-modal/confirm.tsx +2 -1
- package/src/components/form-modal/request.ts +5 -0
- package/src/components/form-modal/routes.ts +4 -1
- package/src/components/index.ts +13 -6
- package/src/components/layout/detached-pane-shell.tsx +1 -0
- package/src/components/layout/floating-pane.tsx +1 -0
- package/src/components/layout/header.tsx +234 -60
- package/src/components/layout/market-summary.ts +9 -6
- package/src/components/layout/pane/capture-status.ts +1 -1
- package/src/components/layout/pane/footer/model.ts +11 -5
- package/src/components/layout/pane/header.tsx +10 -3
- package/src/components/layout/pane/index.tsx +1 -0
- package/src/components/layout/pane/pane-tabs.tsx +9 -1
- package/src/components/layout/shell/chrome.ts +19 -6
- package/src/components/layout/shell/index.tsx +2 -1
- package/src/components/layout/shell/pane/layers.tsx +19 -1
- package/src/components/layout/status-bar.tsx +2 -2
- package/src/components/market-board/index.tsx +11 -3
- package/src/components/onboarding/onboarding-wizard.tsx +1 -0
- package/src/components/onboarding/portfolio-step/broker-setup-panel.tsx +2 -2
- package/src/components/onboarding/wizard-broker-sync.ts +4 -1
- package/src/components/pane-settings-dialog/desktop.tsx +20 -7
- package/src/components/pane-settings-dialog/tui.tsx +17 -9
- package/src/components/pane-settings-dialog/value.ts +8 -1
- package/src/components/pane-settings-dialog.tsx +44 -13
- package/src/components/sign-in-code-panel.tsx +27 -19
- package/src/components/ui/column-grid.tsx +48 -4
- package/src/components/ui/country-flag-art.tsx +180 -0
- package/src/components/ui/country-flag.tsx +118 -12
- package/src/components/ui/data-table/opentui/index.tsx +61 -2
- package/src/components/ui/data-table/opentui/model.ts +109 -2
- package/src/components/ui/data-table/types.ts +1 -1
- package/src/components/ui/display.tsx +5 -1
- package/src/components/ui/index.ts +3 -1
- package/src/components/ui/logo-mark.tsx +11 -2
- package/src/components/ui/query-bar.tsx +1 -1
- package/src/components/ui/row-notes.ts +79 -0
- package/src/components/ui/stat-grid.tsx +28 -3
- package/src/components/ui/status.tsx +3 -1
- package/src/core/app-services.ts +4 -0
- package/src/core/state/app/layout.ts +4 -4
- package/src/data/cached-query.ts +8 -1
- package/src/data/config/chart-settings.ts +3 -3
- package/src/data/config/home.ts +10 -2
- package/src/data/config/layout.ts +4 -1
- package/src/data/config/store/node.ts +4 -0
- package/src/data/config/store/normalize.ts +13 -3
- package/src/data/config/store/portfolio-as-of-column.ts +2 -2
- package/src/data/json-storage.ts +2 -0
- package/src/data/saved-copies.ts +84 -0
- package/src/docs/snapshot.json +65 -32
- package/src/i18n/es.ts +51 -12
- package/src/i18n/ja.ts +51 -12
- package/src/i18n/ko.ts +51 -12
- package/src/i18n/zh-cn.ts +51 -12
- package/src/i18n/zh-tw.ts +51 -12
- package/src/layout/desks.ts +1 -1
- package/src/layout/launch-layout.ts +1 -1
- package/src/layout/pane-manager/floating-actions.ts +5 -3
- package/src/layout/pane-manager/floating.ts +43 -1
- package/src/layout/pane-manager/index.ts +2 -0
- package/src/layout/selected-ticker.ts +74 -0
- package/src/market-data/depositary-pair.ts +251 -0
- package/src/market-data/futures-board.ts +1 -1
- package/src/market-data/futures-contract.ts +124 -40
- package/src/market-data/fx-closes.ts +17 -2
- package/src/market-data/hooks.tsx +19 -11
- package/src/market-data/market/change-basis.ts +49 -7
- package/src/market-data/market/freshness.ts +34 -5
- package/src/market-data/market/period-return.ts +163 -0
- package/src/market-data/market/trading-sessions.ts +13 -0
- package/src/market-data/market/year-to-date.ts +8 -13
- package/src/market-data/performance.ts +20 -14
- package/src/market-data/perpetual-premium.ts +32 -0
- package/src/market-data/published-apac-sessions.ts +2 -1
- package/src/market-data/published-futures-sessions.ts +69 -0
- package/src/market-data/quotes/contributions.ts +5 -1
- package/src/market-data/quotes/freshness.ts +42 -0
- package/src/market-data/quotes/intraday-bar.ts +37 -0
- package/src/market-data/quotes/regular-session-valuation.ts +13 -8
- package/src/market-data/quotes/resolution.ts +4 -2
- package/src/market-data/tax-equivalent.ts +1 -1
- package/src/market-data/ticker-price-returns.ts +3 -1
- package/src/news/aggregator.ts +5 -1
- package/src/news/news-model.ts +4 -0
- package/src/news/types.ts +11 -0
- package/src/notifications/app-notifier.ts +1 -1
- package/src/plugins/auto-update.ts +2 -2
- package/src/plugins/builtin/account-management/index.tsx +1 -0
- package/src/plugins/builtin/account-management/pane.tsx +9 -8
- package/src/plugins/builtin/alerts/alert-engine.ts +30 -18
- package/src/plugins/builtin/alerts/calendar-events.ts +378 -0
- package/src/plugins/builtin/alerts/cli.ts +485 -76
- package/src/plugins/builtin/alerts/command.ts +5 -10
- package/src/plugins/builtin/alerts/event-rows.ts +9 -5
- package/src/plugins/builtin/alerts/events-pane.tsx +71 -56
- package/src/plugins/builtin/alerts/events.ts +108 -5
- package/src/plugins/builtin/alerts/fired-log.ts +78 -0
- package/src/plugins/builtin/alerts/format.ts +2 -1
- package/src/plugins/builtin/alerts/headless.ts +100 -39
- package/src/plugins/builtin/alerts/history-pane.tsx +105 -62
- package/src/plugins/builtin/alerts/history-rows.ts +89 -0
- package/src/plugins/builtin/alerts/index.tsx +45 -18
- package/src/plugins/builtin/alerts/iv-level.ts +365 -0
- package/src/plugins/builtin/alerts/levels.ts +3 -3
- package/src/plugins/builtin/alerts/pane.tsx +97 -29
- package/src/plugins/builtin/alerts/price.ts +35 -0
- package/src/plugins/builtin/alerts/quotes.ts +24 -0
- package/src/plugins/builtin/alerts/research-builder.ts +84 -11
- package/src/plugins/builtin/alerts/research-rules.ts +77 -3
- package/src/plugins/builtin/alerts/scheduled-check.ts +206 -32
- package/src/plugins/builtin/alerts/scheduled-sources.ts +26 -3
- package/src/plugins/builtin/alerts/scheduled.ts +188 -29
- package/src/plugins/builtin/alerts/storage.ts +13 -10
- package/src/plugins/builtin/alerts/targets.ts +12 -3
- package/src/plugins/builtin/analytics/index.tsx +8 -2
- package/src/plugins/builtin/analytics/metrics.ts +1 -1
- package/src/plugins/builtin/analytics/risk-book.ts +215 -0
- package/src/plugins/builtin/analytics/risk-client.ts +13 -6
- package/src/plugins/builtin/analytics/risk-headless.ts +55 -21
- package/src/plugins/builtin/analytics/risk-math.ts +6 -3
- package/src/plugins/builtin/analytics/risk-model.ts +297 -104
- package/src/plugins/builtin/analytics/risk-options.ts +17 -2
- package/src/plugins/builtin/analytics/risk-pane.tsx +107 -43
- package/src/plugins/builtin/attention/pane.tsx +22 -16
- package/src/plugins/builtin/awards/headless.ts +7 -3
- package/src/plugins/builtin/awards/model.ts +18 -0
- package/src/plugins/builtin/awards/pane.tsx +12 -9
- package/src/plugins/builtin/backtest/export.ts +1 -1
- package/src/plugins/builtin/backtest/headless.ts +3 -3
- package/src/plugins/builtin/backtest/rules.ts +41 -5
- package/src/plugins/builtin/broker-manager/add-flow.tsx +12 -7
- package/src/plugins/builtin/broker-manager/detail.tsx +47 -19
- package/src/plugins/builtin/broker-manager/footer.ts +27 -11
- package/src/plugins/builtin/broker-manager/index.tsx +21 -12
- package/src/plugins/builtin/broker-manager/keyboard.ts +1 -1
- package/src/plugins/builtin/broker-manager/model.ts +12 -2
- package/src/plugins/builtin/broker-manager/pane-actions.tsx +183 -57
- package/src/plugins/builtin/broker-manager/table.ts +28 -12
- package/src/plugins/builtin/broker-trading/account-picker.tsx +2 -1
- package/src/plugins/builtin/broker-trading/chart-levels.ts +82 -13
- package/src/plugins/builtin/broker-trading/controller.ts +45 -13
- package/src/plugins/builtin/broker-trading/dock.tsx +24 -4
- package/src/plugins/builtin/broker-trading/headless.ts +2 -1
- package/src/plugins/builtin/broker-trading/index.tsx +7 -1
- package/src/plugins/builtin/broker-trading/linked-orders.ts +148 -0
- package/src/plugins/builtin/broker-trading/order-feed.ts +75 -7
- package/src/plugins/builtin/broker-trading/orders.tsx +109 -31
- package/src/plugins/builtin/broker-trading/overview-orders.tsx +9 -3
- package/src/plugins/builtin/broker-trading/pane-model.ts +30 -2
- package/src/plugins/builtin/broker-trading/pane.tsx +115 -26
- package/src/plugins/builtin/broker-trading/ticket-parts.tsx +36 -7
- package/src/plugins/builtin/broker-trading/ticket.tsx +122 -36
- package/src/plugins/builtin/buildout/cells.tsx +4 -0
- package/src/plugins/builtin/buildout/detail/index.tsx +5 -1
- package/src/plugins/builtin/buildout/detail/ui.tsx +7 -4
- package/src/plugins/builtin/buildout/pane/index.tsx +34 -18
- package/src/plugins/builtin/buildout/pane/status.tsx +0 -4
- package/src/plugins/builtin/builtin-plugin-meta.ts +1 -1
- package/src/plugins/builtin/catalysts/client.ts +2 -2
- package/src/plugins/builtin/catalysts/detail.tsx +3 -2
- package/src/plugins/builtin/catalysts/index.tsx +1 -1
- package/src/plugins/builtin/catalysts/model.ts +49 -4
- package/src/plugins/builtin/catalysts/pane.tsx +9 -11
- package/src/plugins/builtin/central-bank-rates/client.ts +5 -0
- package/src/plugins/builtin/central-bank-rates/headless.ts +36 -10
- package/src/plugins/builtin/central-bank-rates/model.ts +33 -8
- package/src/plugins/builtin/changelog/index.tsx +1 -0
- package/src/plugins/builtin/chart-composer/catalog-inventory.ts +1 -0
- package/src/plugins/builtin/chart-composer/chart-spec-edit.ts +2 -1
- package/src/plugins/builtin/chart-composer/chart-spec.ts +7 -0
- package/src/plugins/builtin/chart-composer/cli-options.ts +2 -5
- package/src/plugins/builtin/chart-composer/data-catalog-pane.tsx +2 -1
- package/src/plugins/builtin/chart-composer/editor/controller.ts +2 -0
- package/src/plugins/builtin/chart-composer/editor.tsx +4 -1
- package/src/plugins/builtin/chart-composer/headless-schema.ts +28 -26
- package/src/plugins/builtin/chart-composer/headless.ts +253 -35
- package/src/plugins/builtin/chart-composer/index.tsx +12 -2
- package/src/plugins/builtin/chart-composer/leverage-overlay.ts +142 -0
- package/src/plugins/builtin/chart-composer/pane.tsx +128 -28
- package/src/plugins/builtin/chart-composer/series-catalog.ts +1 -0
- package/src/plugins/builtin/chart-composer/series-expression.ts +65 -6
- package/src/plugins/builtin/chart-composer/session-history.ts +15 -21
- package/src/plugins/builtin/chart-composer/session-range.ts +4 -2
- package/src/plugins/builtin/chart-composer/settings.ts +31 -19
- package/src/plugins/builtin/chart-composer/use-series-catalog.ts +5 -6
- package/src/plugins/builtin/chart-composer/viewport-labels.ts +18 -8
- package/src/plugins/builtin/chat/attachments/model.ts +3 -1
- package/src/plugins/builtin/chat/content/index.tsx +1 -1
- package/src/plugins/builtin/chat/pane-links/open.ts +1 -1
- package/src/plugins/builtin/chat/people.ts +1 -1
- package/src/plugins/builtin/clinical-trials/client.ts +5 -2
- package/src/plugins/builtin/clinical-trials/model.ts +13 -4
- package/src/plugins/builtin/clinical-trials/pane.tsx +32 -12
- package/src/plugins/builtin/clinical-trials/ticker-sponsor.ts +17 -0
- package/src/plugins/builtin/cloud/askg/controller.ts +1 -1
- package/src/plugins/builtin/cloud/askg/lock-note.ts +1 -1
- package/src/plugins/builtin/cloud/askg/tool-display.ts +1 -1
- package/src/plugins/builtin/cloud/auth-commands.ts +3 -3
- package/src/plugins/builtin/cloud/team/pane-sections.tsx +105 -47
- package/src/plugins/builtin/cloud/team/pane-ui.tsx +42 -4
- package/src/plugins/builtin/cloud/team/pane.tsx +204 -64
- package/src/plugins/builtin/cloud/thesis/store.ts +45 -22
- package/src/plugins/builtin/cloud-tweets/registration.ts +1 -0
- package/src/plugins/builtin/commodities-energy/index.tsx +29 -2
- package/src/plugins/builtin/commodities-energy/view-state.ts +2 -0
- package/src/plugins/builtin/commodity-balances/pane.tsx +14 -8
- package/src/plugins/builtin/company-attention/app-rank.tsx +11 -10
- package/src/plugins/builtin/company-attention/building-model.ts +222 -0
- package/src/plugins/builtin/company-attention/building.tsx +172 -0
- package/src/plugins/builtin/company-attention/client.ts +117 -1
- package/src/plugins/builtin/company-attention/evidence.ts +16 -3
- package/src/plugins/builtin/company-attention/headless.ts +101 -5
- package/src/plugins/builtin/company-attention/index.tsx +6 -3
- package/src/plugins/builtin/company-attention/model.ts +33 -7
- package/src/plugins/builtin/company-attention/moves-model.ts +253 -0
- package/src/plugins/builtin/company-attention/moves.tsx +159 -0
- package/src/plugins/builtin/company-attention/pane.tsx +89 -31
- package/src/plugins/builtin/company-attention/signals-model.ts +229 -0
- package/src/plugins/builtin/company-attention/signals.tsx +160 -0
- package/src/plugins/builtin/company-kpis/headless.ts +3 -2
- package/src/plugins/builtin/company-kpis/model.ts +2 -2
- package/src/plugins/builtin/company-kpis/pane.tsx +5 -4
- package/src/plugins/builtin/composite-plugins.ts +2 -1
- package/src/plugins/builtin/congress-trades/headless.ts +1 -1
- package/src/plugins/builtin/connections/index.ts +1 -0
- package/src/plugins/builtin/correlation/headless-schema.ts +3 -2
- package/src/plugins/builtin/correlation/headless.ts +7 -4
- package/src/plugins/builtin/correlation/relationship/model.ts +1 -0
- package/src/plugins/builtin/correlation/settings.ts +1 -0
- package/src/plugins/builtin/cot/headless.ts +28 -6
- package/src/plugins/builtin/cot/model.ts +12 -0
- package/src/plugins/builtin/cot/pane.tsx +7 -5
- package/src/plugins/builtin/cpi/headless.ts +5 -1
- package/src/plugins/builtin/cpi/pane.tsx +11 -9
- package/src/plugins/builtin/credit-boards/model.ts +2 -0
- package/src/plugins/builtin/credit-documents/headless.ts +1 -1
- package/src/plugins/builtin/credit-documents/pane.tsx +8 -7
- package/src/plugins/builtin/crypto-board/client.ts +86 -0
- package/src/plugins/builtin/crypto-board/defi-view.tsx +218 -0
- package/src/plugins/builtin/crypto-board/defi.ts +239 -0
- package/src/plugins/builtin/crypto-board/headless.ts +117 -6
- package/src/plugins/builtin/crypto-board/index.tsx +8 -3
- package/src/plugins/builtin/crypto-board/model.ts +40 -8
- package/src/plugins/builtin/crypto-board/pane.tsx +55 -21
- package/src/plugins/builtin/crypto-board/series.ts +19 -1
- package/src/plugins/builtin/crypto-etf-flows/client.ts +60 -0
- package/src/plugins/builtin/crypto-etf-flows/headless.ts +132 -0
- package/src/plugins/builtin/crypto-etf-flows/index.tsx +44 -0
- package/src/plugins/builtin/crypto-etf-flows/model.ts +121 -0
- package/src/plugins/builtin/crypto-etf-flows/pane.tsx +193 -0
- package/src/plugins/builtin/debt-maturities/pane.tsx +4 -3
- package/src/plugins/builtin/debug/index.tsx +1 -0
- package/src/plugins/builtin/dividend-yield/index.tsx +1 -1
- package/src/plugins/builtin/docs/index.tsx +1 -1
- package/src/plugins/builtin/docs/pane.tsx +2 -2
- package/src/plugins/builtin/docs/targets.ts +1 -1
- package/src/plugins/builtin/doe/client.ts +5 -1
- package/src/plugins/builtin/doe/headless.ts +12 -6
- package/src/plugins/builtin/doe/model.ts +43 -6
- package/src/plugins/builtin/doe/pane.tsx +19 -12
- package/src/plugins/builtin/earnings/board-model.ts +13 -6
- package/src/plugins/builtin/earnings/board-table.ts +4 -1
- package/src/plugins/builtin/earnings/board.tsx +253 -50
- package/src/plugins/builtin/earnings/calendar-model.ts +188 -0
- package/src/plugins/builtin/earnings/calendar.tsx +338 -0
- package/src/plugins/builtin/earnings/client.ts +4 -3
- package/src/plugins/builtin/earnings/headless.ts +53 -15
- package/src/plugins/builtin/earnings/history-model.ts +53 -36
- package/src/plugins/builtin/earnings/index.tsx +15 -22
- package/src/plugins/builtin/earnings/model.ts +17 -12
- package/src/plugins/builtin/earnings/scope.ts +89 -0
- package/src/plugins/builtin/earnings-calls/calendar.tsx +310 -0
- package/src/plugins/builtin/earnings-calls/data.ts +146 -2
- package/src/plugins/builtin/earnings-calls/headless.ts +151 -9
- package/src/plugins/builtin/earnings-calls/index.tsx +3 -3
- package/src/plugins/builtin/earnings-calls/lock-note.ts +1 -1
- package/src/plugins/builtin/earnings-calls/pane.tsx +149 -31
- package/src/plugins/builtin/earnings-calls/upcoming.ts +195 -0
- package/src/plugins/builtin/earnings-ripple/pane.tsx +10 -5
- package/src/plugins/builtin/econ/calendar-model.ts +132 -20
- package/src/plugins/builtin/econ/detail-view.tsx +48 -10
- package/src/plugins/builtin/econ/fred-catalog.ts +23 -6
- package/src/plugins/builtin/econ/fred-series-map.ts +4 -0
- package/src/plugins/builtin/econ/index.tsx +112 -25
- package/src/plugins/builtin/econ/print-watch.ts +2 -1
- package/src/plugins/builtin/econ/types.ts +32 -1
- package/src/plugins/builtin/econ-statistics/client.ts +16 -3
- package/src/plugins/builtin/econ-statistics/defs.ts +4 -0
- package/src/plugins/builtin/econ-statistics/detail.tsx +2 -2
- package/src/plugins/builtin/econ-statistics/headless.ts +13 -2
- package/src/plugins/builtin/econ-statistics/index.tsx +3 -3
- package/src/plugins/builtin/econ-statistics/pane.tsx +2 -1
- package/src/plugins/builtin/econ-statistics/stats.ts +103 -0
- package/src/plugins/builtin/econ-statistics/view.ts +16 -1
- package/src/plugins/builtin/equity-screener/client.ts +21 -3
- package/src/plugins/builtin/equity-screener/headless.ts +77 -5
- package/src/plugins/builtin/equity-screener/live.ts +1 -1
- package/src/plugins/builtin/equity-screener/model.ts +34 -0
- package/src/plugins/builtin/equity-screener/pane.tsx +148 -106
- package/src/plugins/builtin/equity-screener/screen-check.ts +90 -0
- package/src/plugins/builtin/equity-screener/ticker-check.tsx +148 -0
- package/src/plugins/builtin/estimate-revisions/headless.ts +3 -1
- package/src/plugins/builtin/estimate-revisions/lock-note.ts +3 -3
- package/src/plugins/builtin/estimate-revisions/model.ts +8 -10
- package/src/plugins/builtin/exposure/headless.ts +51 -6
- package/src/plugins/builtin/exposure/index.tsx +28 -2
- package/src/plugins/builtin/exposure/model.ts +7 -0
- package/src/plugins/builtin/exposure/pane.tsx +16 -10
- package/src/plugins/builtin/fear-greed/index.tsx +1 -1
- package/src/plugins/builtin/filing-events/index.tsx +1 -1
- package/src/plugins/builtin/futures/model.ts +10 -9
- package/src/plugins/builtin/futures/returns.ts +8 -36
- package/src/plugins/builtin/futures/table.tsx +1 -1
- package/src/plugins/builtin/futures-curve/client.ts +40 -9
- package/src/plugins/builtin/futures-curve/headless.ts +39 -17
- package/src/plugins/builtin/futures-curve/model.ts +258 -69
- package/src/plugins/builtin/futures-curve/pane.tsx +46 -17
- package/src/plugins/builtin/fx-matrix/client.ts +15 -8
- package/src/plugins/builtin/fx-matrix/headless.ts +32 -14
- package/src/plugins/builtin/fx-matrix/index.tsx +13 -11
- package/src/plugins/builtin/fx-matrix/live-legs.ts +22 -0
- package/src/plugins/builtin/fx-matrix/settings.ts +2 -1
- package/src/plugins/builtin/gpu/board.tsx +4 -1
- package/src/plugins/builtin/gpu/changes.tsx +10 -10
- package/src/plugins/builtin/gpu/equities.tsx +4 -1
- package/src/plugins/builtin/gpu/headless.ts +9 -4
- package/src/plugins/builtin/gpu/history.tsx +4 -2
- package/src/plugins/builtin/gpu/pane.tsx +5 -3
- package/src/plugins/builtin/help/index.tsx +13 -3
- package/src/plugins/builtin/holders/beneficial-model.ts +8 -11
- package/src/plugins/builtin/holders/beneficial-report.ts +6 -5
- package/src/plugins/builtin/holders/beneficial-view.tsx +7 -3
- package/src/plugins/builtin/holders/client.ts +15 -2
- package/src/plugins/builtin/holders/format.ts +28 -17
- package/src/plugins/builtin/holders/headless.ts +48 -8
- package/src/plugins/builtin/holders/index-holders.ts +264 -0
- package/src/plugins/builtin/holders/pane.tsx +79 -15
- package/src/plugins/builtin/holders/report-rows.ts +35 -7
- package/src/plugins/builtin/holders/table-model.ts +2 -1
- package/src/plugins/builtin/holders/thirteenf-match.ts +3 -1
- package/src/plugins/builtin/holders/treemap.tsx +2 -2
- package/src/plugins/builtin/insider/base-values.ts +11 -7
- package/src/plugins/builtin/insider/client.ts +3 -0
- package/src/plugins/builtin/insider/headless.ts +20 -7
- package/src/plugins/builtin/insider/index.tsx +17 -8
- package/src/plugins/builtin/insider/issuer.ts +34 -4
- package/src/plugins/builtin/insider/signals-client.ts +3 -3
- package/src/plugins/builtin/insider/signals.tsx +1 -1
- package/src/plugins/builtin/insider/table-model.ts +35 -13
- package/src/plugins/builtin/insider/table.tsx +5 -2
- package/src/plugins/builtin/ipo-calendar/pane.tsx +7 -4
- package/src/plugins/builtin/iv-history/client.ts +20 -0
- package/src/plugins/builtin/iv-history/events.ts +145 -0
- package/src/plugins/builtin/iv-history/format.ts +3 -0
- package/src/plugins/builtin/iv-history/headless.ts +91 -7
- package/src/plugins/builtin/iv-history/index.tsx +1 -1
- package/src/plugins/builtin/iv-history/model.ts +13 -4
- package/src/plugins/builtin/iv-history/series.ts +3 -1
- package/src/plugins/builtin/jobs/lock-note.ts +1 -1
- package/src/plugins/builtin/jobs/model.ts +4 -15
- package/src/plugins/builtin/jobs/pane.tsx +7 -5
- package/src/plugins/builtin/jobs/share-bars.tsx +11 -5
- package/src/plugins/builtin/jodi/pane.tsx +14 -8
- package/src/plugins/builtin/layout-manager/index.tsx +1 -0
- package/src/plugins/builtin/macro-day/headless.ts +20 -7
- package/src/plugins/builtin/macro-day/index.tsx +3 -2
- package/src/plugins/builtin/macro-day/model.ts +29 -8
- package/src/plugins/builtin/macro-day/pane.tsx +46 -10
- package/src/plugins/builtin/macro-day/releases.ts +55 -13
- package/src/plugins/builtin/market-heatmap/data.ts +9 -2
- package/src/plugins/builtin/market-heatmap/evidence.ts +1 -1
- package/src/plugins/builtin/market-heatmap/headless.ts +9 -6
- package/src/plugins/builtin/market-heatmap/index.tsx +3 -3
- package/src/plugins/builtin/market-heatmap/model.ts +10 -7
- package/src/plugins/builtin/market-movers/client.ts +36 -21
- package/src/plugins/builtin/market-movers/headless.ts +8 -2
- package/src/plugins/builtin/market-movers/index.tsx +16 -10
- package/src/plugins/builtin/market-movers/screener.ts +33 -11
- package/src/plugins/builtin/market-movers/session-body.tsx +4 -2
- package/src/plugins/builtin/market-movers/session-table.ts +4 -2
- package/src/plugins/builtin/market-movers/table.ts +4 -1
- package/src/plugins/builtin/market-valuation/headless.ts +2 -0
- package/src/plugins/builtin/market-valuation/view.ts +5 -0
- package/src/plugins/builtin/members/headless.ts +6 -5
- package/src/plugins/builtin/members/pane.tsx +11 -4
- package/src/plugins/builtin/mna/client.ts +1 -0
- package/src/plugins/builtin/mna/detail.tsx +20 -32
- package/src/plugins/builtin/mna/distress/detail.tsx +16 -4
- package/src/plugins/builtin/mna/distress/model.ts +3 -2
- package/src/plugins/builtin/mna/distress/pane.tsx +7 -4
- package/src/plugins/builtin/mna/headless.ts +6 -13
- package/src/plugins/builtin/mna/model.ts +93 -15
- package/src/plugins/builtin/mna/pane.tsx +5 -4
- package/src/plugins/builtin/news/headless.ts +12 -6
- package/src/plugins/builtin/news/index.tsx +10 -1
- package/src/plugins/builtin/news/wire/index.tsx +3 -2
- package/src/plugins/builtin/news/wire/news/command-bar-search.ts +26 -10
- package/src/plugins/builtin/news/wire/news/query-presets.ts +6 -2
- package/src/plugins/builtin/news/wire/rss/cli.ts +3 -3
- package/src/plugins/builtin/notes/cli.ts +50 -15
- package/src/plugins/builtin/notes/export.ts +17 -6
- package/src/plugins/builtin/notes/files.ts +16 -5
- package/src/plugins/builtin/openfda/pane.tsx +1 -1
- package/src/plugins/builtin/options/carry.ts +2 -2
- package/src/plugins/builtin/options/enrichment-model.ts +10 -9
- package/src/plugins/builtin/options/index.tsx +1 -1
- package/src/plugins/builtin/options/model-spot.ts +70 -4
- package/src/plugins/builtin/options/view.tsx +51 -23
- package/src/plugins/builtin/options-calculator/headless.ts +46 -7
- package/src/plugins/builtin/options-calculator/pane.tsx +3 -2
- package/src/plugins/builtin/options-positioning/headless.ts +11 -3
- package/src/plugins/builtin/options-positioning/model.ts +24 -0
- package/src/plugins/builtin/options-positioning/pane.tsx +10 -12
- package/src/plugins/builtin/options-scenario/client.ts +142 -29
- package/src/plugins/builtin/options-scenario/collar.ts +8 -6
- package/src/plugins/builtin/options-scenario/csp-screen-headless.ts +127 -0
- package/src/plugins/builtin/options-scenario/csp-screen-pane.tsx +165 -0
- package/src/plugins/builtin/options-scenario/csp-screen.ts +258 -0
- package/src/plugins/builtin/options-scenario/csp.ts +101 -21
- package/src/plugins/builtin/options-scenario/headless.ts +49 -21
- package/src/plugins/builtin/options-scenario/hedge.ts +20 -14
- package/src/plugins/builtin/options-scenario/index.tsx +28 -3
- package/src/plugins/builtin/options-scenario/model.ts +13 -0
- package/src/plugins/builtin/options-scenario/pane.tsx +22 -10
- package/src/plugins/builtin/perps/equity-row.tsx +11 -3
- package/src/plugins/builtin/perps/freshness.ts +8 -5
- package/src/plugins/builtin/perps/headless.ts +3 -1
- package/src/plugins/builtin/perps/list-perpetuals.ts +25 -4
- package/src/plugins/builtin/perps/live-rows.ts +161 -0
- package/src/plugins/builtin/perps/markets-section.tsx +154 -0
- package/src/plugins/builtin/perps/pane.tsx +36 -17
- package/src/plugins/builtin/perps/venue-markets.ts +96 -0
- package/src/plugins/builtin/plugin-marketplace/index.tsx +2 -1
- package/src/plugins/builtin/plugin-marketplace/pane.tsx +145 -60
- package/src/plugins/builtin/portfolio-list/cli/bulk-symbols.ts +78 -27
- package/src/plugins/builtin/portfolio-list/cli/portfolio-command.ts +158 -141
- package/src/plugins/builtin/portfolio-list/cli/render.ts +49 -20
- package/src/plugins/builtin/portfolio-list/cli/shared.ts +3 -3
- package/src/plugins/builtin/portfolio-list/cli/watchlist-command.ts +29 -24
- package/src/plugins/builtin/portfolio-list/headless.ts +6 -3
- package/src/plugins/builtin/portfolio-list/income.ts +13 -2
- package/src/plugins/builtin/portfolio-list/index.tsx +9 -2
- package/src/plugins/builtin/portfolio-list/pane/index.tsx +21 -8
- package/src/plugins/builtin/portfolio-list/pane/purchase-date-fx.ts +46 -0
- package/src/plugins/builtin/portfolio-list/summary/live-accounts.ts +16 -9
- package/src/plugins/builtin/portfolio-list/summary/totals.ts +2 -15
- package/src/plugins/builtin/power/client.ts +6 -3
- package/src/plugins/builtin/power/evidence.ts +22 -7
- package/src/plugins/builtin/power/gas.tsx +5 -1
- package/src/plugins/builtin/power/pane.tsx +44 -32
- package/src/plugins/builtin/power/prices.tsx +10 -3
- package/src/plugins/builtin/research/analyst-headless.ts +25 -8
- package/src/plugins/builtin/research/analyst-model.ts +68 -3
- package/src/plugins/builtin/research/corporate-actions-pane.tsx +63 -14
- package/src/plugins/builtin/research/event-model.ts +3 -1
- package/src/plugins/builtin/research/event-sources.ts +12 -4
- package/src/plugins/builtin/research/index.tsx +2 -1
- package/src/plugins/builtin/research/relative-valuation-basis.ts +58 -0
- package/src/plugins/builtin/research/relative-valuation-columns.ts +31 -2
- package/src/plugins/builtin/research/relative-valuation-currency.ts +12 -5
- package/src/plugins/builtin/research/relative-valuation-headless.ts +84 -26
- package/src/plugins/builtin/research/relative-valuation-model.ts +88 -19
- package/src/plugins/builtin/research/relative-valuation-pane.tsx +76 -9
- package/src/plugins/builtin/research/relative-valuation-peers.ts +1 -1
- package/src/plugins/builtin/reverse-dcf/client.ts +2 -1
- package/src/plugins/builtin/reverse-dcf/model.ts +10 -5
- package/src/plugins/builtin/risk-factors/index.tsx +2 -2
- package/src/plugins/builtin/scanner/lock-note.ts +1 -1
- package/src/plugins/builtin/seasonality/client.ts +2 -1
- package/src/plugins/builtin/sec/forms.ts +13 -0
- package/src/plugins/builtin/sec/fund-abroad.ts +32 -0
- package/src/plugins/builtin/sec/fund-facts.ts +68 -8
- package/src/plugins/builtin/sec/headless.ts +85 -8
- package/src/plugins/builtin/sec/index.tsx +58 -12
- package/src/plugins/builtin/sectors/client.ts +6 -4
- package/src/plugins/builtin/sectors/sector-model.ts +11 -15
- package/src/plugins/builtin/series-inventory.ts +2 -0
- package/src/plugins/builtin/shared/broker-reconnect.ts +107 -22
- package/src/plugins/builtin/shared/cloud-resource.ts +15 -2
- package/src/plugins/builtin/shared/cloud-upgrade.ts +34 -6
- package/src/plugins/builtin/shared/earnings-calendar.ts +375 -0
- package/src/plugins/builtin/{earnings/estimate-basis.ts → shared/earnings-estimate-basis.ts} +1 -1
- package/src/plugins/builtin/shared/earnings-report.ts +3 -3
- package/src/plugins/builtin/shared/fx-rate-freshness.ts +23 -1
- package/src/plugins/builtin/shared/job-posting.ts +129 -0
- package/src/plugins/builtin/shared/pro-lock-note.ts +3 -3
- package/src/plugins/builtin/shared/report-freshness.ts +3 -0
- package/src/plugins/builtin/shared/research-trading.tsx +23 -0
- package/src/plugins/builtin/shared/series-cache.ts +2 -0
- package/src/plugins/builtin/shared/series-list-detail.tsx +3 -1
- package/src/plugins/builtin/shared/ticker-surface.ts +2 -1
- package/src/plugins/builtin/shared/volatility/options.ts +2 -1
- package/src/plugins/builtin/short-interest/client.ts +2 -0
- package/src/plugins/builtin/short-interest/headless.ts +41 -12
- package/src/plugins/builtin/short-interest/index.tsx +23 -1
- package/src/plugins/builtin/short-interest/model.ts +70 -19
- package/src/plugins/builtin/short-interest/pane.tsx +19 -2
- package/src/plugins/builtin/short-interest/publications-client.ts +82 -0
- package/src/plugins/builtin/short-interest/publications-headless.ts +29 -0
- package/src/plugins/builtin/short-interest/publications-model.ts +50 -0
- package/src/plugins/builtin/short-interest/publications-pane.tsx +66 -0
- package/src/plugins/builtin/short-interest/schedule.ts +35 -2
- package/src/plugins/builtin/short-interest/surface.tsx +11 -4
- package/src/plugins/builtin/short-interest/types.ts +9 -0
- package/src/plugins/builtin/short-interest/watch-client.ts +14 -8
- package/src/plugins/builtin/short-interest/watch-model.ts +12 -25
- package/src/plugins/builtin/short-interest/watch-pane.tsx +5 -1
- package/src/plugins/builtin/social-mentions/client.ts +2 -1
- package/src/plugins/builtin/supply-chain/flow.tsx +33 -9
- package/src/plugins/builtin/supply-chain/model.ts +51 -3
- package/src/plugins/builtin/supply-chain/pane.tsx +78 -39
- package/src/plugins/builtin/supply-chain/row-evidence.tsx +1 -1
- package/src/plugins/builtin/themes/headless.ts +8 -5
- package/src/plugins/builtin/themes/model.ts +14 -4
- package/src/plugins/builtin/themes/pane.tsx +24 -5
- package/src/plugins/builtin/thirteenf/headless.ts +5 -5
- package/src/plugins/builtin/thirteenf/signals.ts +3 -1
- package/src/plugins/builtin/ticker-detail/adr-pair/headless.ts +123 -0
- package/src/plugins/builtin/ticker-detail/adr-pair/model.ts +132 -0
- package/src/plugins/builtin/ticker-detail/adr-pair/tab.tsx +87 -0
- package/src/plugins/builtin/ticker-detail/data-panes/historical-prices.tsx +40 -26
- package/src/plugins/builtin/ticker-detail/data-panes/history-bars.ts +8 -4
- package/src/plugins/builtin/ticker-detail/data-panes/returns-history.ts +67 -3
- package/src/plugins/builtin/ticker-detail/data-panes/returns-model.ts +112 -5
- package/src/plugins/builtin/ticker-detail/data-panes/returns-pane.tsx +17 -2
- package/src/plugins/builtin/ticker-detail/financials/aggregation.ts +21 -7
- package/src/plugins/builtin/ticker-detail/financials/model.ts +36 -1
- package/src/plugins/builtin/ticker-detail/financials/offerings.ts +56 -0
- package/src/plugins/builtin/ticker-detail/financials/ratios.ts +62 -13
- package/src/plugins/builtin/ticker-detail/financials/tab.tsx +30 -4
- package/src/plugins/builtin/ticker-detail/headless-schema.ts +14 -2
- package/src/plugins/builtin/ticker-detail/headless.ts +148 -35
- package/src/plugins/builtin/ticker-detail/index.tsx +37 -5
- package/src/plugins/builtin/ticker-detail/overview/model.ts +65 -10
- package/src/plugins/builtin/ticker-detail/overview/pane.tsx +9 -1
- package/src/plugins/builtin/ticker-detail/overview-tab.tsx +68 -11
- package/src/plugins/builtin/ticker-detail/pane.tsx +11 -0
- package/src/plugins/builtin/ticker-detail/quote-footer.ts +8 -3
- package/src/plugins/builtin/ticker-detail/research-tabs.ts +11 -0
- package/src/plugins/builtin/vol-surface/client.ts +28 -7
- package/src/plugins/builtin/vol-surface/headless.ts +43 -15
- package/src/plugins/builtin/vol-surface/model.ts +34 -12
- package/src/plugins/builtin/vol-surface/pane.tsx +33 -13
- package/src/plugins/builtin/vol-surface/stored.ts +34 -3
- package/src/plugins/builtin/vol-surface/tables.ts +14 -0
- package/src/plugins/builtin/volatility/model.ts +5 -10
- package/src/plugins/builtin/world-venue-map/basemap-layer.tsx +4 -3
- package/src/plugins/builtin/world-venue-map/basemap.ts +3 -1
- package/src/plugins/builtin/world-venue-map/chokepoint-chart.ts +40 -0
- package/src/plugins/builtin/world-venue-map/evidence.ts +1 -1
- package/src/plugins/builtin/world-venue-map/geo-series.ts +90 -11
- package/src/plugins/builtin/world-venue-map/headless.ts +1 -1
- package/src/plugins/builtin/world-venue-map/index.ts +3 -26
- package/src/plugins/builtin/world-venue-map/layers.ts +1 -1
- package/src/plugins/builtin/world-venue-map/map.tsx +2 -1
- package/src/plugins/builtin/world-venue-map/pane.tsx +4 -2
- package/src/plugins/builtin/world-venue-map/venue-header.tsx +15 -4
- package/src/plugins/builtin/yield-curve/client.ts +25 -0
- package/src/plugins/builtin/yield-curve/curves.ts +7 -4
- package/src/plugins/builtin/yield-curve/headless.ts +38 -4
- package/src/plugins/builtin/yield-curve/history.ts +4 -3
- package/src/plugins/builtin/yield-curve/index.tsx +12 -6
- package/src/plugins/builtin/yield-curve/swaps-model.ts +93 -0
- package/src/plugins/builtin/yield-curve/swaps.tsx +99 -0
- package/src/plugins/bundle.ts +1 -1
- package/src/plugins/catalog-browser.ts +2 -1
- package/src/plugins/compat.ts +3 -3
- package/src/plugins/dependencies.ts +75 -14
- package/src/plugins/extracted-plugins.ts +132 -34
- package/src/plugins/host-link.ts +149 -34
- package/src/plugins/installer.ts +35 -10
- package/src/plugins/loader.ts +206 -38
- package/src/plugins/manager-node.ts +2 -2
- package/src/plugins/marketplace/deactivation.ts +22 -0
- package/src/plugins/marketplace/model.ts +2 -2
- package/src/plugins/marketplace/packs.ts +1 -1
- package/src/plugins/ownership.ts +1 -1
- package/src/plugins/peer-retry.ts +155 -0
- package/src/plugins/registry/contributions.ts +3 -1
- package/src/plugins/registry/index.ts +4 -3
- package/src/plugins/registry/plugin-state.ts +3 -0
- package/src/plugins/seed-notice.ts +20 -0
- package/src/plugins/shortcut-argument.ts +39 -0
- package/src/portfolio/allocation.ts +1 -1
- package/src/portfolio/collection-name.ts +31 -0
- package/src/portfolio/column-values.ts +10 -8
- package/src/portfolio/cost-fx.ts +296 -19
- package/src/portfolio/manual-lots.ts +75 -0
- package/src/portfolio/mutations.ts +60 -22
- package/src/portfolio/suffixed-listings.ts +209 -0
- package/src/portfolio/totals-currency.ts +24 -0
- package/src/public/__snapshots__/public-api.test.ts.snap +14 -0
- package/src/public/time-series.ts +11 -8
- package/src/remote/schema.ts +1 -1
- package/src/renderers/browser/config-host.ts +3 -0
- package/src/renderers/browser/main.tsx +23 -3
- package/src/renderers/dom/boot-frame-page.ts +187 -0
- package/src/renderers/dom/boot-frame.ts +237 -0
- package/src/renderers/dom/build-assets.ts +46 -8
- package/src/renderers/dom/desktop/controls.tsx +1 -1
- package/src/renderers/dom/desktop/query-bar.tsx +2 -0
- package/src/renderers/dom/dom-ui-host.tsx +4 -29
- package/src/renderers/dom/host/ascii-text.ts +16 -2
- package/src/renderers/dom/host/box.tsx +43 -2
- package/src/renderers/dom/host/chart-surface.tsx +2 -0
- package/src/renderers/dom/host/hls.chunk.ts +3 -0
- package/src/renderers/dom/host/image-surface.tsx +49 -0
- package/src/renderers/dom/host/media-surface.tsx +24 -18
- package/src/renderers/dom/host/mouse.ts +30 -0
- package/src/renderers/dom/host/size-observer.ts +1 -1
- package/src/renderers/dom/host/style.ts +1 -1
- package/src/renderers/dom/host/tabs.tsx +16 -5
- package/src/renderers/dom/host/top-surface.ts +127 -0
- package/src/renderers/dom/styles.css +115 -0
- package/src/renderers/dom/test-utils.tsx +2 -1
- package/src/renderers/electrobun/bun/application-menu/index.ts +3 -3
- package/src/renderers/electrobun/bun/core-capabilities.ts +9 -1
- package/src/renderers/electrobun/bun/desktop/backend-requests.ts +3 -0
- package/src/renderers/electrobun/bun/desktop/backend.ts +56 -3
- package/src/renderers/electrobun/bun/desktop/detached-windows.ts +1 -1
- package/src/renderers/electrobun/bun/desktop/host-requests.ts +9 -3
- package/src/renderers/electrobun/bun/desktop/initialization.ts +81 -18
- package/src/renderers/electrobun/bun/desktop/update.ts +210 -30
- package/src/renderers/electrobun/bun/external-plugins.ts +29 -7
- package/src/renderers/electrobun/bun/index.ts +11 -1
- package/src/renderers/electrobun/bun/window/boot-frame.ts +67 -0
- package/src/renderers/electrobun/bun/window/create.ts +4 -1
- package/src/renderers/electrobun/shared/boot-frame.ts +7 -0
- package/src/renderers/electrobun/shared/protocol.ts +6 -1
- package/src/renderers/electrobun/view/cli-pane-shot-entry.tsx +1 -1
- package/src/renderers/electrobun/view/config-host.ts +3 -0
- package/src/renderers/electrobun/view/fatal-screen.tsx +1 -1
- package/src/renderers/electrobun/view/main.tsx +30 -4
- package/src/renderers/electrobun/view/news-source.ts +9 -7
- package/src/renderers/electrobun/view/remote/asset-data-client.ts +9 -2
- package/src/renderers/electrobun/view/ui-host.tsx +1 -1
- package/src/renderers/opentui/browser-open.ts +88 -0
- package/src/renderers/opentui/host.tsx +5 -14
- package/src/renderers/opentui/image/loader.ts +3 -2
- package/src/renderers/opentui/native-smoke.ts +10 -1
- package/src/renderers/opentui/pane-image/index.ts +2 -1
- package/src/renderers/opentui/render-lib.ts +253 -0
- package/src/renderers/opentui/render-timing-smoke.ts +1 -1
- package/src/renderers/opentui/start.tsx +8 -1
- package/src/renderers/share/layout-view.tsx +2 -2
- package/src/renderers/share/main.tsx +4 -4
- package/src/renderers/share/view.tsx +1 -1
- package/src/series/resolve.ts +22 -6
- package/src/series/standalone.ts +30 -2
- package/src/series/types.ts +8 -1
- package/src/shares/api.ts +4 -1
- package/src/shares/pane.ts +1 -1
- package/src/sources/gloomberb-cloud/fred-series.ts +46 -1
- package/src/sources/gloomberb-cloud/index.ts +39 -16
- package/src/sources/gloomberb-cloud/news.ts +39 -0
- package/src/sources/gloomberb-cloud/normalizers.ts +14 -1
- package/src/sources/gloomberb-cloud/perpetuals.ts +49 -1
- package/src/sources/listing-symbols.ts +37 -0
- package/src/sources/provider-errors.ts +16 -2
- package/src/sources/provider-router/financial-routes.ts +21 -3
- package/src/sources/provider-router/financials.ts +15 -2
- package/src/sources/provider-router/history.ts +30 -8
- package/src/sources/provider-router/index.ts +16 -0
- package/src/sources/provider-router/primary.ts +1 -1
- package/src/state/app/bootstrap.ts +23 -0
- package/src/state/hooks/inline-tickers.ts +30 -5
- package/src/sync/controller.ts +1 -1
- package/src/sync/core-contributors.ts +46 -14
- package/src/team/collections-sync.ts +2 -1
- package/src/team/collections.ts +178 -17
- package/src/telemetry/crash-reports.ts +21 -4
- package/src/telemetry/update-failures-node.ts +59 -0
- package/src/telemetry/update-failures.ts +307 -0
- package/src/test-support/builtin-panes.ts +1 -1
- package/src/theme/colors.ts +3 -30
- package/src/theme/ui-tokens.ts +37 -1
- package/src/tickers/company-name-listing.ts +215 -36
- package/src/tickers/company-name.ts +43 -0
- package/src/tickers/index-roots.ts +47 -0
- package/src/tickers/instrument-label.ts +5 -1
- package/src/tickers/listing-fate.ts +30 -0
- package/src/tickers/metadata.ts +10 -0
- package/src/tickers/perpetual-listing.ts +5 -2
- package/src/tickers/search/home-listing.ts +75 -0
- package/src/tickers/search/index.ts +76 -27
- package/src/tickers/search/ranking.ts +54 -4
- package/src/tickers/search/upsert.ts +29 -0
- package/src/tickers/terminal-codes.ts +416 -40
- package/src/time-series/bar-aggregation.ts +243 -0
- package/src/time-series/base-series.ts +307 -0
- package/src/time-series/chart-bounds.ts +349 -0
- package/src/time-series/chart-seed.ts +142 -0
- package/src/time-series/economic.ts +5 -0
- package/src/time-series/fundamentals.ts +18 -3
- package/src/time-series/history-acquisition.ts +499 -0
- package/src/time-series/leverage.ts +100 -0
- package/src/time-series/market-resolution.ts +4 -2
- package/src/time-series/market.ts +2 -1
- package/src/time-series/price-comparison.ts +175 -30
- package/src/time-series/range.ts +9 -1
- package/src/time-series/resolution.ts +174 -16
- package/src/time-series/resolve-context.ts +157 -0
- package/src/time-series/resolve.ts +126 -1577
- package/src/time-series/series-name.ts +38 -0
- package/src/time-series/series-presentation.ts +208 -0
- package/src/time-series/spec.ts +11 -6
- package/src/time-series/studies.ts +109 -12
- package/src/time-series/tail-reconcile.ts +121 -0
- package/src/time-series/types.ts +29 -2
- package/src/time-series/use-chart-resolution.ts +4 -5
- package/src/types/broker.ts +10 -0
- package/src/types/config.ts +14 -0
- package/src/types/data-provider.ts +20 -0
- package/src/types/exchange-rate.ts +6 -0
- package/src/types/financials.ts +104 -7
- package/src/types/headless.ts +83 -6
- package/src/types/instrument.ts +3 -0
- package/src/types/issuer-listings.ts +28 -0
- package/src/types/plugin.ts +65 -8
- package/src/types/price-history.ts +2 -0
- package/src/types/ticker.ts +13 -0
- package/src/types/trading.ts +59 -1
- package/src/ui/ascii-font.ts +13 -1
- package/src/ui/host.tsx +6 -1
- package/src/updater/command-names.ts +175 -0
- package/src/updater/failure.ts +163 -0
- package/src/updater/index.ts +97 -28
- package/src/utils/calendar-date.ts +32 -15
- package/src/utils/cash-runway.ts +241 -0
- package/src/utils/central-banks.ts +42 -0
- package/src/utils/cli-output.ts +259 -80
- package/src/utils/contract-month.ts +16 -0
- package/src/utils/crypto-pair.ts +61 -3
- package/src/utils/currency-pair.ts +26 -0
- package/src/utils/currency-units.ts +29 -0
- package/src/utils/datetime-format.ts +10 -0
- package/src/utils/debug-log.ts +1 -1
- package/src/utils/decimal-comma.ts +39 -6
- package/src/utils/exchange-announcements.ts +71 -0
- package/src/utils/exchange-rate-snapshot.ts +10 -0
- package/src/utils/financial-statements.ts +83 -4
- package/src/utils/format.ts +34 -16
- package/src/utils/fundamentals.ts +150 -34
- package/src/utils/fx-market-hours.ts +10 -1
- package/src/utils/latest-financial-period.ts +8 -0
- package/src/utils/linux-libc.ts +54 -0
- package/src/utils/market-capitalization.ts +111 -15
- package/src/utils/max-drawdown.ts +64 -0
- package/src/utils/network-failure.ts +83 -0
- package/src/utils/option-expiry.ts +139 -7
- package/src/utils/price-earnings.ts +11 -5
- package/src/utils/price-history.ts +18 -8
- package/src/utils/price-window.ts +131 -0
- package/src/utils/release-date.ts +47 -0
- package/src/utils/sec.ts +71 -0
- package/src/utils/throttled-fetch.ts +11 -4
- package/src/utils/trailing-eps.ts +67 -0
- package/src/utils/typed-text.ts +21 -0
- package/src/utils/utc-time.ts +24 -1
- package/src/version.ts +6 -0
- package/src/cli/pane-functions/screenshot.ts +0 -2122
package/src/plugins/loader.ts
CHANGED
|
@@ -1,15 +1,23 @@
|
|
|
1
1
|
import { logFailure } from "../utils/log-failure";
|
|
2
2
|
import { readdir } from "fs/promises";
|
|
3
|
-
import { basename, join } from "path";
|
|
4
|
-
import { existsSync, lstatSync, readFileSync, statSync } from "fs";
|
|
3
|
+
import { basename, dirname, join } from "path";
|
|
4
|
+
import { existsSync, lstatSync, mkdirSync, readFileSync, statSync, writeFileSync } from "fs";
|
|
5
5
|
import { getGloomberbDirs } from "../data/config/home";
|
|
6
6
|
import type { GloomPlugin, PluginTarget } from "../types/plugin";
|
|
7
7
|
import { debugLog } from "../utils/debug-log";
|
|
8
8
|
import { reportCrash } from "../telemetry/crash-reports";
|
|
9
|
+
import { VERSION } from "../version";
|
|
9
10
|
import { findAbsorbedPlugin, type AbsorbedPlugin } from "./absorbed";
|
|
10
11
|
import { checkPluginCompatibility, explainPluginLoadError, findMissingHostExport, pluginSourceFiles, readPluginManifest } from "./compat";
|
|
11
|
-
import {
|
|
12
|
-
|
|
12
|
+
import {
|
|
13
|
+
describeDependencyInstalls,
|
|
14
|
+
installPluginDependencies,
|
|
15
|
+
missingPluginDependencies,
|
|
16
|
+
settleDependencyInstalls,
|
|
17
|
+
} from "./dependencies";
|
|
18
|
+
import { declaredPeerPlugins, describePeerLink, isLinkedPeerModule, linkHostPackages, relinkPeerPlugin } from "./host-link";
|
|
19
|
+
import { refreshResolverFolders, rekeyedEntry, withoutRetryQuery } from "./peer-retry";
|
|
20
|
+
import { pluginDirectoryNames } from "./plugin-names";
|
|
13
21
|
import { pluginFromModule, pluginSupportsTarget } from "./plugin-export";
|
|
14
22
|
|
|
15
23
|
const loaderLog = debugLog.createLogger("plugin-loader");
|
|
@@ -31,7 +39,7 @@ export interface LoadedExternalPlugin {
|
|
|
31
39
|
commit?: string;
|
|
32
40
|
/** `owner/repo` of the checkout's GitHub origin; usage counts trust only gloom-sh's. */
|
|
33
41
|
repo?: string;
|
|
34
|
-
/** A symlink to a local checkout (`
|
|
42
|
+
/** A symlink to a local checkout (`gloom plugin link`) rather than a clone. */
|
|
35
43
|
linked?: boolean;
|
|
36
44
|
/**
|
|
37
45
|
* The plugin's logo as a `data:` URL (plugin-icon.ts), for the desktop and
|
|
@@ -67,8 +75,8 @@ export function getPluginCacheDir(): string {
|
|
|
67
75
|
* Whether a directory inside the plugins folder is a plugin at all.
|
|
68
76
|
*
|
|
69
77
|
* Dot-directories are bookkeeping, not plugins: the desktop bundle cache used
|
|
70
|
-
* to be written to `plugins/.cache`, and it showed up in `
|
|
71
|
-
* as an installed plugin and in `
|
|
78
|
+
* to be written to `plugins/.cache`, and it showed up in `gloom plugins`
|
|
79
|
+
* as an installed plugin and in `gloom update` as a repo to pull. The
|
|
72
80
|
* cache has moved out, but old installs still have that directory, so this
|
|
73
81
|
* stays as the single rule every reader shares.
|
|
74
82
|
*/
|
|
@@ -176,7 +184,7 @@ export function findAbsorbedCheckout(pluginDir: string): AbsorbedPlugin | null {
|
|
|
176
184
|
|
|
177
185
|
function skipsAbsorbedCheckout(pluginDir: string, absorbed: AbsorbedPlugin | null = findAbsorbedCheckout(pluginDir)): boolean {
|
|
178
186
|
if (!absorbed) return false;
|
|
179
|
-
loaderLog.debug(`Skipped ${basename(pluginDir)}: ${absorbed.name} is built into
|
|
187
|
+
loaderLog.debug(`Skipped ${basename(pluginDir)}: ${absorbed.name} is built into Gloom now`);
|
|
180
188
|
return true;
|
|
181
189
|
}
|
|
182
190
|
|
|
@@ -243,6 +251,119 @@ function hasStaleModules(pluginDir: string, commit: string | null): boolean {
|
|
|
243
251
|
}
|
|
244
252
|
}
|
|
245
253
|
|
|
254
|
+
/**
|
|
255
|
+
* The entry a plugin was imported from on a retry, by plugin folder. A later
|
|
256
|
+
* load of the same plugin that is not fresh imports it from there again, so
|
|
257
|
+
* it gets the modules that loaded instead of the failed ones.
|
|
258
|
+
*/
|
|
259
|
+
const retriedEntries = new Map<string, string>();
|
|
260
|
+
|
|
261
|
+
/** Plugin folders whose recovery this process already reported; once is enough to explain it. */
|
|
262
|
+
const reportedRecoveries = new Set<string>();
|
|
263
|
+
|
|
264
|
+
/** Loads running now, which a crash report counts: two at once share the links they rewrite. */
|
|
265
|
+
let loadsInFlight = 0;
|
|
266
|
+
|
|
267
|
+
/**
|
|
268
|
+
* Whether this process is the first to load plugins since this version was
|
|
269
|
+
* installed, null until the first full load records it. Read from a marker
|
|
270
|
+
* in the plugin cache, which the first startup load of a new version writes.
|
|
271
|
+
*/
|
|
272
|
+
let firstLaunchOfVersion: boolean | null = null;
|
|
273
|
+
|
|
274
|
+
function recordLaunchedVersion(): void {
|
|
275
|
+
if (firstLaunchOfVersion !== null) return;
|
|
276
|
+
const marker = join(PLUGIN_CACHE_DIR, "loaded-version");
|
|
277
|
+
try {
|
|
278
|
+
const previous = existsSync(marker) ? readFileSync(marker, "utf-8").trim() : null;
|
|
279
|
+
firstLaunchOfVersion = previous !== VERSION;
|
|
280
|
+
if (firstLaunchOfVersion) {
|
|
281
|
+
mkdirSync(PLUGIN_CACHE_DIR, { recursive: true });
|
|
282
|
+
writeFileSync(marker, VERSION);
|
|
283
|
+
}
|
|
284
|
+
} catch (error) {
|
|
285
|
+
logFailure("plugin-loader", "Recording the loaded version failed")(error);
|
|
286
|
+
}
|
|
287
|
+
}
|
|
288
|
+
|
|
289
|
+
function errorMessage(err: unknown): string {
|
|
290
|
+
return err instanceof Error ? err.message : String(err);
|
|
291
|
+
}
|
|
292
|
+
|
|
293
|
+
/** The sibling plugin a failed import named, when the plugin declares it as a peer. */
|
|
294
|
+
function failedPeer(pluginDir: string, specifier: string | undefined): string | null {
|
|
295
|
+
if (!specifier) return null;
|
|
296
|
+
return declaredPeerPlugins(pluginDir).find((peer) => specifier === peer || specifier.startsWith(`${peer}/`)) ?? null;
|
|
297
|
+
}
|
|
298
|
+
|
|
299
|
+
/**
|
|
300
|
+
* The state of the link to `peer` and around it, for the crash report of an
|
|
301
|
+
* import that failed on it: whether the sibling's folder is there, what the
|
|
302
|
+
* link is and where it points, whether the retry rewrote it, how often this
|
|
303
|
+
* process wrote it before, which `bun install` runs this process made, how
|
|
304
|
+
* many loads ran at once, and whether this is the first launch of the version.
|
|
305
|
+
*/
|
|
306
|
+
function describePeerFailure(pluginDir: string, peer: string, relinked: string, retry: string): string {
|
|
307
|
+
const link = describePeerLink(pluginDir, peer);
|
|
308
|
+
const now = Date.now();
|
|
309
|
+
const installs = describeDependencyInstalls(now);
|
|
310
|
+
const fields = [
|
|
311
|
+
`retry=${retry}`,
|
|
312
|
+
`peer=${peer}`,
|
|
313
|
+
`dir=${link.directory ?? "missing"}`,
|
|
314
|
+
`link=${link.link}${link.target ? `->${link.target}` : ""}${link.linked ? "" : "(not-resolving)"}`,
|
|
315
|
+
`relinked=${relinked}`,
|
|
316
|
+
`link-writes=${link.writes}${link.lastWriteAt ? `@${((now - link.lastWriteAt) / 1000).toFixed(1)}s` : ""}`,
|
|
317
|
+
...(link.lastError ? [`link-error=${link.lastError}`] : []),
|
|
318
|
+
`installs=${installs.length > 0 ? installs.slice(0, 4).join(",") : "none"}`,
|
|
319
|
+
`loads=${loadsInFlight}`,
|
|
320
|
+
`first-launch=${firstLaunchOfVersion === null ? "unknown" : firstLaunchOfVersion ? "yes" : "no"}`,
|
|
321
|
+
...(typeof Bun !== "undefined" ? [`bun=${Bun.version}`] : []),
|
|
322
|
+
];
|
|
323
|
+
return fields.join(" ");
|
|
324
|
+
}
|
|
325
|
+
|
|
326
|
+
type PeerRetry =
|
|
327
|
+
| { module: unknown; detail: string }
|
|
328
|
+
| { error: unknown; detail: string };
|
|
329
|
+
|
|
330
|
+
/**
|
|
331
|
+
* The import that failed on `peer`, once more after linking the sibling
|
|
332
|
+
* again: past Bun's cached view of the plugin's folders and under new module
|
|
333
|
+
* keys (see peer-retry.ts), so it really resolves the sibling again rather
|
|
334
|
+
* than replaying the failure.
|
|
335
|
+
*/
|
|
336
|
+
async function retryPeerImport(pluginDir: string, entryFile: string, peer: string): Promise<PeerRetry> {
|
|
337
|
+
// A `bun install` still running in the plugin or the sibling prunes the
|
|
338
|
+
// link it is about to need.
|
|
339
|
+
const peerDirs = pluginDirectoryNames(peer).map((name) => join(dirname(pluginDir), name));
|
|
340
|
+
await settleDependencyInstalls([pluginDir, ...peerDirs], 15_000);
|
|
341
|
+
// Windows refuses a new junction where one is still being deleted until
|
|
342
|
+
// every handle on the old one closes; that passes in moments.
|
|
343
|
+
const attempts = [relinkPeerPlugin(pluginDir, peer)];
|
|
344
|
+
for (const delayMs of [250, 1_000]) {
|
|
345
|
+
if (!attempts.at(-1)!.startsWith("failed")) break;
|
|
346
|
+
await new Promise((resolve) => setTimeout(resolve, delayMs));
|
|
347
|
+
attempts.push(relinkPeerPlugin(pluginDir, peer));
|
|
348
|
+
}
|
|
349
|
+
const relinked = attempts.join(",");
|
|
350
|
+
// An install that finished during the wait pruned `gloomberb` and `react`
|
|
351
|
+
// as well. After the sibling's own relink, so `relinked` says what that did.
|
|
352
|
+
linkHostPackages(pluginDir);
|
|
353
|
+
refreshResolverFolders(pluginDir, [peer]);
|
|
354
|
+
const specifier = rekeyedEntry(entryFile, pluginDir);
|
|
355
|
+
if (!specifier) {
|
|
356
|
+
return { error: new Error("This process cannot import a plugin again."), detail: describePeerFailure(pluginDir, peer, relinked, "unavailable") };
|
|
357
|
+
}
|
|
358
|
+
try {
|
|
359
|
+
const module = await import(specifier);
|
|
360
|
+
retriedEntries.set(pluginDir, specifier);
|
|
361
|
+
return { module, detail: describePeerFailure(pluginDir, peer, relinked, "loaded") };
|
|
362
|
+
} catch (error) {
|
|
363
|
+
return { error, detail: describePeerFailure(pluginDir, peer, relinked, "failed") };
|
|
364
|
+
}
|
|
365
|
+
}
|
|
366
|
+
|
|
246
367
|
/**
|
|
247
368
|
* Loads one plugin directory. Never throws: a broken plugin comes back with
|
|
248
369
|
* `error` set. Null for a folder that is not a plugin, and for a leftover
|
|
@@ -253,6 +374,19 @@ export async function loadExternalPlugin(
|
|
|
253
374
|
pluginDir: string,
|
|
254
375
|
target: PluginTarget = "cli",
|
|
255
376
|
options: LoadExternalPluginOptions = {},
|
|
377
|
+
): Promise<LoadedExternalPlugin | null> {
|
|
378
|
+
loadsInFlight += 1;
|
|
379
|
+
try {
|
|
380
|
+
return await loadPluginDirectory(pluginDir, target, options);
|
|
381
|
+
} finally {
|
|
382
|
+
loadsInFlight -= 1;
|
|
383
|
+
}
|
|
384
|
+
}
|
|
385
|
+
|
|
386
|
+
async function loadPluginDirectory(
|
|
387
|
+
pluginDir: string,
|
|
388
|
+
target: PluginTarget,
|
|
389
|
+
options: LoadExternalPluginOptions,
|
|
256
390
|
): Promise<LoadedExternalPlugin | null> {
|
|
257
391
|
const directory = basename(pluginDir);
|
|
258
392
|
missingHostExportFailures.delete(directory);
|
|
@@ -303,9 +437,68 @@ export async function loadExternalPlugin(
|
|
|
303
437
|
const restart = hasStaleModules(pluginDir, commit) ? { needsRestart: true } : {};
|
|
304
438
|
if (!importedCommits.has(pluginDir)) importedCommits.set(pluginDir, commit);
|
|
305
439
|
|
|
440
|
+
const failed = (err: unknown, retry?: Extract<PeerRetry, { error: unknown }>): LoadedExternalPlugin => {
|
|
441
|
+
const message = errorMessage(err);
|
|
442
|
+
let detail: string | undefined;
|
|
443
|
+
if (retry) {
|
|
444
|
+
// As plain text: escaping would double a Windows path's backslashes,
|
|
445
|
+
// and the home folder would no longer be recognized to remove.
|
|
446
|
+
const retryMessage = withoutRetryQuery(errorMessage(retry.error));
|
|
447
|
+
detail = retryMessage === message ? retry.detail : `${retry.detail} retry-error=${retryMessage.slice(0, 200)}`;
|
|
448
|
+
// The sibling is installed and linked, and a second import that
|
|
449
|
+
// looked again still failed. A new process imports everything fresh,
|
|
450
|
+
// so the plugin asks for a restart, and the report says why it got here.
|
|
451
|
+
const unresolved = unresolvedSpecifier(err, message);
|
|
452
|
+
if (unresolved && isLinkedPeerModule(pluginDir, unresolved)) {
|
|
453
|
+
loaderLog.info(`${directory} loads after a restart: ${message} [${detail}]`);
|
|
454
|
+
reportCrash(err, { kind: "plugin", plugin: directory, detail });
|
|
455
|
+
return { ...base, plugin: placeholder, needsRestart: true };
|
|
456
|
+
}
|
|
457
|
+
}
|
|
458
|
+
// An update that links against modules this process imported at the old
|
|
459
|
+
// commit, which Bun keeps until a restart. The row already asks for one,
|
|
460
|
+
// and the next launch imports everything fresh; a plugin that is really
|
|
461
|
+
// broken fails there, and is reported there. A host export the running
|
|
462
|
+
// Gloomberb lacks is a different failure and stays one.
|
|
463
|
+
if (restart.needsRestart && !findMissingHostExport(message) && STALE_LINK_FAILURE.test(message)) {
|
|
464
|
+
loaderLog.info(`${directory} loads after a restart: ${message}`);
|
|
465
|
+
return { ...base, plugin: placeholder, needsRestart: true };
|
|
466
|
+
}
|
|
467
|
+
loaderLog.error(`Failed to load plugin from ${pluginDir}: ${err}${detail ? ` [${detail}]` : ""}`);
|
|
468
|
+
reportCrash(err, { kind: "plugin", plugin: directory, ...(detail ? { detail } : {}) });
|
|
469
|
+
if (findMissingHostExport(message)) missingHostExportFailures.add(directory);
|
|
470
|
+
return {
|
|
471
|
+
...base,
|
|
472
|
+
...restart,
|
|
473
|
+
plugin: placeholder,
|
|
474
|
+
error: explainPluginLoadError(message),
|
|
475
|
+
};
|
|
476
|
+
};
|
|
477
|
+
|
|
478
|
+
let module: unknown;
|
|
306
479
|
try {
|
|
307
|
-
const
|
|
308
|
-
|
|
480
|
+
const retried = options.fresh ? undefined : retriedEntries.get(pluginDir);
|
|
481
|
+
module = await import(retried ?? (options.fresh ? `${entryFile}?reload=${Date.now()}` : entryFile));
|
|
482
|
+
} catch (err) {
|
|
483
|
+
// A sibling plugin it imports that did not resolve: not linked yet, or
|
|
484
|
+
// its link was being rewritten. Bun keeps that failure for the process,
|
|
485
|
+
// so the plugin is linked and imported again in a way that looks again.
|
|
486
|
+
const peer = failedPeer(pluginDir, unresolvedSpecifier(err, errorMessage(err)));
|
|
487
|
+
if (!peer) return failed(err);
|
|
488
|
+
const retry = await retryPeerImport(pluginDir, entryFile, peer);
|
|
489
|
+
if ("error" in retry) return failed(err, retry);
|
|
490
|
+
// Loaded, but the failure it recovered from is still a bug somewhere:
|
|
491
|
+
// the report carries the link state that explains it.
|
|
492
|
+
loaderLog.info(`Loaded ${directory} on a second import: ${errorMessage(err)} [${retry.detail}]`);
|
|
493
|
+
if (!reportedRecoveries.has(pluginDir)) {
|
|
494
|
+
reportedRecoveries.add(pluginDir);
|
|
495
|
+
reportCrash(err, { kind: "plugin", plugin: directory, detail: retry.detail });
|
|
496
|
+
}
|
|
497
|
+
module = retry.module;
|
|
498
|
+
}
|
|
499
|
+
|
|
500
|
+
try {
|
|
501
|
+
const plugin = pluginFromModule(module);
|
|
309
502
|
if (!plugin) {
|
|
310
503
|
const error = "Plugin did not export a valid GloomPlugin (missing id or name).";
|
|
311
504
|
reportCrash(error, { kind: "plugin", plugin: directory });
|
|
@@ -325,33 +518,7 @@ export async function loadExternalPlugin(
|
|
|
325
518
|
loaderLog.info(`Loaded external plugin: ${plugin.id} v${plugin.version ?? "0.0.0"}`);
|
|
326
519
|
return { ...base, ...restart, plugin };
|
|
327
520
|
} catch (err) {
|
|
328
|
-
|
|
329
|
-
// A sibling plugin it imports that is linked now but was not when this
|
|
330
|
-
// process first resolved it. Bun keeps that failure until a restart, which
|
|
331
|
-
// is all the plugin needs: not a crash.
|
|
332
|
-
const unresolved = unresolvedSpecifier(err, message);
|
|
333
|
-
if (unresolved && isLinkedPeerModule(pluginDir, unresolved)) {
|
|
334
|
-
loaderLog.info(`${directory} loads after a restart: ${message}`);
|
|
335
|
-
return { ...base, plugin: placeholder, needsRestart: true };
|
|
336
|
-
}
|
|
337
|
-
// An update that links against modules this process imported at the old
|
|
338
|
-
// commit, which Bun keeps until a restart. The row already asks for one,
|
|
339
|
-
// and the next launch imports everything fresh; a plugin that is really
|
|
340
|
-
// broken fails there, and is reported there. A host export the running
|
|
341
|
-
// Gloomberb lacks is a different failure and stays one.
|
|
342
|
-
if (restart.needsRestart && !findMissingHostExport(message) && STALE_LINK_FAILURE.test(message)) {
|
|
343
|
-
loaderLog.info(`${directory} loads after a restart: ${message}`);
|
|
344
|
-
return { ...base, plugin: placeholder, needsRestart: true };
|
|
345
|
-
}
|
|
346
|
-
loaderLog.error(`Failed to load plugin from ${pluginDir}: ${err}`);
|
|
347
|
-
reportCrash(err, { kind: "plugin", plugin: directory });
|
|
348
|
-
if (findMissingHostExport(message)) missingHostExportFailures.add(directory);
|
|
349
|
-
return {
|
|
350
|
-
...base,
|
|
351
|
-
...restart,
|
|
352
|
-
plugin: placeholder,
|
|
353
|
-
error: explainPluginLoadError(message),
|
|
354
|
-
};
|
|
521
|
+
return failed(err);
|
|
355
522
|
}
|
|
356
523
|
}
|
|
357
524
|
|
|
@@ -382,6 +549,7 @@ export async function listPluginDirectories(pluginsDir: string = PLUGINS_DIR): P
|
|
|
382
549
|
}
|
|
383
550
|
|
|
384
551
|
export async function loadExternalPlugins(target: PluginTarget = "cli"): Promise<LoadedExternalPlugin[]> {
|
|
552
|
+
recordLaunchedVersion();
|
|
385
553
|
const results: LoadedExternalPlugin[] = [];
|
|
386
554
|
for (const pluginDir of await listPluginDirectories()) {
|
|
387
555
|
const loaded = await loadExternalPlugin(pluginDir, target);
|
|
@@ -399,7 +567,7 @@ function isSymlink(path: string): boolean {
|
|
|
399
567
|
}
|
|
400
568
|
}
|
|
401
569
|
|
|
402
|
-
/** A linked plugin (`
|
|
570
|
+
/** A linked plugin (`gloom plugin link`) is a symlink, which `readdir` does not report as a directory. */
|
|
403
571
|
export function isDirectoryOrLink(entry: { isDirectory(): boolean; isSymbolicLink(): boolean }, path: string): boolean {
|
|
404
572
|
if (entry.isDirectory()) return true;
|
|
405
573
|
if (!entry.isSymbolicLink()) return false;
|
|
@@ -6,7 +6,7 @@ import type { PluginTarget } from "../types/plugin";
|
|
|
6
6
|
/**
|
|
7
7
|
* The plugin manager for a process that can run git and bun: the terminal,
|
|
8
8
|
* and the desktop's Bun side on behalf of its view. Wraps the installer so
|
|
9
|
-
* the marketplace and `
|
|
9
|
+
* the marketplace and `gloom install` do exactly the same thing, and
|
|
10
10
|
* turns its failures into results the pane can show next to the row.
|
|
11
11
|
*/
|
|
12
12
|
|
|
@@ -41,7 +41,7 @@ export function createNodePluginManager(target: PluginTarget, hooks: NodePluginM
|
|
|
41
41
|
}
|
|
42
42
|
|
|
43
43
|
return {
|
|
44
|
-
// Through the registry, like `
|
|
44
|
+
// Through the registry, like `gloom install`: a plugin that builds on
|
|
45
45
|
// another brings it along instead of failing to load without it.
|
|
46
46
|
install: (repo, pin) => attempt(async () => (await installer()).installListedPlugin(repo, { quiet: true, ...(pin ? { pin } : {}) })),
|
|
47
47
|
update: (directory, pin) => attempt(async () => (await installer()).updatePlugin(directory, { quiet: true, pin })),
|
|
@@ -0,0 +1,22 @@
|
|
|
1
|
+
import type { PluginRegistry } from "../registry";
|
|
2
|
+
import { logFailure } from "../../utils/log-failure";
|
|
3
|
+
|
|
4
|
+
// unregister removes the registration even when cleanup throws. A later
|
|
5
|
+
// no-op cannot confirm that its background work stopped. Keep that uncertainty
|
|
6
|
+
// with this runtime, across pane remounts, until a fresh registry starts.
|
|
7
|
+
const failedStops = new WeakMap<PluginRegistry, Set<string>>();
|
|
8
|
+
|
|
9
|
+
export function deactivatePluginForRemoval(registry: PluginRegistry, pluginId: string): void {
|
|
10
|
+
const failure = "Plugin could not be stopped. Restart before removing it.";
|
|
11
|
+
if (failedStops.get(registry)?.has(pluginId)) throw new Error(failure);
|
|
12
|
+
if (!registry.allPlugins.has(pluginId)) return;
|
|
13
|
+
try {
|
|
14
|
+
registry.unregister(pluginId);
|
|
15
|
+
} catch (error) {
|
|
16
|
+
const failed = failedStops.get(registry) ?? new Set<string>();
|
|
17
|
+
failed.add(pluginId);
|
|
18
|
+
failedStops.set(registry, failed);
|
|
19
|
+
logFailure("plugin-removal", "Plugin cleanup before removal failed")(error);
|
|
20
|
+
throw new Error(failure);
|
|
21
|
+
}
|
|
22
|
+
}
|
|
@@ -72,7 +72,7 @@ export interface InstalledPlugin {
|
|
|
72
72
|
path?: string;
|
|
73
73
|
/** Checked-out commit, when the install is a git checkout. */
|
|
74
74
|
commit?: string;
|
|
75
|
-
/** A dev link (`
|
|
75
|
+
/** A dev link (`gloom plugin link`) rather than a clone. */
|
|
76
76
|
linked?: boolean;
|
|
77
77
|
/** Set when the plugin is installed but cannot run on this renderer. */
|
|
78
78
|
unsupportedTarget?: PluginTarget;
|
|
@@ -180,7 +180,7 @@ function isFeatured(id: string, bundled: boolean, feedFeatured: boolean | undefi
|
|
|
180
180
|
* plugin can be installed but inert because this renderer cannot run it. The
|
|
181
181
|
* merge keeps all three visible rather than showing whichever list is handy.
|
|
182
182
|
*/
|
|
183
|
-
/** The folder `
|
|
183
|
+
/** The folder `gloom install owner/repo` creates, which is the repository name. */
|
|
184
184
|
function repoDirectory(repo: string | undefined): string | null {
|
|
185
185
|
const name = repo?.split("/")[1]?.replace(/\.git$/, "");
|
|
186
186
|
return name ? name.toLowerCase() : null;
|
|
@@ -37,7 +37,7 @@ export const STARTER_PACKS: readonly StarterPack[] = [
|
|
|
37
37
|
{
|
|
38
38
|
id: "everything",
|
|
39
39
|
name: "Everything",
|
|
40
|
-
tagline: "Every research plugin on, as
|
|
40
|
+
tagline: "Every research plugin on, as Gloom ships.",
|
|
41
41
|
plugins: PACK_PLUGIN_IDS,
|
|
42
42
|
},
|
|
43
43
|
{
|
package/src/plugins/ownership.ts
CHANGED
|
@@ -110,7 +110,7 @@ export function builtinPluginGroupMembers(pluginId: string): readonly string[] |
|
|
|
110
110
|
/**
|
|
111
111
|
* `disabledPlugins` after switching plugins on or off in one go, or null when
|
|
112
112
|
* nothing changes. A retired group id switches every member, the way
|
|
113
|
-
* `
|
|
113
|
+
* `gloom plugin enable|disable` does. Changes apply in order, so a later
|
|
114
114
|
* one wins for a plugin two groups share.
|
|
115
115
|
*/
|
|
116
116
|
export function applyPluginToggles(
|
|
@@ -0,0 +1,155 @@
|
|
|
1
|
+
import { readdirSync, readFileSync, type Dirent } from "fs";
|
|
2
|
+
import { dirname, extname, isAbsolute, join, relative } from "path";
|
|
3
|
+
|
|
4
|
+
/**
|
|
5
|
+
* A second import of a plugin whose first one failed on a sibling plugin it
|
|
6
|
+
* imports (IBKR Gateway imports Interactive Brokers), that really looks again.
|
|
7
|
+
*
|
|
8
|
+
* Bun keeps both halves of that failure for the rest of the process. Its
|
|
9
|
+
* resolver remembers each folder it read, so `node_modules` stays without the
|
|
10
|
+
* sibling after the link is made. And the module that failed stays failed
|
|
11
|
+
* under its path, so importing the entry again, even under a fresh query,
|
|
12
|
+
* reaches the same error through the entry's own `./plugin` import. Until
|
|
13
|
+
* now only a restart cleared it, which is why the gateway failed on a launch
|
|
14
|
+
* and worked on the next one.
|
|
15
|
+
*
|
|
16
|
+
* The retry undoes both. It makes Bun read the plugin's folders again (a
|
|
17
|
+
* lookup that misses in a folder Bun had read drops that folder from its
|
|
18
|
+
* cache), and it imports every file of the plugin under a new module key, so
|
|
19
|
+
* nothing from the failed attempt is reused. Imports that leave the plugin,
|
|
20
|
+
* the sibling's files included, resolve to the same modules as always, so the
|
|
21
|
+
* plugin shares the sibling's state as on a normal load.
|
|
22
|
+
*/
|
|
23
|
+
|
|
24
|
+
/** The query that gives a plugin's files their new module keys. */
|
|
25
|
+
const RETRY_PARAM = "gloom-plugin-retry";
|
|
26
|
+
const RETRY_QUERY = new RegExp(`[?&]${RETRY_PARAM}=(\\d+)(?:&|$)`);
|
|
27
|
+
const SOURCE_LOADERS: Readonly<Record<string, "ts" | "tsx" | "js" | "jsx">> = {
|
|
28
|
+
".ts": "ts",
|
|
29
|
+
".mts": "ts",
|
|
30
|
+
".tsx": "tsx",
|
|
31
|
+
".js": "js",
|
|
32
|
+
".mjs": "js",
|
|
33
|
+
".jsx": "jsx",
|
|
34
|
+
};
|
|
35
|
+
/** A file name that is never there: looking it up is what clears a folder. */
|
|
36
|
+
const MISSING_FILE = "./.gloom-resolver-refresh";
|
|
37
|
+
const SKIPPED_FOLDERS = new Set(["node_modules", ".git", "dist"]);
|
|
38
|
+
|
|
39
|
+
/**
|
|
40
|
+
* `text` without the retry query Bun puts in the paths of a retried import's
|
|
41
|
+
* errors, so the retry's error reads like the first import's.
|
|
42
|
+
*/
|
|
43
|
+
export function withoutRetryQuery(text: string): string {
|
|
44
|
+
return text.replace(new RegExp(`[?&]${RETRY_PARAM}=\\d+`, "g"), "");
|
|
45
|
+
}
|
|
46
|
+
|
|
47
|
+
/** The plugin folder each retry imports from, by retry number. */
|
|
48
|
+
const retryRoots = new Map<number, string>();
|
|
49
|
+
let retries = 0;
|
|
50
|
+
let installed = false;
|
|
51
|
+
|
|
52
|
+
function isInside(root: string, path: string): boolean {
|
|
53
|
+
const inside = relative(root, path);
|
|
54
|
+
return !!inside && !inside.startsWith("..") && !isAbsolute(inside);
|
|
55
|
+
}
|
|
56
|
+
|
|
57
|
+
/** The plugin's own folders, without dependencies or build output. */
|
|
58
|
+
function sourceFolders(dir: string, out: string[] = [], depth = 0): string[] {
|
|
59
|
+
out.push(dir);
|
|
60
|
+
if (depth > 8) return out;
|
|
61
|
+
let entries: Dirent[];
|
|
62
|
+
try {
|
|
63
|
+
entries = readdirSync(dir, { withFileTypes: true });
|
|
64
|
+
} catch {
|
|
65
|
+
// Intentional ignore: a folder that cannot be listed has nothing Bun could have cached.
|
|
66
|
+
return out;
|
|
67
|
+
}
|
|
68
|
+
for (const entry of entries) {
|
|
69
|
+
if (entry.isDirectory() && !SKIPPED_FOLDERS.has(entry.name)) sourceFolders(join(dir, entry.name), out, depth + 1);
|
|
70
|
+
}
|
|
71
|
+
return out;
|
|
72
|
+
}
|
|
73
|
+
|
|
74
|
+
/**
|
|
75
|
+
* Makes Bun read the plugin's folders and its links to `peers` from disk
|
|
76
|
+
* again. Bun drops a folder from its resolver cache when a lookup in it
|
|
77
|
+
* misses, so this looks up a file that is not there in each one. The
|
|
78
|
+
* bundler shares the cache, which is why the desktop's compile of the same
|
|
79
|
+
* plugin failed in the same session too.
|
|
80
|
+
*/
|
|
81
|
+
export function refreshResolverFolders(pluginDir: string, peers: readonly string[]): void {
|
|
82
|
+
const modules = join(pluginDir, "node_modules");
|
|
83
|
+
const folders = [...sourceFolders(pluginDir), modules];
|
|
84
|
+
for (const peer of peers) {
|
|
85
|
+
if (peer.startsWith("@")) folders.push(join(modules, peer.split("/")[0]!));
|
|
86
|
+
folders.push(join(modules, peer));
|
|
87
|
+
}
|
|
88
|
+
for (const folder of folders) {
|
|
89
|
+
try {
|
|
90
|
+
Bun.resolveSync(MISSING_FILE, folder);
|
|
91
|
+
} catch {
|
|
92
|
+
// Intentional ignore: the miss is what drops the folder from the cache.
|
|
93
|
+
}
|
|
94
|
+
}
|
|
95
|
+
}
|
|
96
|
+
|
|
97
|
+
/**
|
|
98
|
+
* The plugin's file at `path` (with the retry query), its relative imports
|
|
99
|
+
* of other source files in the plugin given the same query, so they load
|
|
100
|
+
* under new keys as well. Imports that leave the plugin keep their keys.
|
|
101
|
+
*/
|
|
102
|
+
function rekeyedSource(path: string): { contents: string; loader: "ts" | "tsx" | "js" | "jsx" } {
|
|
103
|
+
const match = RETRY_QUERY.exec(path);
|
|
104
|
+
const file = match ? path.slice(0, match.index) : path;
|
|
105
|
+
const loader = SOURCE_LOADERS[extname(file).toLowerCase()] ?? "js";
|
|
106
|
+
let contents = readFileSync(file, "utf8");
|
|
107
|
+
const root = match ? retryRoots.get(Number(match[1])) : undefined;
|
|
108
|
+
if (!match || !root) return { contents, loader };
|
|
109
|
+
const retry = Number(match[1]);
|
|
110
|
+
const specifiers = new Set(
|
|
111
|
+
new Bun.Transpiler({ loader }).scanImports(contents)
|
|
112
|
+
.map((entry) => entry.path)
|
|
113
|
+
.filter((specifier) => (specifier.startsWith("./") || specifier.startsWith("../")) && !specifier.includes("?")),
|
|
114
|
+
);
|
|
115
|
+
for (const specifier of specifiers) {
|
|
116
|
+
let target: string;
|
|
117
|
+
try {
|
|
118
|
+
target = Bun.resolveSync(specifier, dirname(file));
|
|
119
|
+
} catch {
|
|
120
|
+
// Intentional ignore: left as written, the import fails the way it would have.
|
|
121
|
+
continue;
|
|
122
|
+
}
|
|
123
|
+
if (!isInside(root, target) || !SOURCE_LOADERS[extname(target).toLowerCase()]) continue;
|
|
124
|
+
const rekeyed = `${specifier}?${RETRY_PARAM}=${retry}`;
|
|
125
|
+
for (const quote of ["\"", "'", "`"]) {
|
|
126
|
+
contents = contents.split(`${quote}${specifier}${quote}`).join(`${quote}${rekeyed}${quote}`);
|
|
127
|
+
}
|
|
128
|
+
}
|
|
129
|
+
return { contents, loader };
|
|
130
|
+
}
|
|
131
|
+
|
|
132
|
+
function installRekeyingLoader(): boolean {
|
|
133
|
+
if (installed) return true;
|
|
134
|
+
if (typeof Bun === "undefined" || typeof Bun.plugin !== "function") return false;
|
|
135
|
+
Bun.plugin({
|
|
136
|
+
name: "gloomberb-plugin-retry",
|
|
137
|
+
setup(build) {
|
|
138
|
+
build.onLoad({ filter: RETRY_QUERY }, (args) => rekeyedSource(args.path));
|
|
139
|
+
},
|
|
140
|
+
});
|
|
141
|
+
installed = true;
|
|
142
|
+
return true;
|
|
143
|
+
}
|
|
144
|
+
|
|
145
|
+
/**
|
|
146
|
+
* The specifier that imports `entryFile` and the rest of its plugin under
|
|
147
|
+
* new module keys, or null when this process cannot register the loader that
|
|
148
|
+
* does it. The same specifier imports the same modules again.
|
|
149
|
+
*/
|
|
150
|
+
export function rekeyedEntry(entryFile: string, pluginDir: string): string | null {
|
|
151
|
+
if (!installRekeyingLoader()) return null;
|
|
152
|
+
retries += 1;
|
|
153
|
+
retryRoots.set(retries, pluginDir);
|
|
154
|
+
return `${entryFile}?${RETRY_PARAM}=${retries}`;
|
|
155
|
+
}
|
|
@@ -11,6 +11,7 @@ import type {
|
|
|
11
11
|
TickerAction,
|
|
12
12
|
TickerResearchTabDef,
|
|
13
13
|
} from "../../types/plugin";
|
|
14
|
+
import { withFunctionShortcutArgument } from "../shortcut-argument";
|
|
14
15
|
|
|
15
16
|
export interface ContextMenuProviderEntry {
|
|
16
17
|
pluginId: string;
|
|
@@ -89,7 +90,8 @@ export class RegistryContributions {
|
|
|
89
90
|
}
|
|
90
91
|
|
|
91
92
|
registerPaneTemplate(pluginId: string, template: PaneTemplateDef, replace = false): () => void {
|
|
92
|
-
|
|
93
|
+
const registered = withFunctionShortcutArgument(template, this.panesMap.get(template.paneId));
|
|
94
|
+
return this.paneTemplatesMap.register(pluginId, template.id, registered, replace);
|
|
93
95
|
}
|
|
94
96
|
|
|
95
97
|
registerCommand(pluginId: string, command: CommandDef): void {
|
|
@@ -69,6 +69,7 @@ import {
|
|
|
69
69
|
bindPluginContextNamespaces,
|
|
70
70
|
createPluginPaneSettingsState,
|
|
71
71
|
createPluginResumeState,
|
|
72
|
+
resumeStateKey,
|
|
72
73
|
type NamespacedPluginContext,
|
|
73
74
|
} from "./plugin-state";
|
|
74
75
|
import { createPluginSetupCommand, isPluginConfigured } from "./setup-command";
|
|
@@ -405,18 +406,18 @@ export class PluginRegistry implements PluginRuntimeAccess {
|
|
|
405
406
|
|
|
406
407
|
getResumeState<T = unknown>(pluginId: string, key: string, schemaVersion?: number): T | null {
|
|
407
408
|
const stateId = this.stateNamespace(pluginId);
|
|
408
|
-
return this.persistence.pluginState.get<T>(stateId,
|
|
409
|
+
return this.persistence.pluginState.get<T>(stateId, resumeStateKey(key), schemaVersion)?.value ?? null;
|
|
409
410
|
}
|
|
410
411
|
|
|
411
412
|
setResumeState(pluginId: string, key: string, value: unknown, schemaVersion?: number): void {
|
|
412
413
|
const stateId = this.stateNamespace(pluginId);
|
|
413
|
-
this.persistence.pluginState.set(stateId,
|
|
414
|
+
this.persistence.pluginState.set(stateId, resumeStateKey(key), value, schemaVersion);
|
|
414
415
|
this.resumeStateListeners.emit(stateId, key);
|
|
415
416
|
}
|
|
416
417
|
|
|
417
418
|
deleteResumeState(pluginId: string, key: string): void {
|
|
418
419
|
const stateId = this.stateNamespace(pluginId);
|
|
419
|
-
this.persistence.pluginState.delete(stateId,
|
|
420
|
+
this.persistence.pluginState.delete(stateId, resumeStateKey(key));
|
|
420
421
|
this.resumeStateListeners.emit(stateId, key);
|
|
421
422
|
}
|
|
422
423
|
|
|
@@ -4,6 +4,9 @@ import type { LayoutConfig } from "../../types/config";
|
|
|
4
4
|
import type { GloomPluginContext, PluginPaneSettingsState, PluginResumeState } from "../../types/plugin";
|
|
5
5
|
import { deletePluginPaneStateValue, setPluginPaneStateValue } from "../../layout/pane-state";
|
|
6
6
|
|
|
7
|
+
/** Where a plugin's resume state (`ctx.resume`) is kept in the device's plugin state store. */
|
|
8
|
+
export const resumeStateKey = (key: string) => `resume:${key}`;
|
|
9
|
+
|
|
7
10
|
export class RegistryResumeStateListeners {
|
|
8
11
|
private listeners = new Map<string, Set<() => void>>();
|
|
9
12
|
|
|
@@ -0,0 +1,20 @@
|
|
|
1
|
+
import type { PluginSeedNotice } from "./extracted-plugins";
|
|
2
|
+
|
|
3
|
+
/**
|
|
4
|
+
* What the launch's plugin seed could not install, said once the app is up.
|
|
5
|
+
* The seed runs before the app renders (in the terminal's process, or the
|
|
6
|
+
* desktop's Bun process, which hands it to its main window), so it leaves the
|
|
7
|
+
* notice here and the app takes it.
|
|
8
|
+
*/
|
|
9
|
+
let pending: PluginSeedNotice | null = null;
|
|
10
|
+
|
|
11
|
+
export function setPluginSeedNotice(notice: PluginSeedNotice | null): void {
|
|
12
|
+
pending = notice;
|
|
13
|
+
}
|
|
14
|
+
|
|
15
|
+
/** The notice, once: a second call returns null. */
|
|
16
|
+
export function takePluginSeedNotice(): PluginSeedNotice | null {
|
|
17
|
+
const notice = pending;
|
|
18
|
+
pending = null;
|
|
19
|
+
return notice;
|
|
20
|
+
}
|