gloomberb 0.11.3 → 0.12.0
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 +6 -4
- package/README.zh-CN.md +4 -2
- package/package.json +28 -1
- package/src/api-client/auth.ts +10 -0
- package/src/api-client/data.ts +103 -1
- package/src/api-client/index.test.ts +127 -0
- package/src/api-client/index.ts +129 -1
- package/src/api-client/normalizers.ts +39 -0
- package/src/api-client/paths.ts +85 -1
- package/src/api-client/types.ts +196 -0
- package/src/app/pane-runtime/index.tsx +15 -12
- package/src/app/pane-runtime/layout-placement.test.ts +27 -0
- package/src/app/pane-runtime/layout-placement.ts +13 -0
- package/src/app/pane-runtime/plugin-bindings.ts +62 -0
- package/src/app.tsx +60 -18
- package/src/architecture/browser-entry-graph.test.ts +96 -0
- package/src/brokers/profile-form.test.ts +25 -27
- package/src/brokers/test-broker.ts +68 -0
- package/src/cli/commands/plugins.ts +39 -11
- package/src/cli/desktop-pane-shot.ts +285 -16
- package/src/cli/index.ts +1 -1
- package/src/cli/pane-functions/capabilities.ts +58 -28
- package/src/cli/pane-functions/catalog.ts +16 -4
- package/src/cli/pane-functions/discovery.ts +1 -0
- package/src/cli/pane-functions/headless.test.ts +247 -0
- package/src/cli/pane-functions/headless.ts +423 -0
- package/src/cli/pane-functions/index.test.ts +9 -0
- package/src/cli/pane-functions/index.ts +6 -2
- package/src/cli/pane-functions/options.ts +27 -2
- package/src/cli/pane-functions/report.ts +4 -0
- package/src/cli/pane-functions/resolver.ts +26 -8
- package/src/cli/pane-functions/screenshot.test.ts +76 -0
- package/src/cli/pane-functions/screenshot.ts +236 -20
- package/src/cli/restore-plugins.ts +34 -0
- package/src/components/chart/{static/chart → composite}/axis-overlays.test.tsx +3 -3
- package/src/components/chart/{static/chart → composite}/axis-overlays.tsx +6 -11
- package/src/components/chart/{static/chart → composite}/bitmap.ts +17 -3
- package/src/components/chart/composite/composite-chart.test.tsx +68 -20
- package/src/components/chart/composite/composite-chart.tsx +301 -204
- package/src/components/chart/composite/format.ts +8 -2
- package/src/components/chart/composite/interactions.test.ts +68 -102
- package/src/components/chart/composite/interactions.ts +214 -264
- package/src/components/chart/composite/price-axis-labels.test.ts +21 -0
- package/src/components/chart/{price-axis-labels.tsx → composite/price-axis-labels.tsx} +9 -4
- package/src/components/chart/composite/scene.ts +57 -3
- package/src/components/chart/composite/text-renderer.ts +3 -2
- package/src/components/chart/composite/time-scale.ts +138 -57
- package/src/components/chart/composite/types.ts +25 -1
- package/src/components/chart/core/data.ts +9 -13
- package/src/components/chart/core/date-window.ts +7 -1
- package/src/components/chart/core/pointer.ts +3 -0
- package/src/components/chart/core/types.ts +0 -45
- package/src/components/chart/native/chart-rasterizer.ts +0 -1
- package/src/components/chart/native/kitty/index.test.ts +0 -188
- package/src/components/chart/native/raster/crosshair.ts +6 -5
- package/src/components/chart/native/raster/primitives.ts +0 -23
- package/src/components/chart/native/renderer-selection.ts +81 -31
- package/src/components/chart/static/{chart/surface.test.tsx → chart-surface.test.tsx} +28 -80
- package/src/components/chart/static/chart-surface.tsx +150 -0
- package/src/components/chart/static/index.ts +8 -0
- package/src/components/chart/static/multi-line-chart-surface.tsx +51 -166
- package/src/components/chart/static/scatter-chart-surface.test.ts +30 -0
- package/src/components/chart/static/scatter-chart-surface.tsx +135 -34
- package/src/components/chart/static/series.ts +49 -0
- package/src/components/command-bar/action-runtime.ts +1 -3
- package/src/components/command-bar/assist/model.test.ts +17 -2
- package/src/components/command-bar/assist/model.ts +40 -9
- package/src/components/command-bar/commands/direct/index.ts +1 -1
- package/src/components/command-bar/commands/direct/runtime.ts +1 -1
- package/src/components/command-bar/commands/registry.ts +0 -11
- package/src/components/command-bar/helpers.test.ts +2 -2
- package/src/components/command-bar/helpers.ts +2 -6
- package/src/components/command-bar/keyboard-shortcuts.ts +0 -11
- package/src/components/command-bar/list/badge.test.ts +54 -0
- package/src/components/command-bar/list/badge.ts +62 -0
- package/src/components/command-bar/list/model.test.ts +103 -0
- package/src/components/command-bar/list/model.ts +61 -4
- package/src/components/command-bar/list/view.test.tsx +113 -0
- package/src/components/command-bar/list/view.tsx +147 -131
- package/src/components/command-bar/pane-templates/workflow.ts +1 -1
- package/src/components/command-bar/panel/body.tsx +51 -65
- package/src/components/command-bar/panel/index.tsx +48 -13
- package/src/components/command-bar/panel/layout.test.ts +139 -0
- package/src/components/command-bar/panel/layout.ts +65 -28
- package/src/components/command-bar/panel/native-surface.ts +24 -0
- package/src/components/command-bar/panel/prompt-binding.ts +54 -0
- package/src/components/command-bar/panel/runtime.ts +6 -3
- package/src/components/command-bar/panel/state.ts +41 -7
- package/src/components/command-bar/panel/types.ts +7 -1
- package/src/components/command-bar/routes/root/provider-search.ts +34 -15
- package/src/components/command-bar/routes/root/results.test.ts +161 -0
- package/src/components/command-bar/routes/root/results.ts +30 -28
- package/src/components/command-bar/routes/root/runtime.ts +37 -20
- package/src/components/command-bar/routes/root/search-providers.test.tsx +224 -0
- package/src/components/command-bar/routes/root/search-providers.ts +205 -0
- package/src/components/command-bar/routes/root/selection.ts +1 -12
- package/src/components/command-bar/routes/root/shortcuts.test.ts +8 -8
- package/src/components/command-bar/routes/ticker-search/actions.ts +10 -9
- package/src/components/command-bar/routes/ticker-search/results.test.ts +54 -1
- package/src/components/command-bar/routes/ticker-search/results.ts +60 -19
- package/src/components/command-bar/routes/ticker-search/route.ts +1 -0
- package/src/components/command-bar/routing/actions.ts +1 -81
- package/src/components/command-bar/routing/launch-request.ts +1 -1
- package/src/components/command-bar/routing/list-state.ts +6 -21
- package/src/components/command-bar/selection-runtime.ts +1 -1
- package/src/components/command-bar/surface/assist.test.tsx +14 -10
- package/src/components/command-bar/surface/environment.ts +8 -1
- package/src/components/command-bar/surface/index.test.tsx +84 -68
- package/src/components/command-bar/surface/index.tsx +33 -36
- package/src/components/command-bar/surface/test-harness.tsx +15 -3
- package/src/components/command-bar/theme-picker.tsx +43 -15
- package/src/components/command-bar/view-model.test.ts +53 -8
- package/src/components/command-bar/view-model.ts +43 -14
- package/src/components/command-bar/workflow/tickers.ts +1 -0
- package/src/components/command-bar/workflow/types.ts +1 -1
- package/src/components/data-table/view.test.tsx +45 -6
- package/src/components/data-table/view.tsx +55 -9
- package/src/components/index.ts +10 -2
- package/src/components/input-search-bar.test.tsx +36 -2
- package/src/components/input-search-bar.tsx +18 -1
- package/src/components/layout/header.test.tsx +57 -10
- package/src/components/layout/header.tsx +292 -149
- package/src/components/layout/market-summary.test.ts +81 -0
- package/src/components/layout/market-summary.ts +109 -0
- package/src/components/layout/shell/chrome.ts +96 -1
- package/src/components/layout/shell/index.tsx +11 -3
- package/src/components/layout/shell/menu.ts +9 -0
- package/src/components/layout/shell/pane/actions.ts +29 -0
- package/src/components/layout/shell/pane/management-shortcuts.ts +5 -0
- package/src/components/layout/shell/shortcuts.ts +3 -0
- package/src/components/layout/status-bar.test.tsx +9 -8
- package/src/components/layout/status-bar.tsx +85 -54
- package/src/components/onboarding/onboarding-frame.tsx +2 -26
- package/src/components/price-sparkline/index.ts +61 -34
- package/src/components/price-sparkline/view.tsx +1 -1
- package/src/components/sign-in-gate.test.tsx +128 -0
- package/src/components/sign-in-gate.tsx +149 -0
- package/src/components/speedometer-gauge/desktop.tsx +2 -12
- package/src/components/ticker/badge/list.tsx +17 -3
- package/src/components/ticker/list-table-view.tsx +6 -3
- package/src/components/ui/data-table/index.tsx +3 -2
- package/src/components/ui/data-table/opentui/index.tsx +165 -120
- package/src/components/ui/frame.tsx +28 -0
- package/src/components/ui/index.ts +3 -0
- package/src/components/ui/native-select.tsx +20 -10
- package/src/components/ui/select-button.tsx +138 -0
- package/src/components/ui/status.tsx +2 -2
- package/src/components/ui/table-layout.ts +1 -1
- package/src/components/use-double-click-activation.ts +7 -3
- package/src/core/app-services.ts +3 -3
- package/src/data/config/layout.ts +12 -6
- package/src/data/config/store/index.test.ts +97 -0
- package/src/data/config/store/migrations.ts +41 -0
- package/src/data/config/store/normalize.ts +5 -3
- package/src/i18n/es.ts +6 -2
- package/src/i18n/ja.ts +6 -2
- package/src/i18n/ko.ts +6 -2
- package/src/i18n/zh-cn.ts +6 -2
- package/src/i18n/zh-tw.ts +6 -2
- package/src/layout-marketplace/pane-imagery.ts +1 -0
- package/src/layout-marketplace/payload.test.ts +17 -0
- package/src/layout-marketplace/payload.ts +40 -5
- package/src/market-data/coordinator/index.ts +3 -2
- package/src/market-data/coordinator/quotes.ts +173 -66
- package/src/market-data/coordinator/subscriptions.test.ts +215 -37
- package/src/pane-settings.ts +1 -1
- package/src/plugins/builtin/analytics/pane-model.ts +1 -1
- package/src/plugins/builtin/analytics/view.tsx +1 -1
- package/src/plugins/builtin/broker-manager/index.test.tsx +3 -2
- package/src/plugins/builtin/broker-manager/model.test.ts +2 -2
- package/src/plugins/builtin/chart-composer/catalog-inventory.ts +16 -2
- package/src/plugins/builtin/chart-composer/pane.tsx +22 -8
- package/src/plugins/builtin/chat/content/composer.tsx +8 -4
- package/src/plugins/builtin/cloud/auth-dialog.tsx +14 -228
- package/src/plugins/builtin/cloud/auth-form.tsx +277 -0
- package/src/plugins/builtin/cloud/plugin.tsx +1 -0
- package/src/plugins/builtin/composite-plugins.ts +14 -1
- package/src/plugins/builtin/correlation/relationship/model.ts +1 -1
- package/src/plugins/builtin/correlation/relationship/pane.tsx +2 -6
- package/src/plugins/builtin/correlation/relationship/view-model.ts +2 -2
- package/src/plugins/builtin/credit-conditions/index.test.tsx +12 -6
- package/src/plugins/builtin/credit-conditions/index.tsx +2 -21
- package/src/plugins/builtin/dividend-yield/index.tsx +1 -0
- package/src/plugins/builtin/dividend-yield/pane.tsx +1 -1
- package/src/plugins/builtin/earnings-calls/data.ts +223 -0
- package/src/plugins/builtin/earnings-calls/format.ts +49 -0
- package/src/plugins/builtin/earnings-calls/index.tsx +69 -0
- package/src/plugins/builtin/earnings-calls/pane.tsx +756 -0
- package/src/plugins/builtin/earnings-calls/prose.test.ts +36 -0
- package/src/plugins/builtin/earnings-calls/prose.ts +59 -0
- package/src/plugins/builtin/earnings-calls/transcript-view.tsx +334 -0
- package/src/plugins/builtin/econ/detail-view.tsx +1 -2
- package/src/plugins/builtin/econ/fred-series-map.ts +16 -1
- package/src/plugins/builtin/econ/index.tsx +2 -1
- package/src/plugins/builtin/econ-statistics/cache.ts +4 -0
- package/src/plugins/builtin/econ-statistics/client.ts +92 -0
- package/src/plugins/builtin/econ-statistics/defs.ts +66 -0
- package/src/plugins/builtin/econ-statistics/detail.tsx +154 -0
- package/src/plugins/builtin/econ-statistics/headless.test.ts +54 -0
- package/src/plugins/builtin/econ-statistics/headless.ts +171 -0
- package/src/plugins/builtin/econ-statistics/index.tsx +54 -0
- package/src/plugins/builtin/econ-statistics/pane.tsx +356 -0
- package/src/plugins/builtin/econ-statistics/stats.ts +522 -0
- package/src/plugins/builtin/econ-statistics/transform.test.ts +86 -0
- package/src/plugins/builtin/econ-statistics/transform.ts +85 -0
- package/src/plugins/builtin/econ-statistics/trend.ts +57 -0
- package/src/plugins/builtin/econ-statistics/view.ts +90 -0
- package/src/plugins/builtin/fear-greed/charts.tsx +7 -18
- package/src/plugins/builtin/fear-greed/data.ts +6 -1
- package/src/plugins/builtin/help/index.tsx +4 -0
- package/src/plugins/builtin/holders/index.tsx +1 -0
- package/src/plugins/builtin/insider/index.tsx +1 -0
- package/src/plugins/builtin/kelly-sizer/pane.tsx +1 -1
- package/src/plugins/builtin/kelly-sizer/sections.tsx +2 -3
- package/src/plugins/builtin/market-valuation/align.ts +122 -0
- package/src/plugins/builtin/market-valuation/cache.ts +32 -0
- package/src/plugins/builtin/market-valuation/chart-projection.ts +217 -0
- package/src/plugins/builtin/market-valuation/chart-series.ts +89 -0
- package/src/plugins/builtin/market-valuation/client.test.ts +141 -0
- package/src/plugins/builtin/market-valuation/client.ts +116 -0
- package/src/plugins/builtin/market-valuation/defs.ts +251 -0
- package/src/plugins/builtin/market-valuation/detail.tsx +159 -0
- package/src/plugins/builtin/market-valuation/headless.test.ts +58 -0
- package/src/plugins/builtin/market-valuation/headless.ts +170 -0
- package/src/plugins/builtin/market-valuation/index.tsx +64 -0
- package/src/plugins/builtin/market-valuation/indicators.ts +422 -0
- package/src/plugins/builtin/market-valuation/model.test.ts +350 -0
- package/src/plugins/builtin/market-valuation/model.ts +8 -0
- package/src/plugins/builtin/market-valuation/pane.test.tsx +247 -0
- package/src/plugins/builtin/market-valuation/pane.tsx +344 -0
- package/src/plugins/builtin/market-valuation/series.ts +12 -0
- package/src/plugins/builtin/market-valuation/settings.ts +38 -0
- package/src/plugins/builtin/market-valuation/sources.ts +130 -0
- package/src/plugins/builtin/market-valuation/trend.ts +89 -0
- package/src/plugins/builtin/market-valuation/view.ts +137 -0
- package/src/plugins/builtin/market-valuation/zone-scale/desktop.tsx +123 -0
- package/src/plugins/builtin/market-valuation/zone-scale/index.tsx +12 -0
- package/src/plugins/builtin/market-valuation/zone-scale/model.ts +60 -0
- package/src/plugins/builtin/market-valuation/zone-scale/terminal.tsx +94 -0
- package/src/plugins/builtin/news/wire/breaking/filters.test.ts +99 -0
- package/src/plugins/builtin/news/wire/breaking/filters.ts +110 -0
- package/src/plugins/builtin/news/wire/breaking/notifications.test.ts +157 -53
- package/src/plugins/builtin/news/wire/breaking/notifications.ts +91 -25
- package/src/plugins/builtin/news/wire/index.tsx +31 -44
- package/src/plugins/builtin/options/index.tsx +1 -0
- package/src/plugins/builtin/options/view.test.tsx +29 -1
- package/src/plugins/builtin/options/view.tsx +1 -22
- package/src/plugins/builtin/plugin-marketplace/feed.ts +80 -0
- package/src/plugins/builtin/plugin-marketplace/index.tsx +31 -0
- package/src/plugins/builtin/plugin-marketplace/model.test.ts +200 -0
- package/src/plugins/builtin/plugin-marketplace/model.ts +204 -0
- package/src/plugins/builtin/plugin-marketplace/pane.tsx +385 -0
- package/src/plugins/builtin/plugin-marketplace/store.ts +46 -0
- package/src/plugins/builtin/plugin-module.ts +9 -1
- package/src/plugins/builtin/research/index.tsx +4 -0
- package/src/plugins/builtin/research-search/command-bar-search.test.ts +81 -0
- package/src/plugins/builtin/research-search/command-bar-search.ts +175 -0
- package/src/plugins/builtin/research-search/data.ts +109 -0
- package/src/plugins/builtin/research-search/document-view.test.tsx +75 -0
- package/src/plugins/builtin/research-search/document-view.tsx +254 -0
- package/src/plugins/builtin/research-search/filter-bar.tsx +62 -0
- package/src/plugins/builtin/research-search/focus-handoff.ts +47 -0
- package/src/plugins/builtin/research-search/index.tsx +85 -0
- package/src/plugins/builtin/research-search/model.test.ts +40 -0
- package/src/plugins/builtin/research-search/model.ts +291 -0
- package/src/plugins/builtin/research-search/pane.test.tsx +241 -0
- package/src/plugins/builtin/research-search/pane.tsx +678 -0
- package/src/plugins/builtin/research-search/saved-view.tsx +171 -0
- package/src/plugins/builtin/research-search/snippet-text.tsx +35 -0
- package/src/plugins/builtin/research-search/snippet.test.ts +78 -0
- package/src/plugins/builtin/research-search/snippet.ts +134 -0
- package/src/plugins/builtin/scanner/flow-model.test.ts +11 -1
- package/src/plugins/builtin/scanner/flow-model.ts +29 -1
- package/src/plugins/builtin/scanner/flow-pane.tsx +78 -22
- package/src/plugins/builtin/sec/index.tsx +1 -0
- package/src/plugins/builtin/shared/series-cache.ts +93 -0
- package/src/plugins/builtin/short-interest/index.tsx +1 -0
- package/src/plugins/builtin/short-interest/pane.tsx +1 -1
- package/src/plugins/builtin/thirteenf/index.tsx +1 -0
- package/src/plugins/builtin/ticker-detail/index.tsx +0 -14
- package/src/plugins/builtin/ticker-detail/overview-tab.tsx +1 -1
- package/src/plugins/builtin/volatility/index.tsx +1 -1
- package/src/plugins/builtin/world-venue-map/map.desktop.test.tsx +106 -0
- package/src/plugins/builtin/world-venue-map/map.tsx +213 -69
- package/src/plugins/builtin/world-venue-map/model.test.ts +32 -0
- package/src/plugins/builtin/world-venue-map/model.ts +134 -13
- package/src/plugins/builtin/yield-curve/index.tsx +1 -1
- package/src/plugins/bundle.test.ts +109 -0
- package/src/plugins/bundle.ts +139 -0
- package/src/plugins/catalog-browser.test.ts +1 -0
- package/src/plugins/catalog-browser.ts +10 -0
- package/src/plugins/catalog-manifest.test.ts +43 -0
- package/src/plugins/catalog-manifest.ts +92 -0
- package/src/plugins/catalog-ui.ts +20 -4
- package/src/plugins/catalog.ts +9 -2
- package/src/plugins/current-target.ts +28 -0
- package/src/plugins/host-contract.ts +37 -0
- package/src/plugins/host-link.ts +158 -0
- package/src/plugins/host-modules.ts +61 -0
- package/src/plugins/loader.ts +41 -22
- package/src/plugins/ownership.ts +1 -0
- package/src/plugins/prediction-markets/index.tsx +1 -0
- package/src/plugins/registry/context.ts +3 -0
- package/src/plugins/registry/contributions.ts +27 -0
- package/src/plugins/registry/index.test.ts +25 -0
- package/src/plugins/registry/index.ts +8 -0
- package/src/plugins/registry/pane-settings.ts +6 -13
- package/src/plugins/seed.test.ts +83 -0
- package/src/plugins/seed.ts +80 -0
- package/src/public/broker.ts +31 -0
- package/src/public/market-data.ts +9 -0
- package/src/public/pane-hooks.ts +57 -0
- package/src/public/public-api.test.ts +285 -0
- package/src/public/react.ts +62 -0
- package/src/public/test-support.ts +23 -0
- package/src/public/time-series.ts +8 -0
- package/src/public/utils.ts +77 -0
- package/src/remote/layout-helpers.ts +6 -8
- package/src/remote/resources.ts +2 -0
- package/src/remote/schema.ts +1 -0
- package/src/remote/semantic-tree.test.tsx +105 -0
- package/src/remote/semantic-tree.tsx +53 -35
- package/src/renderers/browser/main.tsx +6 -0
- package/src/renderers/cloudflare/worker.test.ts +19 -0
- package/src/renderers/cloudflare/worker.ts +1 -1
- package/src/renderers/electrobun/bun/external-plugins.ts +140 -0
- package/src/renderers/electrobun/bun/index.ts +5 -2
- package/src/renderers/electrobun/shared/protocol.ts +21 -0
- package/src/renderers/electrobun/view/build-assets.ts +0 -1
- package/src/renderers/electrobun/view/cli-pane-shot-entry.tsx +51 -1
- package/src/renderers/electrobun/view/external-plugins.test.ts +45 -0
- package/src/renderers/electrobun/view/external-plugins.ts +63 -0
- package/src/renderers/electrobun/view/host/ascii-text.test.ts +48 -0
- package/src/renderers/electrobun/view/host/ascii-text.ts +11 -1
- package/src/renderers/electrobun/view/host/chart-surface.tsx +38 -32
- package/src/renderers/electrobun/view/host/mouse.ts +16 -2
- package/src/renderers/electrobun/view/main.tsx +27 -2
- package/src/renderers/electrobun/view/styles.css +5 -0
- package/src/renderers/electrobun/view/toast-host.tsx +18 -0
- package/src/renderers/opentui/chart-surface.tsx +5 -1
- package/src/renderers/opentui/host.tsx +16 -2
- package/src/renderers/opentui/interaction-performance.test.ts +79 -0
- package/src/renderers/opentui/interaction-performance.ts +188 -0
- package/src/renderers/opentui/start.tsx +26 -1
- package/src/renderers/opentui/test-utils.tsx +13 -0
- package/src/renderers/opentui/toast-host.tsx +26 -2
- package/src/renderers/opentui/ui-host.tsx +1 -0
- package/src/sources/provider-router/search.test.ts +191 -0
- package/src/sources/provider-router/search.ts +92 -39
- package/src/state/app/context/index.tsx +2 -0
- package/src/state/app/context/selector.test.tsx +33 -1
- package/src/state/hooks/quote-streaming.test.tsx +93 -0
- package/src/state/hooks/quote-streaming.ts +106 -30
- package/src/state/pane-table-export-registry.ts +19 -0
- package/src/theme/color-utils.ts +1 -1
- package/src/theme/colors.ts +50 -0
- package/src/theme/themes.test.ts +15 -2
- package/src/theme/themes.ts +19 -1
- package/src/tickers/search/index.test.ts +26 -0
- package/src/tickers/search/index.ts +42 -17
- package/src/tickers/search/ranking.ts +14 -0
- package/src/time-series/chart-data.test.ts +216 -0
- package/src/time-series/resolution.test.ts +25 -26
- package/src/time-series/resolution.ts +41 -10
- package/src/time-series/resolve.ts +7 -0
- package/src/time-series/types.ts +3 -1
- package/src/time-series/use-chart-resolution.ts +5 -0
- package/src/types/config.ts +123 -3
- package/src/types/data-provider.ts +11 -0
- package/src/types/headless.ts +161 -0
- package/src/types/plugin.ts +102 -0
- package/src/ui/host.tsx +12 -1
- package/src/ui/index.tsx +1 -0
- package/src/ui/toast.tsx +8 -4
- package/src/utils/format.ts +35 -0
- package/src/utils/fuzzy-search.test.ts +94 -0
- package/src/utils/fuzzy-search.ts +81 -22
- package/src/utils/shortcut-labels.ts +14 -0
- package/src/components/chart/core/axis-format.ts +0 -157
- package/src/components/chart/core/index.test.ts +0 -1075
- package/src/components/chart/core/projection.ts +0 -357
- package/src/components/chart/core/render-utils.ts +0 -4
- package/src/components/chart/core/renderer.ts +0 -244
- package/src/components/chart/core/scene.ts +0 -180
- package/src/components/chart/core/time-axis.ts +0 -330
- package/src/components/chart/cursor-motion.ts +0 -47
- package/src/components/chart/indicators/types.ts +0 -26
- package/src/components/chart/market-session.ts +0 -176
- package/src/components/chart/multi-line/renderer.test.ts +0 -83
- package/src/components/chart/multi-line/renderer.ts +0 -161
- package/src/components/chart/multi-line/scene.ts +0 -188
- package/src/components/chart/native/raster/layout.ts +0 -129
- package/src/components/chart/native/raster/price-chart.ts +0 -244
- package/src/components/chart/rendering/chart-draw.ts +0 -270
- package/src/components/chart/rendering/geometry.ts +0 -95
- package/src/components/chart/rendering/pixel-buffer.ts +0 -267
- package/src/components/chart/scatter-chart-renderer.test.ts +0 -31
- package/src/components/chart/scatter-chart-renderer.ts +0 -223
- package/src/components/chart/static/chart/surface.tsx +0 -358
- package/src/components/command-bar/routes/root/article-results.test.ts +0 -83
- package/src/components/command-bar/routes/root/article-results.ts +0 -55
- package/src/plugins/builtin/news/wire/article-search.test.ts +0 -72
- package/src/plugins/builtin/news/wire/article-search.ts +0 -140
- package/src/plugins/builtin/substack/api/auth.ts +0 -185
- package/src/plugins/builtin/substack/api/cache.ts +0 -82
- package/src/plugins/builtin/substack/api/loaders.ts +0 -170
- package/src/plugins/builtin/substack/api/store.ts +0 -186
- package/src/plugins/builtin/substack/api/types.ts +0 -42
- package/src/plugins/builtin/substack/api.test.ts +0 -298
- package/src/plugins/builtin/substack/article-detail.tsx +0 -397
- package/src/plugins/builtin/substack/article-stack.tsx +0 -133
- package/src/plugins/builtin/substack/content.ts +0 -478
- package/src/plugins/builtin/substack/feed-tabs.tsx +0 -44
- package/src/plugins/builtin/substack/index.tsx +0 -49
- package/src/plugins/builtin/substack/login-view.tsx +0 -126
- package/src/plugins/builtin/substack/model.test.ts +0 -155
- package/src/plugins/builtin/substack/normalize.ts +0 -343
- package/src/plugins/builtin/substack/pane-footer.ts +0 -52
- package/src/plugins/builtin/substack/pane-state.ts +0 -170
- package/src/plugins/builtin/substack/pane.tsx +0 -547
- package/src/plugins/builtin/substack/read-state.ts +0 -30
- package/src/plugins/builtin/substack/table.ts +0 -111
- package/src/plugins/builtin/substack/types.ts +0 -71
- package/src/plugins/builtin/substack/utils.ts +0 -131
- package/src/plugins/builtin/ticker-detail/data-panes/provider-search.tsx +0 -229
- package/src/plugins/ibkr/account-cache.test.ts +0 -102
- package/src/plugins/ibkr/account-cache.ts +0 -24
- package/src/plugins/ibkr/broker-adapter.ts +0 -286
- package/src/plugins/ibkr/config.test.ts +0 -79
- package/src/plugins/ibkr/config.ts +0 -250
- package/src/plugins/ibkr/dialogs.tsx +0 -40
- package/src/plugins/ibkr/flex/index.test.ts +0 -264
- package/src/plugins/ibkr/flex/index.ts +0 -367
- package/src/plugins/ibkr/flex/statement-client.ts +0 -235
- package/src/plugins/ibkr/fundamental-parser.ts +0 -149
- package/src/plugins/ibkr/gateway/account-loaders.ts +0 -266
- package/src/plugins/ibkr/gateway/account-summary.ts +0 -164
- package/src/plugins/ibkr/gateway/client-lock.ts +0 -154
- package/src/plugins/ibkr/gateway/connection-events.ts +0 -114
- package/src/plugins/ibkr/gateway/connection.ts +0 -152
- package/src/plugins/ibkr/gateway/contracts.ts +0 -132
- package/src/plugins/ibkr/gateway/fundamentals.ts +0 -83
- package/src/plugins/ibkr/gateway/helpers.ts +0 -33
- package/src/plugins/ibkr/gateway/history-requests.ts +0 -158
- package/src/plugins/ibkr/gateway/history.ts +0 -120
- package/src/plugins/ibkr/gateway/instrument-lookup.ts +0 -117
- package/src/plugins/ibkr/gateway/market-data.ts +0 -345
- package/src/plugins/ibkr/gateway/order-execution.ts +0 -218
- package/src/plugins/ibkr/gateway/orders.ts +0 -63
- package/src/plugins/ibkr/gateway/price-normalization.test.ts +0 -44
- package/src/plugins/ibkr/gateway/price-normalization.ts +0 -50
- package/src/plugins/ibkr/gateway/quote-stream-controller.ts +0 -203
- package/src/plugins/ibkr/gateway/quote-stream.ts +0 -171
- package/src/plugins/ibkr/gateway/selection.ts +0 -51
- package/src/plugins/ibkr/gateway/service/index.test.ts +0 -675
- package/src/plugins/ibkr/gateway/service/index.ts +0 -429
- package/src/plugins/ibkr/gateway/service/lifecycle.ts +0 -191
- package/src/plugins/ibkr/gateway/service/manager.ts +0 -52
- package/src/plugins/ibkr/gateway/service/market-data.ts +0 -48
- package/src/plugins/ibkr/gateway/service/native-loader.ts +0 -12
- package/src/plugins/ibkr/gateway/service/native.ts +0 -543
- package/src/plugins/ibkr/gateway/timeouts.ts +0 -13
- package/src/plugins/ibkr/gateway/types.ts +0 -27
- package/src/plugins/ibkr/index.test.tsx +0 -162
- package/src/plugins/ibkr/index.tsx +0 -159
- package/src/plugins/ibkr/instance-selection.test.ts +0 -120
- package/src/plugins/ibkr/instance-selection.ts +0 -36
- package/src/plugins/ibkr/portfolio-performance.test.ts +0 -32
- package/src/plugins/ibkr/portfolio-performance.ts +0 -129
- package/src/plugins/ibkr/trade/badge.tsx +0 -28
- package/src/plugins/ibkr/trade/dialogs.tsx +0 -44
- package/src/plugins/ibkr/trade/preview-panel.tsx +0 -130
- package/src/plugins/ibkr/trade/tab/actions.tsx +0 -443
- package/src/plugins/ibkr/trade/tab/field-editors.tsx +0 -79
- package/src/plugins/ibkr/trade/tab/footer.ts +0 -53
- package/src/plugins/ibkr/trade/tab/header.tsx +0 -167
- package/src/plugins/ibkr/trade/tab/index.test.tsx +0 -178
- package/src/plugins/ibkr/trade/tab/index.tsx +0 -298
- package/src/plugins/ibkr/trade/tab/model.ts +0 -159
- package/src/plugins/ibkr/trade/tab/order-request.ts +0 -64
- package/src/plugins/ibkr/trade/tab/shortcuts.ts +0 -89
- package/src/plugins/ibkr/trade/tab/state-sync.ts +0 -86
- package/src/plugins/ibkr/trade/ticket-panel.tsx +0 -301
- package/src/plugins/ibkr/trade/utils.test.ts +0 -175
- package/src/plugins/ibkr/trade/utils.ts +0 -144
- package/src/plugins/ibkr/trading/pane-view.tsx +0 -237
- package/src/plugins/ibkr/trading/pane.tsx +0 -332
- package/src/plugins/ibkr/trading/state.test.ts +0 -109
- package/src/plugins/ibkr/trading/state.ts +0 -335
|
@@ -1,12 +1,16 @@
|
|
|
1
1
|
import { dirname, resolve } from "path";
|
|
2
2
|
import { mkdir } from "fs/promises";
|
|
3
3
|
import type { PaneRuntimeState } from "../../core/state/app/state";
|
|
4
|
-
import { CHART_COMPOSER_PANE_ID } from "../../types/config";
|
|
4
|
+
import { CHART_COMPOSER_PANE_ID, type AppConfig } from "../../types/config";
|
|
5
5
|
import type { OptionsChain, PricePoint, TickerFinancials } from "../../types/financials";
|
|
6
6
|
import type { TickerRecord } from "../../types/ticker";
|
|
7
7
|
import { slugifyName } from "../../utils/slugify";
|
|
8
|
+
import { getTheme, getThemeIds } from "../../theme/themes";
|
|
9
|
+
|
|
10
|
+
const DEFAULT_SHOT_DEVICE_SCALE_FACTOR = 2;
|
|
8
11
|
import {
|
|
9
12
|
renderDesktopPaneScreenshot,
|
|
13
|
+
type DesktopPaneShotApiProxy,
|
|
10
14
|
type DesktopPaneShotPayload,
|
|
11
15
|
type DesktopPaneShotRenderResult,
|
|
12
16
|
} from "../desktop-pane-shot";
|
|
@@ -39,8 +43,16 @@ import {
|
|
|
39
43
|
getVisibleWindowForDateRange,
|
|
40
44
|
} from "../../components/chart/core/date-window";
|
|
41
45
|
import { parseChartSpec } from "../../plugins/builtin/chart-composer/chart-spec";
|
|
46
|
+
import {
|
|
47
|
+
defaultValuationSeriesLoader,
|
|
48
|
+
requiredSeries as valuationRequiredSeries,
|
|
49
|
+
} from "../../plugins/builtin/market-valuation/client";
|
|
50
|
+
import type { DatedObservation } from "../../plugins/builtin/market-valuation/series";
|
|
51
|
+
import { defaultStatLoader } from "../../plugins/builtin/econ-statistics/client";
|
|
52
|
+
import { STATS } from "../../plugins/builtin/econ-statistics/stats";
|
|
42
53
|
import { publicTickerKey } from "../../utils/exchanges";
|
|
43
54
|
import { apiClient } from "../../api-client";
|
|
55
|
+
import { getCloudApiBaseUrl } from "../../api-client/request";
|
|
44
56
|
import type { FredSeriesCacheEntry } from "../../data/fred-series";
|
|
45
57
|
import type { ResolvedSeries } from "../../time-series/types";
|
|
46
58
|
import { chartSeriesSourceKey, createChartSeriesResolver } from "../../capabilities";
|
|
@@ -57,6 +69,102 @@ import {
|
|
|
57
69
|
const DESKTOP_CELL_WIDTH_PX = 8;
|
|
58
70
|
const DESKTOP_CELL_HEIGHT_PX = 18;
|
|
59
71
|
const OPTIONS_PANE_ID = "options";
|
|
72
|
+
const MARKET_VALUATION_PANE_ID = "market-valuation";
|
|
73
|
+
const ECON_STATISTICS_PANE_ID = "econ-statistics";
|
|
74
|
+
const CLOUD_PLUGIN_ID = "gloomberb-cloud";
|
|
75
|
+
const CLOUD_SESSION_KEYS = ["resume:session", "session"] as const;
|
|
76
|
+
const CREDENTIAL_FIELD_NAMES = new Set([
|
|
77
|
+
"accesstoken",
|
|
78
|
+
"accessurl",
|
|
79
|
+
"apikey",
|
|
80
|
+
"apisecret",
|
|
81
|
+
"authorization",
|
|
82
|
+
"cookie",
|
|
83
|
+
"credentials",
|
|
84
|
+
"oauth",
|
|
85
|
+
"passphrase",
|
|
86
|
+
"password",
|
|
87
|
+
"privatekey",
|
|
88
|
+
"refreshtoken",
|
|
89
|
+
"secret",
|
|
90
|
+
"sessiontoken",
|
|
91
|
+
"token",
|
|
92
|
+
]);
|
|
93
|
+
|
|
94
|
+
interface PersistedShotCloudSession {
|
|
95
|
+
sessionToken?: unknown;
|
|
96
|
+
}
|
|
97
|
+
|
|
98
|
+
/**
|
|
99
|
+
* The proxy receives the desktop session out of band. Keeping this separate
|
|
100
|
+
* from DesktopPaneShotPayload prevents the token from entering the page,
|
|
101
|
+
* semantic evidence, or JSON CLI output.
|
|
102
|
+
*/
|
|
103
|
+
function isCredentialField(key: string): boolean {
|
|
104
|
+
const normalized = key.replace(/[^a-z0-9]/gi, "").toLowerCase();
|
|
105
|
+
return CREDENTIAL_FIELD_NAMES.has(normalized)
|
|
106
|
+
|| normalized.endsWith("password")
|
|
107
|
+
|| normalized.endsWith("passphrase")
|
|
108
|
+
|| normalized.endsWith("secret")
|
|
109
|
+
|| normalized.endsWith("token")
|
|
110
|
+
|| normalized.endsWith("credential")
|
|
111
|
+
|| normalized.endsWith("cookie")
|
|
112
|
+
|| normalized.endsWith("apikey")
|
|
113
|
+
|| normalized.endsWith("accesskey")
|
|
114
|
+
|| normalized.endsWith("privatekey")
|
|
115
|
+
|| normalized.endsWith("authorization")
|
|
116
|
+
|| normalized.endsWith("accessurl");
|
|
117
|
+
}
|
|
118
|
+
|
|
119
|
+
/** Removes credential-shaped object fields before data enters the page or JSON output. */
|
|
120
|
+
export function stripDesktopShotCredentials<T>(value: T): T {
|
|
121
|
+
if (Array.isArray(value)) {
|
|
122
|
+
return value.map((entry) => stripDesktopShotCredentials(entry)) as T;
|
|
123
|
+
}
|
|
124
|
+
if (!value || typeof value !== "object" || value instanceof Date) return value;
|
|
125
|
+
const clean: Record<string, unknown> = {};
|
|
126
|
+
for (const [key, entry] of Object.entries(value as Record<string, unknown>)) {
|
|
127
|
+
if (isCredentialField(key)) continue;
|
|
128
|
+
clean[key] = stripDesktopShotCredentials(entry);
|
|
129
|
+
}
|
|
130
|
+
return clean as T;
|
|
131
|
+
}
|
|
132
|
+
|
|
133
|
+
export function resolveDesktopShotApiProxy(
|
|
134
|
+
context: Pick<MarketContext, "persistence">,
|
|
135
|
+
): DesktopPaneShotApiProxy {
|
|
136
|
+
let sessionToken: string | null = null;
|
|
137
|
+
for (const key of CLOUD_SESSION_KEYS) {
|
|
138
|
+
const value = context.persistence.pluginState.get<PersistedShotCloudSession>(
|
|
139
|
+
CLOUD_PLUGIN_ID,
|
|
140
|
+
key,
|
|
141
|
+
1,
|
|
142
|
+
)?.value;
|
|
143
|
+
if (typeof value?.sessionToken === "string" && value.sessionToken.length > 0) {
|
|
144
|
+
sessionToken = value.sessionToken;
|
|
145
|
+
break;
|
|
146
|
+
}
|
|
147
|
+
}
|
|
148
|
+
return {
|
|
149
|
+
baseUrl: getCloudApiBaseUrl(),
|
|
150
|
+
sessionToken,
|
|
151
|
+
};
|
|
152
|
+
}
|
|
153
|
+
|
|
154
|
+
/** Same reason as the valuation legs: the renderer cannot fill its own cache. */
|
|
155
|
+
async function collectShotStatSeries(
|
|
156
|
+
resolved: ResolvedPaneFunction,
|
|
157
|
+
): Promise<Array<[string, DatedObservation[]]>> {
|
|
158
|
+
if (resolved.pane.id !== ECON_STATISTICS_PANE_ID) return [];
|
|
159
|
+
const loaded = await Promise.all(STATS.map(async (def) => {
|
|
160
|
+
try {
|
|
161
|
+
return [def.seriesId, await defaultStatLoader(def)] as [string, DatedObservation[]];
|
|
162
|
+
} catch {
|
|
163
|
+
return null;
|
|
164
|
+
}
|
|
165
|
+
}));
|
|
166
|
+
return loaded.filter((entry): entry is [string, DatedObservation[]] => !!entry);
|
|
167
|
+
}
|
|
60
168
|
|
|
61
169
|
async function collectShotFredSeries(
|
|
62
170
|
resolved: ResolvedPaneFunction,
|
|
@@ -81,6 +189,25 @@ async function collectShotFredSeries(
|
|
|
81
189
|
return loaded.filter((entry): entry is [string, FredSeriesCacheEntry] => !!entry);
|
|
82
190
|
}
|
|
83
191
|
|
|
192
|
+
/**
|
|
193
|
+
* The pane reads its legs from a client cache the shot renderer cannot fill itself,
|
|
194
|
+
* so fetch them here on the Bun side and hand them over with the payload.
|
|
195
|
+
*/
|
|
196
|
+
async function collectShotValuationSeries(
|
|
197
|
+
resolved: ResolvedPaneFunction,
|
|
198
|
+
): Promise<Array<[string, DatedObservation[]]>> {
|
|
199
|
+
if (resolved.pane.id !== MARKET_VALUATION_PANE_ID) return [];
|
|
200
|
+
const loaded = await Promise.all(valuationRequiredSeries().map(async (def) => {
|
|
201
|
+
try {
|
|
202
|
+
const series = await defaultValuationSeriesLoader(def);
|
|
203
|
+
return [def.key, series.observations] as [string, DatedObservation[]];
|
|
204
|
+
} catch {
|
|
205
|
+
return null;
|
|
206
|
+
}
|
|
207
|
+
}));
|
|
208
|
+
return loaded.filter((entry): entry is [string, DatedObservation[]] => !!entry);
|
|
209
|
+
}
|
|
210
|
+
|
|
84
211
|
async function collectShotCapabilitySeries(
|
|
85
212
|
resolved: ResolvedPaneFunction,
|
|
86
213
|
): Promise<Array<[string, ResolvedSeries]>> {
|
|
@@ -196,6 +323,27 @@ export type PaneScreenshotDataEvidence =
|
|
|
196
323
|
| PaneScreenshotFundamentalSeriesEvidence
|
|
197
324
|
| PaneScreenshotFinancialStatementEvidence;
|
|
198
325
|
|
|
326
|
+
export interface PaneScreenshotReadinessSignals {
|
|
327
|
+
rowCount: number;
|
|
328
|
+
loadingStateDetected: boolean;
|
|
329
|
+
errorStateDetected: boolean;
|
|
330
|
+
emptyStateDetected: boolean;
|
|
331
|
+
complete: boolean;
|
|
332
|
+
semanticMismatch: boolean;
|
|
333
|
+
requiresStructuredDataEvidence: boolean;
|
|
334
|
+
hasStructuredDataEvidence: boolean;
|
|
335
|
+
}
|
|
336
|
+
|
|
337
|
+
export function isPaneScreenshotUsable(signals: PaneScreenshotReadinessSignals): boolean {
|
|
338
|
+
return signals.rowCount > 0
|
|
339
|
+
&& !signals.loadingStateDetected
|
|
340
|
+
&& !signals.errorStateDetected
|
|
341
|
+
&& !signals.emptyStateDetected
|
|
342
|
+
&& signals.complete
|
|
343
|
+
&& !signals.semanticMismatch
|
|
344
|
+
&& (!signals.requiresStructuredDataEvidence || signals.hasStructuredDataEvidence);
|
|
345
|
+
}
|
|
346
|
+
|
|
199
347
|
export interface PaneScreenshotResult {
|
|
200
348
|
kind: "pane-screenshot";
|
|
201
349
|
target: string;
|
|
@@ -238,9 +386,20 @@ async function buildDesktopShotPayload(
|
|
|
238
386
|
options: Record<string, string | true>,
|
|
239
387
|
widthPx: number,
|
|
240
388
|
heightPx: number,
|
|
389
|
+
theme: string | null,
|
|
390
|
+
scale: number,
|
|
391
|
+
watermark: string | null,
|
|
241
392
|
): Promise<DesktopPaneShotPayload> {
|
|
242
|
-
|
|
243
|
-
|
|
393
|
+
// The requested size is the output size. Scale shrinks the CSS viewport and
|
|
394
|
+
// raises the device scale factor by the same factor, so a 1200px wide shot at
|
|
395
|
+
// scale 1.5 lays out 100 cells instead of 150 and every glyph is 1.5x larger.
|
|
396
|
+
// Snap to whole cells: rounding up used to make the pane a few pixels taller
|
|
397
|
+
// than the capture, which clipped the bottom axis of charts.
|
|
398
|
+
const widthCells = Math.max(1, Math.floor(widthPx / scale / DESKTOP_CELL_WIDTH_PX));
|
|
399
|
+
const heightCells = Math.max(1, Math.floor(heightPx / scale / DESKTOP_CELL_HEIGHT_PX));
|
|
400
|
+
widthPx = widthCells * DESKTOP_CELL_WIDTH_PX;
|
|
401
|
+
heightPx = heightCells * DESKTOP_CELL_HEIGHT_PX;
|
|
402
|
+
const deviceScaleFactor = DEFAULT_SHOT_DEVICE_SCALE_FACTOR * scale;
|
|
244
403
|
const initialPaneState = optionPaneState(resolved.options);
|
|
245
404
|
const pluginState = capabilityPluginState(resolved.capability, resolved.options);
|
|
246
405
|
if (Object.keys(pluginState).length > 0) {
|
|
@@ -252,9 +411,9 @@ async function buildDesktopShotPayload(
|
|
|
252
411
|
if (isFinancialAnalysisFunction(resolved) && !initialPaneState.activeTabId) {
|
|
253
412
|
initialPaneState.activeTabId = "financials";
|
|
254
413
|
}
|
|
255
|
-
const paneState
|
|
414
|
+
const paneState = stripDesktopShotCredentials<Record<string, PaneRuntimeState>>({
|
|
256
415
|
[resolved.instance.instanceId]: initialPaneState,
|
|
257
|
-
};
|
|
416
|
+
});
|
|
258
417
|
const layout = {
|
|
259
418
|
dockRoot: null,
|
|
260
419
|
instances: [resolved.instance],
|
|
@@ -268,8 +427,9 @@ async function buildDesktopShotPayload(
|
|
|
268
427
|
}],
|
|
269
428
|
detached: [],
|
|
270
429
|
};
|
|
271
|
-
const config = {
|
|
430
|
+
const config = stripDesktopShotCredentials<AppConfig>({
|
|
272
431
|
...context.config,
|
|
432
|
+
...(theme ? { theme: resolveShotTheme(theme) } : {}),
|
|
273
433
|
layout,
|
|
274
434
|
layouts: [{
|
|
275
435
|
name: "CLI Shot",
|
|
@@ -280,14 +440,16 @@ async function buildDesktopShotPayload(
|
|
|
280
440
|
}],
|
|
281
441
|
activeLayoutIndex: 0,
|
|
282
442
|
onboardingComplete: true,
|
|
283
|
-
};
|
|
443
|
+
});
|
|
284
444
|
|
|
285
445
|
const tickers: TickerRecord[] = [];
|
|
286
446
|
const financials: Array<[string, TickerFinancials]> = [];
|
|
287
447
|
const optionsChains: Array<[string, OptionsChain]> = [];
|
|
288
|
-
const [fredSeries, capabilitySeries] = await Promise.all([
|
|
448
|
+
const [fredSeries, capabilitySeries, valuationSeries, statSeries] = await Promise.all([
|
|
289
449
|
collectShotFredSeries(resolved),
|
|
290
450
|
collectShotCapabilitySeries(resolved),
|
|
451
|
+
collectShotValuationSeries(resolved),
|
|
452
|
+
collectShotStatSeries(resolved),
|
|
291
453
|
]);
|
|
292
454
|
const includeOptionsChains = resolved.pane.id === OPTIONS_PANE_ID || resolved.template?.paneId === OPTIONS_PANE_ID;
|
|
293
455
|
for (const symbol of collectShotSymbols(resolved, rawArg)) {
|
|
@@ -327,15 +489,30 @@ async function buildDesktopShotPayload(
|
|
|
327
489
|
heightCells,
|
|
328
490
|
widthPx,
|
|
329
491
|
heightPx,
|
|
492
|
+
deviceScaleFactor,
|
|
493
|
+
watermark,
|
|
330
494
|
tickers,
|
|
331
495
|
financials,
|
|
332
496
|
optionsChains,
|
|
333
497
|
fredSeries,
|
|
498
|
+
valuationSeries,
|
|
499
|
+
statSeries,
|
|
334
500
|
capabilitySeries,
|
|
335
501
|
paneState,
|
|
336
502
|
};
|
|
337
503
|
}
|
|
338
504
|
|
|
505
|
+
function resolveShotTheme(requested: string): string {
|
|
506
|
+
const normalized = requested.trim().toLowerCase().replace(/[\s_]+/g, "-");
|
|
507
|
+
const ids = getThemeIds();
|
|
508
|
+
const match = ids.find((id) => id.toLowerCase() === normalized)
|
|
509
|
+
?? ids.find((id) => getTheme(id).name.toLowerCase().replace(/[\s_]+/g, "-") === normalized);
|
|
510
|
+
if (!match) {
|
|
511
|
+
throw new Error(`Unknown theme "${requested}". Available themes: ${ids.join(", ")}`);
|
|
512
|
+
}
|
|
513
|
+
return match;
|
|
514
|
+
}
|
|
515
|
+
|
|
339
516
|
export function shotPriceHistoryRange(resolved: ResolvedPaneFunction): TimeRange | null {
|
|
340
517
|
switch (resolved.capability.id) {
|
|
341
518
|
case "chart-composer":
|
|
@@ -364,6 +541,9 @@ export async function renderDesktopShot({
|
|
|
364
541
|
outputPath,
|
|
365
542
|
width,
|
|
366
543
|
height,
|
|
544
|
+
theme,
|
|
545
|
+
scale,
|
|
546
|
+
watermark,
|
|
367
547
|
options,
|
|
368
548
|
}: {
|
|
369
549
|
resolved: ResolvedPaneFunction;
|
|
@@ -372,14 +552,41 @@ export async function renderDesktopShot({
|
|
|
372
552
|
outputPath: string;
|
|
373
553
|
width: number;
|
|
374
554
|
height: number;
|
|
555
|
+
theme?: string | null;
|
|
556
|
+
scale?: number;
|
|
557
|
+
watermark?: string | null;
|
|
375
558
|
options: Record<string, string | true>;
|
|
376
559
|
}): Promise<PaneScreenshotResult> {
|
|
377
560
|
await mkdir(dirname(outputPath), { recursive: true });
|
|
378
|
-
const
|
|
379
|
-
const
|
|
561
|
+
const apiProxy = resolveDesktopShotApiProxy(context);
|
|
562
|
+
const previousSessionToken = apiClient.getSessionToken();
|
|
563
|
+
let payload: DesktopPaneShotPayload;
|
|
564
|
+
let render: DesktopPaneShotRenderResult;
|
|
565
|
+
apiClient.setSessionToken(apiProxy.sessionToken);
|
|
566
|
+
try {
|
|
567
|
+
payload = await buildDesktopShotPayload(
|
|
568
|
+
resolved,
|
|
569
|
+
context,
|
|
570
|
+
rawArg,
|
|
571
|
+
options,
|
|
572
|
+
width,
|
|
573
|
+
height,
|
|
574
|
+
theme ?? null,
|
|
575
|
+
scale ?? 1,
|
|
576
|
+
watermark ?? null,
|
|
577
|
+
);
|
|
578
|
+
render = await renderDesktopPaneScreenshot(payload, outputPath, apiProxy);
|
|
579
|
+
} finally {
|
|
580
|
+
apiClient.setSessionToken(previousSessionToken);
|
|
581
|
+
}
|
|
380
582
|
const symbols = payload.financials.map(([symbol]) => symbol);
|
|
381
|
-
const
|
|
382
|
-
const
|
|
583
|
+
const usesLiveDomEvidence = resolved.capability.screenshotReadiness === "live-dom";
|
|
584
|
+
const rowCount = usesLiveDomEvidence
|
|
585
|
+
? render.rows.length
|
|
586
|
+
: shotSemanticRowCount(resolved, payload, render.semanticUi);
|
|
587
|
+
const unavailableSymbols = usesLiveDomEvidence
|
|
588
|
+
? []
|
|
589
|
+
: shotUnavailableSymbols(resolved, payload, render.semanticUi);
|
|
383
590
|
const complete = unavailableSymbols.length === 0;
|
|
384
591
|
const expectedText = shotExpectedText(resolved, symbols, payload);
|
|
385
592
|
const normalizedVisibleText = render.visibleText.toLowerCase();
|
|
@@ -397,12 +604,21 @@ export async function renderDesktopShot({
|
|
|
397
604
|
const semanticMismatch = missingExpectedText.length > 0
|
|
398
605
|
|| missingExpectedSelections.length > 0
|
|
399
606
|
|| chartEvidenceMismatches.length > 0;
|
|
400
|
-
const empty = render.
|
|
401
|
-
|
|
402
|
-
|
|
403
|
-
|
|
404
|
-
|
|
405
|
-
|
|
607
|
+
const empty = render.loadingStateDetected
|
|
608
|
+
|| render.errorStateDetected
|
|
609
|
+
|| render.emptyStateDetected
|
|
610
|
+
|| rowCount === 0
|
|
611
|
+
|| semanticMismatch;
|
|
612
|
+
const usable = isPaneScreenshotUsable({
|
|
613
|
+
rowCount,
|
|
614
|
+
loadingStateDetected: render.loadingStateDetected,
|
|
615
|
+
errorStateDetected: render.errorStateDetected,
|
|
616
|
+
emptyStateDetected: render.emptyStateDetected,
|
|
617
|
+
complete,
|
|
618
|
+
semanticMismatch,
|
|
619
|
+
requiresStructuredDataEvidence: requiresStructuredDataEvidence(resolved),
|
|
620
|
+
hasStructuredDataEvidence: dataEvidence !== null,
|
|
621
|
+
});
|
|
406
622
|
return {
|
|
407
623
|
kind: "pane-screenshot",
|
|
408
624
|
target: resolved.token,
|
|
@@ -414,7 +630,7 @@ export async function renderDesktopShot({
|
|
|
414
630
|
screenshotReadiness: resolved.capability.screenshotReadiness,
|
|
415
631
|
},
|
|
416
632
|
symbols,
|
|
417
|
-
options: resolved.options,
|
|
633
|
+
options: stripDesktopShotCredentials(resolved.options),
|
|
418
634
|
rowCount,
|
|
419
635
|
empty,
|
|
420
636
|
complete,
|
|
@@ -424,7 +640,7 @@ export async function renderDesktopShot({
|
|
|
424
640
|
dataEvidence,
|
|
425
641
|
outputPath,
|
|
426
642
|
render: {
|
|
427
|
-
...render,
|
|
643
|
+
...stripDesktopShotCredentials(render),
|
|
428
644
|
expectedText,
|
|
429
645
|
missingExpectedText,
|
|
430
646
|
expectedSelections,
|
|
@@ -0,0 +1,34 @@
|
|
|
1
|
+
import { saveConfig } from "../data/config/store";
|
|
2
|
+
import { loadCliConfigIfAvailable } from "./context";
|
|
3
|
+
import { seedExtractedPlugins } from "../plugins/seed";
|
|
4
|
+
import { debugLog } from "../utils/debug-log";
|
|
5
|
+
|
|
6
|
+
const log = debugLog.createLogger("plugin-seed");
|
|
7
|
+
|
|
8
|
+
/**
|
|
9
|
+
* Reinstalls plugins that moved out of this repository into their own.
|
|
10
|
+
*
|
|
11
|
+
* Runs before the plugin catalog is read so a restored plugin is available in
|
|
12
|
+
* the same session, and stays quiet on failure: an offline launch should start
|
|
13
|
+
* normally and try again next time, not block on a network request.
|
|
14
|
+
*/
|
|
15
|
+
export async function restoreExtractedPlugins(): Promise<void> {
|
|
16
|
+
try {
|
|
17
|
+
const config = await loadCliConfigIfAvailable();
|
|
18
|
+
// No data directory yet means a first run: there is nothing to restore.
|
|
19
|
+
if (!config) return;
|
|
20
|
+
const { installPlugin } = await import("./commands/plugins");
|
|
21
|
+
const result = await seedExtractedPlugins(config, installPlugin);
|
|
22
|
+
|
|
23
|
+
const seeded = [...new Set(result.seeded)].sort();
|
|
24
|
+
const existing = [...new Set(config.seededPlugins ?? [])].sort();
|
|
25
|
+
if (seeded.join() === existing.join()) return;
|
|
26
|
+
|
|
27
|
+
await saveConfig({ ...config, seededPlugins: seeded });
|
|
28
|
+
if (result.installed.length > 0) {
|
|
29
|
+
log.info(`Restored ${result.installed.join(", ")} into ~/.gloomberb/plugins`);
|
|
30
|
+
}
|
|
31
|
+
} catch (error) {
|
|
32
|
+
log.error(`Plugin restore skipped: ${error}`);
|
|
33
|
+
}
|
|
34
|
+
}
|
|
@@ -4,9 +4,9 @@ import {
|
|
|
4
4
|
UiHostProvider,
|
|
5
5
|
type RendererHost,
|
|
6
6
|
type UiHost,
|
|
7
|
-
} from "
|
|
8
|
-
import { WebBox } from "
|
|
9
|
-
import { WebText } from "
|
|
7
|
+
} from "../../../ui";
|
|
8
|
+
import { WebBox } from "../../../renderers/electrobun/view/host/box";
|
|
9
|
+
import { WebText } from "../../../renderers/electrobun/view/host/text";
|
|
10
10
|
import { StaticXAxisLabels } from "./axis-overlays";
|
|
11
11
|
|
|
12
12
|
const renderer: RendererHost = {
|
|
@@ -1,19 +1,14 @@
|
|
|
1
|
-
import { Box, Text, useUiCapabilities, useUiHost } from "
|
|
1
|
+
import { Box, Text, useUiCapabilities, useUiHost } from "../../../ui";
|
|
2
|
+
import type { CompositeChartXMarker } from "./types";
|
|
2
3
|
|
|
3
|
-
export
|
|
4
|
-
id: string;
|
|
5
|
-
xRatio: number;
|
|
6
|
-
label?: string;
|
|
7
|
-
color?: string;
|
|
8
|
-
lineChar?: string;
|
|
9
|
-
}
|
|
4
|
+
export type StaticChartXMarker = CompositeChartXMarker;
|
|
10
5
|
|
|
11
6
|
export interface StaticChartXAxisLabel {
|
|
12
7
|
label: string;
|
|
13
8
|
ratio: number;
|
|
14
9
|
}
|
|
15
10
|
|
|
16
|
-
|
|
11
|
+
function clampRatio(value: number): number {
|
|
17
12
|
if (!Number.isFinite(value)) return 0;
|
|
18
13
|
return Math.max(0, Math.min(1, value));
|
|
19
14
|
}
|
|
@@ -222,7 +217,7 @@ export function StaticXMarkerOverlay({
|
|
|
222
217
|
height,
|
|
223
218
|
fallbackColor,
|
|
224
219
|
}: {
|
|
225
|
-
markers: StaticChartXMarker[];
|
|
220
|
+
markers: readonly StaticChartXMarker[];
|
|
226
221
|
width: number;
|
|
227
222
|
height: number;
|
|
228
223
|
fallbackColor?: string;
|
|
@@ -288,7 +283,7 @@ export function StaticXMarkerLabels({
|
|
|
288
283
|
width,
|
|
289
284
|
fallbackColor,
|
|
290
285
|
}: {
|
|
291
|
-
markers: StaticChartXMarker[];
|
|
286
|
+
markers: readonly StaticChartXMarker[];
|
|
292
287
|
width: number;
|
|
293
288
|
fallbackColor?: string;
|
|
294
289
|
}) {
|
|
@@ -1,6 +1,9 @@
|
|
|
1
1
|
import { useMemo } from "react";
|
|
2
|
-
import { useNativeRenderer, useUiCapabilities } from "
|
|
3
|
-
import {
|
|
2
|
+
import { useNativeRenderer, useUiCapabilities } from "../../../ui";
|
|
3
|
+
import { useOptionalAppSelector } from "../../../state/app/context";
|
|
4
|
+
import type { ChartRendererPreference } from "../core/types";
|
|
5
|
+
import { resolveNativeBitmapSize, shouldRenderNativeBitmap } from "../native/bitmap-support";
|
|
6
|
+
import { useResolvedChartRendererState } from "../native/renderer-selection";
|
|
4
7
|
|
|
5
8
|
export interface StaticChartBitmapSize {
|
|
6
9
|
pixelWidth: number;
|
|
@@ -16,13 +19,22 @@ export function useStaticChartBitmapSize(width: number, height: number): StaticC
|
|
|
16
19
|
pixelRatio = 1,
|
|
17
20
|
} = useUiCapabilities();
|
|
18
21
|
const nativeRenderer = useNativeRenderer();
|
|
22
|
+
const preferredRenderer = useOptionalAppSelector<ChartRendererPreference | null>(
|
|
23
|
+
(state) => state.config.chartPreferences.renderer,
|
|
24
|
+
null,
|
|
25
|
+
);
|
|
26
|
+
const rendererState = useResolvedChartRendererState(
|
|
27
|
+
nativeCharts === true ? preferredRenderer ?? "auto" : "braille",
|
|
28
|
+
nativeRenderer,
|
|
29
|
+
);
|
|
19
30
|
const rendererCapabilities = nativeRenderer.capabilities;
|
|
20
31
|
const rendererResolution = nativeRenderer.resolution;
|
|
21
32
|
const rendererTerminalWidth = nativeRenderer.terminalWidth;
|
|
22
33
|
const rendererTerminalHeight = nativeRenderer.terminalHeight;
|
|
23
34
|
|
|
24
35
|
return useMemo(() => {
|
|
25
|
-
|
|
36
|
+
const nativeRendererActive = preferredRenderer === null || rendererState.renderer === "kitty";
|
|
37
|
+
if (nativeRendererActive && shouldRenderNativeBitmap(nativeRenderer, nativeCharts === true)) {
|
|
26
38
|
return resolveNativeBitmapSize({
|
|
27
39
|
width,
|
|
28
40
|
height,
|
|
@@ -48,8 +60,10 @@ export function useStaticChartBitmapSize(width: number, height: number): StaticC
|
|
|
48
60
|
nativeCharts,
|
|
49
61
|
nativeRenderer,
|
|
50
62
|
pixelRatio,
|
|
63
|
+
preferredRenderer,
|
|
51
64
|
rendererCapabilities,
|
|
52
65
|
rendererResolution,
|
|
66
|
+
rendererState.renderer,
|
|
53
67
|
rendererTerminalHeight,
|
|
54
68
|
rendererTerminalWidth,
|
|
55
69
|
width,
|