gloomberb 0.9.9 → 0.10.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 +41 -3
- package/README.zh-CN.md +294 -0
- package/package.json +10 -4
- package/patches/@opentui%2Fcore@0.3.2.patch +26 -69
- package/src/api-client/auth.ts +2 -0
- package/src/api-client/index.test.ts +4 -0
- package/src/api-client/types.ts +3 -0
- package/src/app/pane-runtime/pane-settings-runtime.tsx +1 -0
- package/src/app/pane-template-dialog-wizard.test.tsx +36 -0
- package/src/app/pane-template-dialog-wizard.tsx +10 -3
- package/src/app/runtime/desktop-deeplink.test.ts +15 -0
- package/src/app/runtime/desktop-deeplink.ts +21 -6
- package/src/app.tsx +40 -33
- package/src/capabilities/service-capabilities.ts +7 -2
- package/src/cli/commands/automation.test.ts +202 -0
- package/src/cli/commands/automation.ts +153 -36
- package/src/cli/commands/market.ts +1 -14
- package/src/cli/commands/system.ts +4 -1
- package/src/cli/context.ts +1 -1
- package/src/cli/desktop-pane-shot.ts +65 -4
- package/src/cli/entry.ts +1 -1
- package/src/cli/pane-functions/capabilities.ts +532 -0
- package/src/cli/pane-functions/catalog.ts +39 -4
- package/src/cli/pane-functions/data.test.ts +17 -0
- package/src/cli/pane-functions/data.ts +55 -13
- package/src/cli/pane-functions/discovery.ts +36 -9
- package/src/cli/pane-functions/index.test.ts +104 -1
- package/src/cli/pane-functions/index.ts +64 -5
- package/src/cli/pane-functions/options.ts +21 -6
- package/src/cli/pane-functions/report.ts +735 -72
- package/src/cli/pane-functions/resolver.ts +70 -6
- package/src/cli/pane-functions/screenshot.test.ts +431 -0
- package/src/cli/pane-functions/screenshot.ts +952 -8
- package/src/components/chart/composite/column-layout.ts +215 -0
- package/src/components/chart/composite/composite-chart.test.tsx +630 -0
- package/src/components/chart/composite/composite-chart.tsx +1148 -0
- package/src/components/chart/composite/format.test.ts +137 -0
- package/src/components/chart/composite/format.ts +135 -0
- package/src/components/chart/composite/index.ts +38 -0
- package/src/components/chart/composite/interactions.test.ts +109 -0
- package/src/components/chart/composite/interactions.ts +247 -0
- package/src/components/chart/composite/price-series.test.ts +39 -0
- package/src/components/chart/composite/price-series.ts +78 -0
- package/src/components/chart/composite/rasterizer.ts +359 -0
- package/src/components/chart/composite/renderers.test.ts +610 -0
- package/src/components/chart/composite/scene.test.ts +464 -0
- package/src/components/chart/composite/scene.ts +553 -0
- package/src/components/chart/composite/text-renderer.ts +285 -0
- package/src/components/chart/composite/time-scale.test.ts +88 -0
- package/src/components/chart/composite/time-scale.ts +217 -0
- package/src/components/chart/composite/types.ts +141 -0
- package/src/components/chart/core/data.ts +81 -5
- package/src/components/chart/core/index.test.ts +128 -43
- package/src/components/chart/core/resolution.ts +0 -6
- package/src/components/chart/native/chart-rasterizer.ts +1 -3
- package/src/components/chart/native/kitty/index.test.ts +99 -120
- package/src/components/chart/native/kitty/manager.ts +3 -0
- package/src/components/chart/native/kitty/protocol.ts +4 -1
- package/src/components/chart/native/raster/crosshair.ts +79 -46
- package/src/components/chart/native/raster/types.ts +2 -11
- package/src/components/chart/native/surface/manager.ts +48 -3
- package/src/components/chart/price-axis-labels.tsx +18 -4
- package/src/components/command-bar/commands/direct/index.ts +25 -0
- package/src/components/command-bar/commands/registry.ts +9 -0
- package/src/components/command-bar/helpers.test.ts +4 -1
- package/src/components/command-bar/list/view.tsx +18 -6
- package/src/components/command-bar/multi-select-picker.tsx +6 -5
- package/src/components/command-bar/pane-settings.test.ts +141 -0
- package/src/components/command-bar/pane-settings.ts +61 -1
- package/src/components/command-bar/panel/body.tsx +7 -6
- package/src/components/command-bar/routes/root/command-items.ts +4 -4
- package/src/components/command-bar/routes/root/results.ts +10 -1
- package/src/components/command-bar/routes/root/selection.test.ts +54 -0
- package/src/components/command-bar/routes/root/selection.ts +13 -0
- package/src/components/command-bar/routing/actions.ts +18 -2
- package/src/components/command-bar/routing/list-state.ts +2 -1
- package/src/components/command-bar/surface/index.test.tsx +36 -4
- package/src/components/command-bar/surface/pane.test.tsx +93 -0
- package/src/components/command-bar/theme-picker.tsx +2 -1
- package/src/components/command-bar/view-model.ts +19 -20
- package/src/components/command-bar/workflow/body.tsx +2 -1
- package/src/components/command-bar/workflow/field-row.tsx +3 -2
- package/src/components/command-bar/workflow/fields.ts +4 -2
- package/src/components/command-bar/workflow/ops.test.ts +161 -0
- package/src/components/command-bar/workflow/ops.ts +20 -50
- package/src/components/command-bar/workflow/route-actions.test.ts +34 -0
- package/src/components/command-bar/workflow/route-actions.ts +4 -0
- package/src/components/command-bar/workflow/types.ts +1 -0
- package/src/components/feed-data-table/stack-view.tsx +6 -5
- package/src/components/index.ts +13 -1
- package/src/components/layout/detached-pane-shell.tsx +2 -1
- package/src/components/layout/floating-pane.tsx +3 -0
- package/src/components/layout/header.tsx +15 -8
- package/src/components/layout/pane/footer/index.test.tsx +22 -3
- package/src/components/layout/pane/footer/index.tsx +3 -1
- package/src/components/layout/pane/footer/model.ts +9 -2
- package/src/components/layout/pane/header.tsx +4 -6
- package/src/components/layout/pane/index.tsx +3 -0
- package/src/components/layout/pane/sidebar.test.tsx +100 -0
- package/src/components/layout/pane/sidebar.tsx +239 -0
- package/src/components/layout/pane/title.ts +4 -3
- package/src/components/layout/shell/action-menu-overlay.tsx +5 -3
- package/src/components/layout/shell/drag/runtime.ts +2 -0
- package/src/components/layout/shell/menu.test.ts +19 -0
- package/src/components/layout/shell/menu.ts +8 -5
- package/src/components/layout/shell/native/pointer-runtime.ts +4 -1
- package/src/components/layout/shell/pane/layers.tsx +2 -2
- package/src/components/layout/status-bar.tsx +8 -7
- package/src/components/layout/window-controls.tsx +4 -3
- package/src/components/metric-treemap/index.tsx +3 -2
- package/src/components/onboarding/onboarding-steps.tsx +30 -29
- package/src/components/onboarding/onboarding-wizard.tsx +5 -4
- package/src/components/onboarding/portfolio-step/broker-fields-panel.tsx +15 -12
- package/src/components/onboarding/portfolio-step/broker-setup-panel.tsx +17 -16
- package/src/components/onboarding/portfolio-step/broker-sync-panel.tsx +6 -5
- package/src/components/onboarding/portfolio-step/choose-panel.tsx +5 -4
- package/src/components/pane-settings-dialog/desktop.tsx +25 -3
- package/src/components/pane-settings-dialog/field-dialogs.tsx +5 -4
- package/src/components/pane-settings-dialog/tui.tsx +11 -9
- package/src/components/pane-settings-dialog/value.ts +8 -5
- package/src/components/pane-settings-dialog.test.tsx +235 -0
- package/src/components/pane-settings-dialog.tsx +24 -0
- package/src/components/pane-template-wizard.tsx +6 -2
- package/src/components/ticker/list-table-view.tsx +3 -2
- package/src/components/ui/button.tsx +3 -1
- package/src/components/ui/choice-dialog.tsx +6 -1
- package/src/components/ui/confirm-dialog.tsx +3 -2
- package/src/components/ui/fields.tsx +10 -1
- package/src/components/ui/frame.tsx +4 -1
- package/src/components/ui/index.ts +5 -0
- package/src/components/ui/inline-quick-add.tsx +104 -0
- package/src/components/ui/list-view.tsx +5 -4
- package/src/components/ui/loading.tsx +2 -1
- package/src/components/ui/multi-select/dialog.tsx +188 -44
- package/src/components/ui/popover.tsx +10 -0
- package/src/components/ui/shortcut-hint.tsx +2 -0
- package/src/components/ui/status.tsx +4 -3
- package/src/components/ui/tabs.tsx +19 -8
- package/src/components/ui/toggle.tsx +44 -3
- package/src/components/ui/ui.test.tsx +67 -5
- package/src/core/app-services.ts +4 -6
- package/src/core/state/session-persistence.ts +3 -2
- package/src/data/config/chart-settings.ts +712 -0
- package/src/data/config/layout.ts +24 -5
- package/src/data/config/store/index.test.ts +377 -14
- package/src/data/config/store/normalize.ts +79 -65
- package/src/data/fred-series.ts +137 -0
- package/src/i18n/index.test.ts +114 -0
- package/src/i18n/index.ts +147 -0
- package/src/i18n/ja.ts +1013 -0
- package/src/i18n/ko.ts +1011 -0
- package/src/i18n/languages.test.ts +31 -0
- package/src/i18n/languages.ts +72 -0
- package/src/i18n/zh-cn.ts +1013 -0
- package/src/i18n/zh-tw.ts +1013 -0
- package/src/plugins/builtin/account-management/footer.ts +3 -2
- package/src/plugins/builtin/account-management/form-components.tsx +3 -2
- package/src/plugins/builtin/account-management/keyboard.ts +6 -0
- package/src/plugins/builtin/account-management/model.ts +25 -21
- package/src/plugins/builtin/account-management/navigation.test.ts +27 -0
- package/src/plugins/builtin/account-management/navigation.ts +24 -0
- package/src/plugins/builtin/account-management/pane.tsx +120 -85
- package/src/plugins/builtin/account-management/password-dialog.tsx +10 -9
- package/src/plugins/builtin/ai/agent-history.ts +139 -0
- package/src/plugins/builtin/ai/ask-ai-detail-tab.tsx +133 -51
- package/src/plugins/builtin/ai/ask-ai.test.tsx +83 -22
- package/src/plugins/builtin/ai/index.test.ts +302 -0
- package/src/plugins/builtin/ai/index.tsx +374 -40
- package/src/plugins/builtin/ai/pane-settings.test.ts +155 -0
- package/src/plugins/builtin/ai/pane-settings.ts +319 -0
- package/src/plugins/builtin/ai/pi/credential-store.test.ts +80 -0
- package/src/plugins/builtin/ai/pi/credential-store.ts +138 -0
- package/src/plugins/builtin/ai/pi/file-store.ts +138 -0
- package/src/plugins/builtin/ai/pi/host.test.ts +500 -0
- package/src/plugins/builtin/ai/pi/host.ts +564 -0
- package/src/plugins/builtin/ai/pi/index.ts +5 -0
- package/src/plugins/builtin/ai/pi/models-store.test.ts +44 -0
- package/src/plugins/builtin/ai/pi/models-store.ts +141 -0
- package/src/plugins/builtin/ai/pi/providers.ts +68 -0
- package/src/plugins/builtin/ai/pi/runtime.test.ts +240 -0
- package/src/plugins/builtin/ai/pi/runtime.ts +635 -0
- package/src/plugins/builtin/ai/providers.test.ts +68 -0
- package/src/plugins/builtin/ai/providers.ts +163 -38
- package/src/plugins/builtin/ai/runner-selection.test.ts +174 -0
- package/src/plugins/builtin/ai/runner-selection.ts +193 -0
- package/src/plugins/builtin/ai/runner-selector.tsx +153 -0
- package/src/plugins/builtin/ai/runner.test.ts +198 -0
- package/src/plugins/builtin/ai/runner.ts +276 -73
- package/src/plugins/builtin/ai/screener/contract.test.ts +26 -73
- package/src/plugins/builtin/ai/screener/contract.ts +14 -52
- package/src/plugins/builtin/ai/screener/editor-runtime.ts +55 -5
- package/src/plugins/builtin/ai/screener/editor.tsx +42 -36
- package/src/plugins/builtin/ai/screener/footer.ts +82 -67
- package/src/plugins/builtin/ai/screener/keyboard.ts +27 -11
- package/src/plugins/builtin/ai/screener/model.test.ts +24 -0
- package/src/plugins/builtin/ai/screener/model.ts +9 -3
- package/src/plugins/builtin/ai/screener/pane.test.tsx +142 -55
- package/src/plugins/builtin/ai/screener/pane.tsx +95 -97
- package/src/plugins/builtin/ai/screener/results-view.tsx +8 -41
- package/src/plugins/builtin/ai/screener/runner.ts +41 -25
- package/src/plugins/builtin/ai/screener/tabs-bar.tsx +2 -2
- package/src/plugins/builtin/ai/use-runtime-providers.ts +28 -0
- package/src/plugins/builtin/ai/workspace/model.test.ts +227 -0
- package/src/plugins/builtin/ai/workspace/model.ts +308 -0
- package/src/plugins/builtin/ai/workspace/pane.test.tsx +197 -0
- package/src/plugins/builtin/ai/workspace/pane.tsx +896 -0
- package/src/plugins/builtin/analytics/index.test.tsx +3 -3
- package/src/plugins/builtin/analytics/index.tsx +3 -8
- package/src/plugins/builtin/broker-manager/detail.tsx +25 -24
- package/src/plugins/builtin/broker-manager/index.test.tsx +1 -1
- package/src/plugins/builtin/broker-manager/index.tsx +9 -11
- package/src/plugins/builtin/broker-manager/model.ts +11 -10
- package/src/plugins/builtin/broker-manager/pane-actions.tsx +22 -21
- package/src/plugins/builtin/broker-manager/table.ts +9 -8
- package/src/plugins/builtin/changelog/index.tsx +3 -8
- package/src/plugins/builtin/chart-composer/chart-spec.ts +89 -0
- package/src/plugins/builtin/chart-composer/cli-options.ts +98 -0
- package/src/plugins/builtin/chart-composer/date-window-dialog.tsx +120 -0
- package/src/plugins/builtin/chart-composer/editor.test.tsx +332 -0
- package/src/plugins/builtin/chart-composer/editor.tsx +1107 -0
- package/src/plugins/builtin/chart-composer/index.tsx +228 -0
- package/src/plugins/builtin/chart-composer/pane.tsx +645 -0
- package/src/plugins/builtin/chart-composer/presets.test.ts +561 -0
- package/src/plugins/builtin/chart-composer/presets.ts +759 -0
- package/src/plugins/builtin/chart-composer/quick-add.test.tsx +245 -0
- package/src/plugins/builtin/chart-composer/quick-add.tsx +409 -0
- package/src/plugins/builtin/chart-composer/semantic.ts +86 -0
- package/src/plugins/builtin/chart-composer/series-catalog.test.ts +65 -0
- package/src/plugins/builtin/chart-composer/series-catalog.ts +295 -0
- package/src/plugins/builtin/chart-composer/settings.test.ts +163 -0
- package/src/plugins/builtin/chart-composer/settings.ts +397 -0
- package/src/plugins/builtin/chart-composer/shortcuts.test.ts +44 -0
- package/src/plugins/builtin/chart-composer/shortcuts.ts +35 -0
- package/src/plugins/builtin/chart-composer/use-series-catalog.ts +103 -0
- package/src/plugins/builtin/chat/channel-labels.ts +5 -4
- package/src/plugins/builtin/chat/channels.ts +12 -11
- package/src/plugins/builtin/chat/chat.test.tsx +32 -0
- package/src/plugins/builtin/chat/content/composer-runtime.ts +6 -1
- package/src/plugins/builtin/chat/content/composer.tsx +9 -8
- package/src/plugins/builtin/chat/content/index.tsx +36 -1
- package/src/plugins/builtin/chat/content/new-dm-dialog.tsx +8 -7
- package/src/plugins/builtin/chat/content/transcript.tsx +9 -3
- package/src/plugins/builtin/chat/controller/utils.ts +10 -9
- package/src/plugins/builtin/chat/message/desktop.tsx +17 -10
- package/src/plugins/builtin/chat/message/profile-popover.test.tsx +122 -3
- package/src/plugins/builtin/chat/message/profile-popover.tsx +38 -1
- package/src/plugins/builtin/chat/message/terminal.tsx +19 -10
- package/src/plugins/builtin/chat/pane-state.test.ts +31 -0
- package/src/plugins/builtin/chat/pane-state.ts +30 -0
- package/src/plugins/builtin/chat/pane.tsx +27 -4
- package/src/plugins/builtin/chat/profile-popover.ts +62 -5
- package/src/plugins/builtin/chat/sidebar.test.tsx +4 -7
- package/src/plugins/builtin/chat/sidebar.tsx +107 -168
- package/src/plugins/builtin/chat/test-harness.tsx +6 -0
- package/src/plugins/builtin/cloud/auth-actions.tsx +5 -4
- package/src/plugins/builtin/cloud/plugin.tsx +150 -127
- package/src/plugins/builtin/composite-plugins.ts +71 -0
- package/src/plugins/builtin/correlation/index.test.tsx +4 -4
- package/src/plugins/builtin/correlation/index.tsx +3 -8
- package/src/plugins/builtin/earnings/index.tsx +37 -21
- package/src/plugins/builtin/earnings/model.test.ts +52 -0
- package/src/plugins/builtin/earnings/model.ts +32 -0
- package/src/plugins/builtin/econ/detail-view.tsx +17 -4
- package/src/plugins/builtin/econ/fred-cache.test.ts +57 -11
- package/src/plugins/builtin/econ/index.tsx +16 -20
- package/src/plugins/builtin/fear-greed/index.tsx +2 -8
- package/src/plugins/builtin/fx-matrix/index.tsx +3 -8
- package/src/plugins/builtin/help/components.tsx +5 -4
- package/src/plugins/builtin/help/index.tsx +14 -17
- package/src/plugins/builtin/holders/index.tsx +2 -8
- package/src/plugins/builtin/insider/index.tsx +2 -7
- package/src/plugins/builtin/kelly-sizer/index.test.tsx +2 -2
- package/src/plugins/builtin/kelly-sizer/index.tsx +3 -7
- package/src/plugins/builtin/kelly-sizer/test-support.tsx +3 -3
- package/src/plugins/builtin/layout-manager/index.tsx +3 -7
- package/src/plugins/builtin/market-heatmap/index.tsx +3 -8
- package/src/plugins/builtin/market-movers/index.tsx +3 -8
- package/src/plugins/builtin/news/index.tsx +12 -16
- package/src/plugins/builtin/news/wire/breaking/pane.test.tsx +3 -3
- package/src/plugins/builtin/news/wire/index.tsx +83 -73
- package/src/plugins/builtin/options/index.tsx +2 -8
- package/src/plugins/builtin/plugin-module.test.ts +89 -0
- package/src/plugins/builtin/plugin-module.ts +116 -0
- package/src/plugins/builtin/portfolio-list/header.tsx +4 -3
- package/src/plugins/builtin/portfolio-list/index.test.ts +17 -0
- package/src/plugins/builtin/portfolio-list/index.tsx +3 -5
- package/src/plugins/builtin/portfolio-list/pane/index.test.tsx +3 -3
- package/src/plugins/builtin/portfolio-list/quick-add/index.tsx +53 -53
- package/src/plugins/builtin/portfolio-list/settings.ts +5 -3
- package/src/plugins/builtin/portfolio-list/summary/index.tsx +4 -3
- package/src/plugins/builtin/research/index.tsx +2 -8
- package/src/plugins/builtin/sec/index.tsx +2 -8
- package/src/plugins/builtin/sectors/index.tsx +3 -8
- package/src/plugins/builtin/thirteenf/index.tsx +3 -8
- package/src/plugins/builtin/thirteenf/pane.test.tsx +1 -1
- package/src/plugins/builtin/ticker-detail/chart-tab-switch.test.tsx +49 -23
- package/src/plugins/builtin/ticker-detail/index.test.tsx +15 -136
- package/src/plugins/builtin/ticker-detail/index.tsx +2 -93
- package/src/plugins/builtin/ticker-detail/overview/components.tsx +6 -5
- package/src/plugins/builtin/ticker-detail/overview-tab.tsx +41 -17
- package/src/plugins/builtin/ticker-detail/pane.tsx +4 -3
- package/src/plugins/builtin/ticker-detail/quote-monitor/index.test.tsx +1 -1
- package/src/plugins/builtin/ticker-detail/settings.ts +3 -50
- package/src/plugins/builtin/ticker-research-backend-plugin.ts +17 -0
- package/src/plugins/builtin/ticker-research-plugin.ts +27 -0
- package/src/plugins/builtin/tv/channels.ts +27 -0
- package/src/plugins/builtin/tv/index.tsx +40 -0
- package/src/plugins/builtin/tv/pane.tsx +286 -0
- package/src/plugins/builtin/tv/youtube-stream.ts +100 -0
- package/src/plugins/builtin/world-indices/index.tsx +3 -8
- package/src/plugins/builtin/yield-curve/index.tsx +8 -8
- package/src/plugins/catalog-backend.test.ts +21 -0
- package/src/plugins/catalog-backend.ts +42 -0
- package/src/plugins/catalog-ui.ts +6 -14
- package/src/plugins/ibkr/instance-selection.test.ts +0 -1
- package/src/plugins/ownership.ts +143 -0
- package/src/plugins/prediction-markets/backend-plugin.ts +19 -0
- package/src/plugins/prediction-markets/chart.test.tsx +7 -5
- package/src/plugins/prediction-markets/chart.tsx +25 -7
- package/src/plugins/registry/index.test.ts +51 -0
- package/src/plugins/registry/index.ts +8 -0
- package/src/plugins/registry/pane-settings.ts +1 -1
- package/src/plugins/runtime/index.test.tsx +2 -2
- package/src/remote/app-host.tsx +16 -3
- package/src/remote/controller.test.ts +102 -1
- package/src/remote/controller.ts +122 -0
- package/src/remote/types.ts +11 -0
- package/src/renderers/electrobun/bun/core-capabilities.ts +123 -27
- package/src/renderers/electrobun/bun/desktop/backend-requests.ts +5 -1
- package/src/renderers/electrobun/bun/desktop/initialization.ts +5 -1
- package/src/renderers/electrobun/bun/desktop/media.ts +15 -0
- package/src/renderers/electrobun/bun/desktop/window-style.ts +4 -1
- package/src/renderers/electrobun/bun/desktop/workspace/index.test.ts +32 -1
- package/src/renderers/electrobun/bun/desktop/workspace/index.ts +10 -0
- package/src/renderers/electrobun/bun/index.ts +5 -0
- package/src/renderers/electrobun/bun/tui-entry.ts +1 -6
- package/src/renderers/electrobun/view/ai-host.ts +124 -19
- package/src/renderers/electrobun/view/backend-rpc.ts +4 -0
- package/src/renderers/electrobun/view/cli-pane-shot-entry.tsx +151 -39
- package/src/renderers/electrobun/view/desktop/popover.tsx +166 -0
- package/src/renderers/electrobun/view/dialog-host.test.ts +25 -0
- package/src/renderers/electrobun/view/dialog-host.tsx +75 -12
- package/src/renderers/electrobun/view/host/box.tsx +5 -0
- package/src/renderers/electrobun/view/host/chart-surface.tsx +10 -9
- package/src/renderers/electrobun/view/host/input.tsx +9 -19
- package/src/renderers/electrobun/view/host/media-surface.tsx +170 -0
- package/src/renderers/electrobun/view/host/mouse.ts +1 -0
- package/src/renderers/electrobun/view/host/style.ts +1 -1
- package/src/renderers/electrobun/view/host/tabs.tsx +4 -3
- package/src/renderers/electrobun/view/main.tsx +10 -3
- package/src/renderers/electrobun/view/styles.css +17 -0
- package/src/renderers/electrobun/view/ui-host.tsx +7 -0
- package/src/renderers/opentui/chart-surface.test.tsx +52 -6
- package/src/renderers/opentui/chart-surface.tsx +95 -11
- package/src/renderers/opentui/dialog-host.tsx +36 -5
- package/src/renderers/opentui/host.tsx +39 -0
- package/src/renderers/opentui/start.tsx +30 -0
- package/src/renderers/opentui/ui-host.tsx +2 -0
- package/src/sources/provider-router/index.test.ts +43 -0
- package/src/sources/provider-router/index.ts +4 -0
- package/src/sources/provider-router/supplemental.ts +46 -0
- package/src/sources/sec-edgar.test.ts +203 -2
- package/src/sources/sec-edgar.ts +70 -15
- package/src/state/app/context/index.tsx +13 -1
- package/src/state/app/context/selector.test.tsx +62 -1
- package/src/state/session-persistence.test.ts +13 -2
- package/src/sync/controller.test.ts +190 -3
- package/src/sync/controller.ts +76 -45
- package/src/sync/core-contributors.test.ts +121 -0
- package/src/sync/core-contributors.ts +104 -27
- package/src/sync/react.ts +6 -8
- package/src/sync/types.ts +3 -0
- package/src/time-series/alignment.ts +158 -0
- package/src/time-series/economic.ts +49 -0
- package/src/time-series/field-catalog.ts +306 -0
- package/src/time-series/fundamentals.test.ts +505 -0
- package/src/time-series/fundamentals.ts +842 -0
- package/src/time-series/hooks.ts +45 -0
- package/src/time-series/index.ts +14 -0
- package/src/time-series/live-quotes.test.ts +219 -0
- package/src/time-series/live-quotes.ts +203 -0
- package/src/time-series/market-resolution.ts +53 -0
- package/src/time-series/market.ts +125 -0
- package/src/time-series/reporting.ts +98 -0
- package/src/time-series/resolve.test.ts +1281 -0
- package/src/time-series/resolve.ts +783 -0
- package/src/time-series/spec-studies.test.ts +400 -0
- package/src/time-series/spec.ts +487 -0
- package/src/time-series/studies.ts +563 -0
- package/src/time-series/transforms.test.ts +105 -0
- package/src/time-series/transforms.ts +152 -0
- package/src/time-series/types.ts +162 -0
- package/src/time-series/use-chart-resolution.ts +166 -0
- package/src/types/config.ts +9 -11
- package/src/types/desktop-window.ts +1 -0
- package/src/types/financials.ts +4 -0
- package/src/types/media.ts +17 -0
- package/src/types/plugin.ts +32 -1
- package/src/ui/context-menu.tsx +15 -3
- package/src/ui/dialog.tsx +14 -2
- package/src/ui/host.tsx +40 -1
- package/src/ui/index.tsx +9 -0
- package/src/utils/exchanges.test.ts +13 -1
- package/src/utils/exchanges.ts +10 -0
- package/src/utils/financial-statements.test.ts +138 -0
- package/src/utils/financial-statements.ts +115 -8
- package/src/utils/format.test.ts +11 -1
- package/src/utils/format.ts +7 -0
- package/src/version.ts +1 -1
- package/src/components/chart/bar-chart-renderer.test.ts +0 -233
- package/src/components/chart/bar-chart-renderer.ts +0 -445
- package/src/components/chart/comparison/data.test.ts +0 -159
- package/src/components/chart/comparison/data.ts +0 -302
- package/src/components/chart/comparison/renderer.test.ts +0 -187
- package/src/components/chart/comparison/renderer.ts +0 -282
- package/src/components/chart/comparison/scene.ts +0 -178
- package/src/components/chart/comparison-stock-chart/axis-width.ts +0 -99
- package/src/components/chart/comparison-stock-chart/canvas.ts +0 -148
- package/src/components/chart/comparison-stock-chart/controls.ts +0 -252
- package/src/components/chart/comparison-stock-chart/helpers.ts +0 -101
- package/src/components/chart/comparison-stock-chart/interactions.ts +0 -208
- package/src/components/chart/comparison-stock-chart/layout-metrics.ts +0 -62
- package/src/components/chart/comparison-stock-chart/layout.tsx +0 -155
- package/src/components/chart/comparison-stock-chart/legend.tsx +0 -74
- package/src/components/chart/comparison-stock-chart/native-surfaces.ts +0 -89
- package/src/components/chart/comparison-stock-chart/render-data.ts +0 -227
- package/src/components/chart/comparison-stock-chart/render-output.ts +0 -140
- package/src/components/chart/comparison-stock-chart/selection-runtime.ts +0 -128
- package/src/components/chart/comparison-stock-chart/sources.ts +0 -51
- package/src/components/chart/comparison-stock-chart/surface-runtime.ts +0 -159
- package/src/components/chart/comparison-stock-chart/toolbar.tsx +0 -117
- package/src/components/chart/comparison-stock-chart/types.ts +0 -22
- package/src/components/chart/comparison-stock-chart/view.tsx +0 -572
- package/src/components/chart/comparison-stock-chart/viewport-runtime.ts +0 -239
- package/src/components/chart/comparison-stock-chart.tsx +0 -24
- package/src/components/chart/core/axis-measure.ts +0 -33
- package/src/components/chart/core/controller.test.ts +0 -157
- package/src/components/chart/core/controller.ts +0 -349
- package/src/components/chart/core/indicator-selector.tsx +0 -75
- package/src/components/chart/core/keyboard.ts +0 -24
- package/src/components/chart/core/pane-settings.test.ts +0 -52
- package/src/components/chart/core/pane-settings.ts +0 -141
- package/src/components/chart/core/scroll.test.ts +0 -64
- package/src/components/chart/core/scroll.ts +0 -82
- package/src/components/chart/core/window-viewport.test.ts +0 -69
- package/src/components/chart/core/window-viewport.ts +0 -162
- package/src/components/chart/display-cursor.ts +0 -153
- package/src/components/chart/indicators/bands.test.ts +0 -36
- package/src/components/chart/indicators/bands.ts +0 -29
- package/src/components/chart/indicators/moving-averages.test.ts +0 -39
- package/src/components/chart/indicators/moving-averages.ts +0 -42
- package/src/components/chart/indicators/options.test.ts +0 -32
- package/src/components/chart/indicators/options.ts +0 -107
- package/src/components/chart/indicators/oscillators.test.ts +0 -58
- package/src/components/chart/indicators/oscillators.ts +0 -92
- package/src/components/chart/native/canvas-bitmaps.ts +0 -140
- package/src/components/chart/native/raster/comparison-chart.ts +0 -162
- package/src/components/chart/native/surface/hooks.ts +0 -144
- package/src/components/chart/native/surface/rendering.ts +0 -211
- package/src/components/chart/static/bar-chart-surface.test.tsx +0 -101
- package/src/components/chart/static/bar-chart-surface.tsx +0 -292
- package/src/components/chart/stock-chart/auto.ts +0 -216
- package/src/components/chart/stock-chart/axis-width.ts +0 -146
- package/src/components/chart/stock-chart/bitmaps.ts +0 -22
- package/src/components/chart/stock-chart/canvas.ts +0 -202
- package/src/components/chart/stock-chart/controls.tsx +0 -149
- package/src/components/chart/stock-chart/cursor.ts +0 -60
- package/src/components/chart/stock-chart/data-runtime.ts +0 -128
- package/src/components/chart/stock-chart/footer.test.ts +0 -65
- package/src/components/chart/stock-chart/footer.ts +0 -303
- package/src/components/chart/stock-chart/geometry.ts +0 -160
- package/src/components/chart/stock-chart/index.test.ts +0 -532
- package/src/components/chart/stock-chart/index.tsx +0 -29
- package/src/components/chart/stock-chart/indicators.ts +0 -226
- package/src/components/chart/stock-chart/interaction-runtime.ts +0 -44
- package/src/components/chart/stock-chart/interactions.ts +0 -300
- package/src/components/chart/stock-chart/keyboard.ts +0 -373
- package/src/components/chart/stock-chart/layout-metrics.ts +0 -62
- package/src/components/chart/stock-chart/layout.tsx +0 -177
- package/src/components/chart/stock-chart/native-surfaces.ts +0 -121
- package/src/components/chart/stock-chart/presentation.ts +0 -67
- package/src/components/chart/stock-chart/renderer-switch.test.tsx +0 -263
- package/src/components/chart/stock-chart/rendering/bounds.ts +0 -116
- package/src/components/chart/stock-chart/rendering/candidates.ts +0 -145
- package/src/components/chart/stock-chart/rendering/data.ts +0 -370
- package/src/components/chart/stock-chart/rendering/invalidation.ts +0 -68
- package/src/components/chart/stock-chart/rendering/output.ts +0 -304
- package/src/components/chart/stock-chart/rendering/planning.ts +0 -122
- package/src/components/chart/stock-chart/rendering/projection.test.tsx +0 -98
- package/src/components/chart/stock-chart/rendering/projection.ts +0 -112
- package/src/components/chart/stock-chart/rendering/state.test.ts +0 -70
- package/src/components/chart/stock-chart/rendering/state.ts +0 -283
- package/src/components/chart/stock-chart/requests.ts +0 -337
- package/src/components/chart/stock-chart/resolution-support.ts +0 -96
- package/src/components/chart/stock-chart/resolved/runtime.ts +0 -289
- package/src/components/chart/stock-chart/resolved.tsx +0 -359
- package/src/components/chart/stock-chart/settings.ts +0 -81
- package/src/components/chart/stock-chart/surface-runtime.ts +0 -62
- package/src/components/chart/stock-chart/types.ts +0 -25
- package/src/components/chart/stock-chart/view.tsx +0 -155
- package/src/components/chart/stock-chart/viewport/effects.ts +0 -293
- package/src/components/chart/stock-chart/viewport/index.ts +0 -144
- package/src/components/chart/stock-chart/viewport/runtime.ts +0 -375
- package/src/components/chart/time-axis-label.tsx +0 -175
- package/src/plugins/builtin/ai/gloomberb-cli.ts +0 -71
- package/src/plugins/builtin/ai/screener/action-bar.tsx +0 -58
- package/src/plugins/builtin/comparison-chart/index.test.tsx +0 -848
- package/src/plugins/builtin/comparison-chart/index.tsx +0 -194
- package/src/plugins/builtin/econ/fred-cache.ts +0 -106
- package/src/plugins/builtin/plugin-groups.ts +0 -130
- package/src/plugins/builtin/ticker-detail/chart-pane.tsx +0 -91
- package/src/plugins/builtin/ticker-detail/chart-tab.tsx +0 -100
- package/src/plugins/builtin/ticker-detail/data-panes/fundamental-graph/content.tsx +0 -296
- package/src/plugins/builtin/ticker-detail/data-panes/fundamental-graph/data.ts +0 -62
- package/src/plugins/builtin/ticker-detail/data-panes/fundamental-graph/model.ts +0 -608
- package/src/plugins/builtin/ticker-detail/data-panes/fundamental-graph/settings.ts +0 -65
- package/src/plugins/builtin/ticker-detail/data-panes/fundamental-graph/types.ts +0 -58
- package/src/plugins/builtin/ticker-detail/data-panes/fundamental-graph.tsx +0 -138
- package/src/plugins/builtin/ticker-detail/data-panes.test.ts +0 -220
|
@@ -0,0 +1,532 @@
|
|
|
1
|
+
import type { PaneDef, PaneTemplateDef } from "../../types/plugin";
|
|
2
|
+
|
|
3
|
+
export type PaneFunctionReadiness = "ready" | "partial" | "unsupported";
|
|
4
|
+
export type PaneFunctionTickerCardinality = "none" | "one" | "one-or-more" | "two-or-more" | "one-or-two";
|
|
5
|
+
export type PaneFunctionOptionType = "enum" | "integer" | "string" | "boolean";
|
|
6
|
+
export type NormalizedPaneFunctionOptions = Record<string, string | number | boolean>;
|
|
7
|
+
|
|
8
|
+
export interface PaneFunctionOptionValue {
|
|
9
|
+
value: string;
|
|
10
|
+
aliases?: string[];
|
|
11
|
+
}
|
|
12
|
+
|
|
13
|
+
export interface PaneFunctionOptionDef {
|
|
14
|
+
key: string;
|
|
15
|
+
description: string;
|
|
16
|
+
type: PaneFunctionOptionType;
|
|
17
|
+
aliases?: string[];
|
|
18
|
+
values?: PaneFunctionOptionValue[];
|
|
19
|
+
defaultValue?: string | number | boolean;
|
|
20
|
+
minimum?: number;
|
|
21
|
+
maximum?: number;
|
|
22
|
+
settingKey?: string;
|
|
23
|
+
pluginState?: {
|
|
24
|
+
pluginId: string;
|
|
25
|
+
key?: string;
|
|
26
|
+
};
|
|
27
|
+
}
|
|
28
|
+
|
|
29
|
+
export interface PaneFunctionCapability {
|
|
30
|
+
id: string;
|
|
31
|
+
botSafe: boolean;
|
|
32
|
+
tickerCardinality: PaneFunctionTickerCardinality;
|
|
33
|
+
aliases: string[];
|
|
34
|
+
intents: string[];
|
|
35
|
+
outputKind: string;
|
|
36
|
+
reportReadiness: PaneFunctionReadiness;
|
|
37
|
+
screenshotReadiness: PaneFunctionReadiness;
|
|
38
|
+
dataRequirements: string[];
|
|
39
|
+
limitations: string[];
|
|
40
|
+
options: PaneFunctionOptionDef[];
|
|
41
|
+
}
|
|
42
|
+
|
|
43
|
+
const PERIOD_OPTION: PaneFunctionOptionDef = {
|
|
44
|
+
key: "period",
|
|
45
|
+
description: "Financial reporting period.",
|
|
46
|
+
type: "enum",
|
|
47
|
+
aliases: ["financialPeriod"],
|
|
48
|
+
values: [
|
|
49
|
+
{ value: "annual", aliases: ["a", "ann", "year", "yearly", "fy"] },
|
|
50
|
+
{ value: "quarterly", aliases: ["q", "qtr", "quarter"] },
|
|
51
|
+
],
|
|
52
|
+
defaultValue: "annual",
|
|
53
|
+
};
|
|
54
|
+
|
|
55
|
+
const GRAPH_PERIOD_OPTION: PaneFunctionOptionDef = {
|
|
56
|
+
...PERIOD_OPTION,
|
|
57
|
+
};
|
|
58
|
+
|
|
59
|
+
const GRAPH_PERIOD_COUNT_OPTION: PaneFunctionOptionDef = {
|
|
60
|
+
key: "periods",
|
|
61
|
+
description: "Keep only the latest N annual or quarterly observations per ticker.",
|
|
62
|
+
type: "integer",
|
|
63
|
+
aliases: ["years", "limit"],
|
|
64
|
+
minimum: 1,
|
|
65
|
+
maximum: 40,
|
|
66
|
+
};
|
|
67
|
+
|
|
68
|
+
const RANGE_VALUES: PaneFunctionOptionValue[] = [
|
|
69
|
+
{ value: "1D", aliases: ["day", "daily"] },
|
|
70
|
+
{ value: "1W", aliases: ["week", "weekly"] },
|
|
71
|
+
{ value: "1M", aliases: ["month", "monthly"] },
|
|
72
|
+
{ value: "3M" },
|
|
73
|
+
{ value: "6M" },
|
|
74
|
+
{ value: "1Y", aliases: ["year"] },
|
|
75
|
+
{ value: "5Y", aliases: ["five-years", "five years"] },
|
|
76
|
+
{ value: "ALL", aliases: ["max", "maximum"] },
|
|
77
|
+
];
|
|
78
|
+
|
|
79
|
+
const FUNDAMENTAL_METRIC_VALUES: PaneFunctionOptionValue[] = [
|
|
80
|
+
{ value: "totalRevenue", aliases: ["revenue", "sales"] },
|
|
81
|
+
{ value: "grossProfit", aliases: ["gross profit"] },
|
|
82
|
+
{ value: "grossMargin", aliases: ["gross margin"] },
|
|
83
|
+
{ value: "operatingIncome", aliases: ["operating income", "ebit"] },
|
|
84
|
+
{ value: "operatingMargin", aliases: ["operating margin"] },
|
|
85
|
+
{ value: "netIncome", aliases: ["net income", "profit", "earnings"] },
|
|
86
|
+
{ value: "netMargin", aliases: ["net margin", "profit margin"] },
|
|
87
|
+
{ value: "operatingCashFlow", aliases: ["operating cash flow", "cash flow", "ocf"] },
|
|
88
|
+
{ value: "freeCashFlow", aliases: ["free cash flow", "fcf"] },
|
|
89
|
+
{ value: "freeCashFlowMargin", aliases: ["free cash flow margin", "fcf margin"] },
|
|
90
|
+
{ value: "totalAssets", aliases: ["assets", "total assets"] },
|
|
91
|
+
{ value: "totalDebt", aliases: ["debt", "total debt"] },
|
|
92
|
+
{ value: "totalEquity", aliases: ["equity", "book value"] },
|
|
93
|
+
{ value: "eps", aliases: ["earnings per share"] },
|
|
94
|
+
];
|
|
95
|
+
|
|
96
|
+
const VALUATION_METRIC_VALUES: PaneFunctionOptionValue[] = [
|
|
97
|
+
{ value: "trailingPE", aliases: ["pe", "p/e", "trailing pe"] },
|
|
98
|
+
{ value: "forwardPE", aliases: ["forward pe", "forward p/e"] },
|
|
99
|
+
{ value: "pegRatio", aliases: ["peg", "peg ratio"] },
|
|
100
|
+
{ value: "priceSales", aliases: ["price sales", "price to sales", "p/s"] },
|
|
101
|
+
{ value: "evSales", aliases: ["ev sales", "ev/sales"] },
|
|
102
|
+
{ value: "evEbitda", aliases: ["ev ebitda", "ev/ebitda"] },
|
|
103
|
+
{ value: "priceFcf", aliases: ["price fcf", "price to free cash flow", "p/fcf"] },
|
|
104
|
+
];
|
|
105
|
+
|
|
106
|
+
const CAPABILITIES: Record<string, PaneFunctionCapability> = {
|
|
107
|
+
"chart-composer-pane": {
|
|
108
|
+
id: "chart-composer",
|
|
109
|
+
botSafe: true,
|
|
110
|
+
tickerCardinality: "none",
|
|
111
|
+
aliases: ["custom chart", "mixed series chart", "chart composer", "economic chart"],
|
|
112
|
+
intents: ["chart arbitrary market fundamental valuation and economic series together"],
|
|
113
|
+
outputKind: "chart-series",
|
|
114
|
+
reportReadiness: "ready",
|
|
115
|
+
screenshotReadiness: "ready",
|
|
116
|
+
dataRequirements: ["data required by each authored chart series"],
|
|
117
|
+
limitations: ["FRED observations do not include historical vintage availability dates."],
|
|
118
|
+
options: [
|
|
119
|
+
{
|
|
120
|
+
key: "rangePreset",
|
|
121
|
+
description: "Chart history window.",
|
|
122
|
+
type: "enum",
|
|
123
|
+
aliases: ["range"],
|
|
124
|
+
values: RANGE_VALUES,
|
|
125
|
+
},
|
|
126
|
+
{
|
|
127
|
+
key: "chartResolution",
|
|
128
|
+
description: "Market-price sampling resolution.",
|
|
129
|
+
type: "enum",
|
|
130
|
+
aliases: ["resolution"],
|
|
131
|
+
values: ["auto", "1m", "5m", "15m", "30m", "45m", "1h", "1d", "1wk", "1mo"]
|
|
132
|
+
.map((value) => ({ value })),
|
|
133
|
+
},
|
|
134
|
+
],
|
|
135
|
+
},
|
|
136
|
+
"financial-analysis-pane": {
|
|
137
|
+
id: "financial-statements",
|
|
138
|
+
botSafe: true,
|
|
139
|
+
tickerCardinality: "one",
|
|
140
|
+
aliases: ["financials", "financial statement", "income statement", "balance sheet", "cash flow statement"],
|
|
141
|
+
intents: ["inspect company financial statements", "review income balance sheet or cash flow"],
|
|
142
|
+
outputKind: "financial-statement",
|
|
143
|
+
reportReadiness: "ready",
|
|
144
|
+
screenshotReadiness: "ready",
|
|
145
|
+
dataRequirements: ["ticker financial statements"],
|
|
146
|
+
limitations: ["One company per invocation; use GF for cross-company metric comparisons."],
|
|
147
|
+
options: [
|
|
148
|
+
PERIOD_OPTION,
|
|
149
|
+
{
|
|
150
|
+
key: "statement",
|
|
151
|
+
description: "Statement to display.",
|
|
152
|
+
type: "enum",
|
|
153
|
+
aliases: ["tab", "financialStatement"],
|
|
154
|
+
values: [
|
|
155
|
+
{ value: "income", aliases: ["income statement", "is"] },
|
|
156
|
+
{ value: "balance", aliases: ["balance sheet", "bs"] },
|
|
157
|
+
{ value: "cashflow", aliases: ["cash flow", "cash flow statement", "cf", "cashflows"] },
|
|
158
|
+
],
|
|
159
|
+
defaultValue: "income",
|
|
160
|
+
},
|
|
161
|
+
],
|
|
162
|
+
},
|
|
163
|
+
"fundamental-graph-pane": {
|
|
164
|
+
id: "fundamental-series",
|
|
165
|
+
botSafe: true,
|
|
166
|
+
tickerCardinality: "one-or-more",
|
|
167
|
+
aliases: [
|
|
168
|
+
"fundamental comparison",
|
|
169
|
+
"financial metric comparison",
|
|
170
|
+
"cash flow comparison",
|
|
171
|
+
"revenue comparison",
|
|
172
|
+
"earnings comparison",
|
|
173
|
+
"operating cash flow",
|
|
174
|
+
"free cash flow",
|
|
175
|
+
"fcf",
|
|
176
|
+
"ocf",
|
|
177
|
+
],
|
|
178
|
+
intents: ["compare company fundamentals over time", "compare cash flow revenue earnings margins assets debt or equity"],
|
|
179
|
+
outputKind: "fundamental-series",
|
|
180
|
+
reportReadiness: "ready",
|
|
181
|
+
screenshotReadiness: "ready",
|
|
182
|
+
dataRequirements: ["ticker annual or quarterly financial statements"],
|
|
183
|
+
limitations: ["One metric per invocation; run twice when both operating and free cash flow are requested."],
|
|
184
|
+
options: [
|
|
185
|
+
{
|
|
186
|
+
key: "metric",
|
|
187
|
+
description: "Fundamental metric to compare.",
|
|
188
|
+
type: "enum",
|
|
189
|
+
values: FUNDAMENTAL_METRIC_VALUES,
|
|
190
|
+
defaultValue: "totalRevenue",
|
|
191
|
+
},
|
|
192
|
+
GRAPH_PERIOD_OPTION,
|
|
193
|
+
GRAPH_PERIOD_COUNT_OPTION,
|
|
194
|
+
],
|
|
195
|
+
},
|
|
196
|
+
"valuation-graph-pane": {
|
|
197
|
+
id: "valuation-series",
|
|
198
|
+
botSafe: true,
|
|
199
|
+
tickerCardinality: "one-or-more",
|
|
200
|
+
aliases: ["valuation comparison", "multiple comparison", "pe comparison", "price to sales comparison", "ev ebitda"],
|
|
201
|
+
intents: ["compare company valuation multiples over time"],
|
|
202
|
+
outputKind: "valuation-series",
|
|
203
|
+
reportReadiness: "ready",
|
|
204
|
+
screenshotReadiness: "ready",
|
|
205
|
+
dataRequirements: ["ticker financial statements", "price history"],
|
|
206
|
+
limitations: ["Historical multiples require usable prices and statement share counts."],
|
|
207
|
+
options: [
|
|
208
|
+
{
|
|
209
|
+
key: "metric",
|
|
210
|
+
description: "Valuation metric to compare.",
|
|
211
|
+
type: "enum",
|
|
212
|
+
values: VALUATION_METRIC_VALUES,
|
|
213
|
+
defaultValue: "priceSales",
|
|
214
|
+
},
|
|
215
|
+
GRAPH_PERIOD_OPTION,
|
|
216
|
+
GRAPH_PERIOD_COUNT_OPTION,
|
|
217
|
+
],
|
|
218
|
+
},
|
|
219
|
+
"comparison-chart-pane": {
|
|
220
|
+
id: "price-comparison",
|
|
221
|
+
botSafe: true,
|
|
222
|
+
tickerCardinality: "two-or-more",
|
|
223
|
+
aliases: ["stock comparison", "price performance comparison", "returns comparison", "compare stock prices"],
|
|
224
|
+
intents: ["compare market price performance for multiple securities"],
|
|
225
|
+
outputKind: "price-performance",
|
|
226
|
+
reportReadiness: "ready",
|
|
227
|
+
screenshotReadiness: "ready",
|
|
228
|
+
dataRequirements: ["price history"],
|
|
229
|
+
limitations: ["Compares market prices or percentage returns, never company financial statements."],
|
|
230
|
+
options: [
|
|
231
|
+
{
|
|
232
|
+
key: "rangePreset",
|
|
233
|
+
description: "Price-history window.",
|
|
234
|
+
type: "enum",
|
|
235
|
+
aliases: ["range"],
|
|
236
|
+
values: RANGE_VALUES,
|
|
237
|
+
defaultValue: "1Y",
|
|
238
|
+
},
|
|
239
|
+
{
|
|
240
|
+
key: "axisMode",
|
|
241
|
+
description: "Display raw price or normalized percentage performance.",
|
|
242
|
+
type: "enum",
|
|
243
|
+
values: [
|
|
244
|
+
{ value: "percent", aliases: ["return", "returns", "performance"] },
|
|
245
|
+
{ value: "price", aliases: ["prices"] },
|
|
246
|
+
],
|
|
247
|
+
defaultValue: "percent",
|
|
248
|
+
},
|
|
249
|
+
{
|
|
250
|
+
key: "chartResolution",
|
|
251
|
+
description: "Price sampling resolution.",
|
|
252
|
+
type: "enum",
|
|
253
|
+
aliases: ["resolution"],
|
|
254
|
+
values: ["1m", "5m", "15m", "30m", "45m", "1h", "1d", "1wk", "1mo"].map((value) => ({ value })),
|
|
255
|
+
defaultValue: "1d",
|
|
256
|
+
},
|
|
257
|
+
],
|
|
258
|
+
},
|
|
259
|
+
"correlation-pane": {
|
|
260
|
+
id: "return-correlation",
|
|
261
|
+
botSafe: true,
|
|
262
|
+
tickerCardinality: "two-or-more",
|
|
263
|
+
aliases: ["correlation", "return correlation", "correlation matrix", "pearson correlation"],
|
|
264
|
+
intents: ["compare correlations between security returns"],
|
|
265
|
+
outputKind: "correlation-matrix",
|
|
266
|
+
reportReadiness: "ready",
|
|
267
|
+
screenshotReadiness: "partial",
|
|
268
|
+
dataRequirements: ["date-aligned price history"],
|
|
269
|
+
limitations: ["Correlation is computed from daily returns with at least five shared observations."],
|
|
270
|
+
options: [{
|
|
271
|
+
key: "rangePreset",
|
|
272
|
+
description: "Correlation history window.",
|
|
273
|
+
type: "enum",
|
|
274
|
+
aliases: ["range"],
|
|
275
|
+
values: RANGE_VALUES.filter(({ value }) => !["1D", "1W", "ALL"].includes(value)),
|
|
276
|
+
defaultValue: "1Y",
|
|
277
|
+
settingKey: "rangePreset",
|
|
278
|
+
}],
|
|
279
|
+
},
|
|
280
|
+
"relationship-graph-pane": {
|
|
281
|
+
id: "security-relationship",
|
|
282
|
+
botSafe: true,
|
|
283
|
+
tickerCardinality: "one-or-two",
|
|
284
|
+
aliases: ["relationship", "ratio", "beta", "regression", "rolling correlation"],
|
|
285
|
+
intents: ["analyze ratio correlation and regression between two securities"],
|
|
286
|
+
outputKind: "relationship-analysis",
|
|
287
|
+
reportReadiness: "ready",
|
|
288
|
+
screenshotReadiness: "partial",
|
|
289
|
+
dataRequirements: ["date-aligned price history"],
|
|
290
|
+
limitations: ["A single ticker is compared with SPY."],
|
|
291
|
+
options: [
|
|
292
|
+
{
|
|
293
|
+
key: "range",
|
|
294
|
+
description: "Relationship history window.",
|
|
295
|
+
type: "enum",
|
|
296
|
+
aliases: ["rangePreset"],
|
|
297
|
+
values: RANGE_VALUES.filter(({ value }) => !["1D", "1W"].includes(value)),
|
|
298
|
+
defaultValue: "1Y",
|
|
299
|
+
pluginState: { pluginId: "market-overview" },
|
|
300
|
+
},
|
|
301
|
+
{
|
|
302
|
+
key: "correlationWindow",
|
|
303
|
+
description: "Rolling-correlation window in observations.",
|
|
304
|
+
type: "integer",
|
|
305
|
+
aliases: ["window"],
|
|
306
|
+
defaultValue: 120,
|
|
307
|
+
minimum: 5,
|
|
308
|
+
maximum: 1000,
|
|
309
|
+
pluginState: { pluginId: "market-overview" },
|
|
310
|
+
},
|
|
311
|
+
],
|
|
312
|
+
},
|
|
313
|
+
"relative-valuation-pane": {
|
|
314
|
+
id: "relative-valuation",
|
|
315
|
+
botSafe: true,
|
|
316
|
+
tickerCardinality: "one-or-more",
|
|
317
|
+
aliases: ["relative valuation", "peer valuation", "valuation comps", "compare multiples"],
|
|
318
|
+
intents: ["compare current valuation and operating metrics across peers"],
|
|
319
|
+
outputKind: "relative-valuation",
|
|
320
|
+
reportReadiness: "ready",
|
|
321
|
+
screenshotReadiness: "partial",
|
|
322
|
+
dataRequirements: ["ticker quote and fundamentals"],
|
|
323
|
+
limitations: ["Uses current provider fundamentals rather than a historical series."],
|
|
324
|
+
options: [],
|
|
325
|
+
},
|
|
326
|
+
"quote-monitor-pane": {
|
|
327
|
+
id: "quote-comparison",
|
|
328
|
+
botSafe: true,
|
|
329
|
+
tickerCardinality: "one-or-more",
|
|
330
|
+
aliases: ["quotes", "stock prices", "market snapshot", "price comparison"],
|
|
331
|
+
intents: ["compare current quotes for one or more securities"],
|
|
332
|
+
outputKind: "quote-comparison",
|
|
333
|
+
reportReadiness: "ready",
|
|
334
|
+
screenshotReadiness: "ready",
|
|
335
|
+
dataRequirements: ["current quotes"],
|
|
336
|
+
limitations: [],
|
|
337
|
+
options: [],
|
|
338
|
+
},
|
|
339
|
+
"historical-prices-pane": {
|
|
340
|
+
id: "historical-prices",
|
|
341
|
+
botSafe: true,
|
|
342
|
+
tickerCardinality: "one",
|
|
343
|
+
aliases: ["historical prices", "price history", "ohlcv", "daily prices"],
|
|
344
|
+
intents: ["inspect historical open high low close and volume"],
|
|
345
|
+
outputKind: "price-history",
|
|
346
|
+
reportReadiness: "ready",
|
|
347
|
+
screenshotReadiness: "partial",
|
|
348
|
+
dataRequirements: ["price history"],
|
|
349
|
+
limitations: [],
|
|
350
|
+
options: [{
|
|
351
|
+
key: "range",
|
|
352
|
+
description: "Price-history window.",
|
|
353
|
+
type: "enum",
|
|
354
|
+
aliases: ["rangePreset"],
|
|
355
|
+
values: RANGE_VALUES,
|
|
356
|
+
defaultValue: "ALL",
|
|
357
|
+
pluginState: { pluginId: "ticker-research" },
|
|
358
|
+
}],
|
|
359
|
+
},
|
|
360
|
+
"graph-price-pane": {
|
|
361
|
+
id: "price-chart",
|
|
362
|
+
botSafe: true,
|
|
363
|
+
tickerCardinality: "one",
|
|
364
|
+
aliases: ["price chart", "stock chart", "historical chart"],
|
|
365
|
+
intents: ["chart a security price over time"],
|
|
366
|
+
outputKind: "price-history",
|
|
367
|
+
reportReadiness: "ready",
|
|
368
|
+
screenshotReadiness: "ready",
|
|
369
|
+
dataRequirements: ["price history"],
|
|
370
|
+
limitations: [],
|
|
371
|
+
options: [{
|
|
372
|
+
key: "rangePreset",
|
|
373
|
+
settingKey: "chartRangePreset",
|
|
374
|
+
description: "Chart history window.",
|
|
375
|
+
type: "enum",
|
|
376
|
+
aliases: ["range"],
|
|
377
|
+
values: RANGE_VALUES,
|
|
378
|
+
defaultValue: "5Y",
|
|
379
|
+
}],
|
|
380
|
+
},
|
|
381
|
+
"graph-intraday-price-pane": {
|
|
382
|
+
id: "intraday-price-chart",
|
|
383
|
+
botSafe: true,
|
|
384
|
+
tickerCardinality: "one",
|
|
385
|
+
aliases: ["intraday chart", "intraday price", "one day chart"],
|
|
386
|
+
intents: ["chart intraday security prices"],
|
|
387
|
+
outputKind: "price-history",
|
|
388
|
+
reportReadiness: "ready",
|
|
389
|
+
screenshotReadiness: "partial",
|
|
390
|
+
dataRequirements: ["intraday price history"],
|
|
391
|
+
limitations: ["Intraday availability depends on the selected market-data provider."],
|
|
392
|
+
options: [],
|
|
393
|
+
},
|
|
394
|
+
};
|
|
395
|
+
|
|
396
|
+
const UNSUPPORTED_CAPABILITY: PaneFunctionCapability = {
|
|
397
|
+
id: "unverified-pane",
|
|
398
|
+
botSafe: false,
|
|
399
|
+
tickerCardinality: "none",
|
|
400
|
+
aliases: [],
|
|
401
|
+
intents: [],
|
|
402
|
+
outputKind: "pane",
|
|
403
|
+
reportReadiness: "unsupported",
|
|
404
|
+
screenshotReadiness: "unsupported",
|
|
405
|
+
dataRequirements: [],
|
|
406
|
+
limitations: ["This UI pane has not been verified as a deterministic CLI or bot capability."],
|
|
407
|
+
options: [],
|
|
408
|
+
};
|
|
409
|
+
|
|
410
|
+
function optionToken(value: string): string {
|
|
411
|
+
return value.trim().toLowerCase().replace(/[\s_.-]+/g, "");
|
|
412
|
+
}
|
|
413
|
+
|
|
414
|
+
export function getPaneFunctionCapability(
|
|
415
|
+
template: PaneTemplateDef | undefined,
|
|
416
|
+
_pane: PaneDef,
|
|
417
|
+
): PaneFunctionCapability {
|
|
418
|
+
return template ? CAPABILITIES[template.id] ?? UNSUPPORTED_CAPABILITY : UNSUPPORTED_CAPABILITY;
|
|
419
|
+
}
|
|
420
|
+
|
|
421
|
+
function resolveOptionDef(
|
|
422
|
+
capability: PaneFunctionCapability,
|
|
423
|
+
rawKey: string,
|
|
424
|
+
): PaneFunctionOptionDef | undefined {
|
|
425
|
+
const token = optionToken(rawKey);
|
|
426
|
+
return capability.options.find((option) => (
|
|
427
|
+
optionToken(option.key) === token
|
|
428
|
+
|| option.aliases?.some((alias) => optionToken(alias) === token)
|
|
429
|
+
));
|
|
430
|
+
}
|
|
431
|
+
|
|
432
|
+
function normalizeEnumValue(option: PaneFunctionOptionDef, rawValue: string): string {
|
|
433
|
+
const token = optionToken(rawValue);
|
|
434
|
+
const match = option.values?.find((candidate) => (
|
|
435
|
+
optionToken(candidate.value) === token
|
|
436
|
+
|| candidate.aliases?.some((alias) => optionToken(alias) === token)
|
|
437
|
+
));
|
|
438
|
+
if (match) return match.value;
|
|
439
|
+
throw new Error(
|
|
440
|
+
`Invalid --${option.key} value "${rawValue}". Use one of: ${option.values?.map(({ value }) => value).join(", ") ?? ""}.`,
|
|
441
|
+
);
|
|
442
|
+
}
|
|
443
|
+
|
|
444
|
+
function normalizeOptionValue(option: PaneFunctionOptionDef, rawValue: string | true): string | number | boolean {
|
|
445
|
+
if (option.type === "boolean") {
|
|
446
|
+
if (rawValue === true) return true;
|
|
447
|
+
if (/^true$/i.test(rawValue)) return true;
|
|
448
|
+
if (/^false$/i.test(rawValue)) return false;
|
|
449
|
+
throw new Error(`Invalid --${option.key} value "${rawValue}". Use true or false.`);
|
|
450
|
+
}
|
|
451
|
+
if (rawValue === true) throw new Error(`--${option.key} requires a value.`);
|
|
452
|
+
if (option.type === "enum") return normalizeEnumValue(option, rawValue);
|
|
453
|
+
if (option.type === "integer") {
|
|
454
|
+
const value = Number(rawValue);
|
|
455
|
+
if (!Number.isInteger(value)) throw new Error(`--${option.key} must be an integer.`);
|
|
456
|
+
if (option.minimum != null && value < option.minimum) {
|
|
457
|
+
throw new Error(`--${option.key} must be at least ${option.minimum}.`);
|
|
458
|
+
}
|
|
459
|
+
if (option.maximum != null && value > option.maximum) {
|
|
460
|
+
throw new Error(`--${option.key} must be at most ${option.maximum}.`);
|
|
461
|
+
}
|
|
462
|
+
return value;
|
|
463
|
+
}
|
|
464
|
+
return rawValue;
|
|
465
|
+
}
|
|
466
|
+
|
|
467
|
+
export function normalizeCapabilityOptions(
|
|
468
|
+
capability: PaneFunctionCapability,
|
|
469
|
+
options: Record<string, string | true>,
|
|
470
|
+
settings: { strict?: boolean } = {},
|
|
471
|
+
): NormalizedPaneFunctionOptions {
|
|
472
|
+
if (!capability.botSafe) {
|
|
473
|
+
return Object.fromEntries(Object.entries(options).map(([key, value]) => [key, value]));
|
|
474
|
+
}
|
|
475
|
+
|
|
476
|
+
const normalized: Record<string, string | number | boolean> = {};
|
|
477
|
+
for (const option of capability.options) {
|
|
478
|
+
if (option.defaultValue !== undefined) normalized[option.key] = option.defaultValue;
|
|
479
|
+
}
|
|
480
|
+
for (const [rawKey, rawValue] of Object.entries(options)) {
|
|
481
|
+
const option = resolveOptionDef(capability, rawKey);
|
|
482
|
+
if (!option) {
|
|
483
|
+
if (settings.strict === false) {
|
|
484
|
+
normalized[rawKey] = rawValue;
|
|
485
|
+
continue;
|
|
486
|
+
}
|
|
487
|
+
const supported = capability.options.map(({ key }) => `--${key}`).join(", ");
|
|
488
|
+
throw new Error(
|
|
489
|
+
`${capability.id} does not support --${rawKey}.${supported ? ` Supported options: ${supported}.` : " It has no options."}`,
|
|
490
|
+
);
|
|
491
|
+
}
|
|
492
|
+
normalized[option.key] = normalizeOptionValue(option, rawValue);
|
|
493
|
+
}
|
|
494
|
+
return normalized;
|
|
495
|
+
}
|
|
496
|
+
|
|
497
|
+
export function capabilityPaneSettings(
|
|
498
|
+
capability: PaneFunctionCapability,
|
|
499
|
+
options: NormalizedPaneFunctionOptions,
|
|
500
|
+
): Record<string, unknown> {
|
|
501
|
+
const settings: Record<string, unknown> = {};
|
|
502
|
+
for (const option of capability.options) {
|
|
503
|
+
if (option.pluginState) continue;
|
|
504
|
+
const value = options[option.key];
|
|
505
|
+
if (value !== undefined) settings[option.settingKey ?? option.key] = value;
|
|
506
|
+
}
|
|
507
|
+
return settings;
|
|
508
|
+
}
|
|
509
|
+
|
|
510
|
+
export function capabilityPluginState(
|
|
511
|
+
capability: PaneFunctionCapability,
|
|
512
|
+
options: NormalizedPaneFunctionOptions,
|
|
513
|
+
): Record<string, Record<string, unknown>> {
|
|
514
|
+
const pluginState: Record<string, Record<string, unknown>> = {};
|
|
515
|
+
for (const option of capability.options) {
|
|
516
|
+
if (!option.pluginState) continue;
|
|
517
|
+
const value = options[option.key];
|
|
518
|
+
if (value === undefined) continue;
|
|
519
|
+
const plugin = pluginState[option.pluginState.pluginId] ?? {};
|
|
520
|
+
plugin[option.pluginState.key ?? option.key] = value;
|
|
521
|
+
pluginState[option.pluginState.pluginId] = plugin;
|
|
522
|
+
}
|
|
523
|
+
return pluginState;
|
|
524
|
+
}
|
|
525
|
+
|
|
526
|
+
export function capabilityOptionSummary(capability: PaneFunctionCapability): string[] {
|
|
527
|
+
return capability.options.map((option) => {
|
|
528
|
+
const values = option.values?.map(({ value }) => value).join("|");
|
|
529
|
+
const defaultValue = option.defaultValue !== undefined ? ` default=${String(option.defaultValue)}` : "";
|
|
530
|
+
return `--${option.key}${values ? ` <${values}>` : ` <${option.type}>`}${defaultValue}`;
|
|
531
|
+
});
|
|
532
|
+
}
|
|
@@ -5,6 +5,11 @@ import {
|
|
|
5
5
|
normalizeLookupToken,
|
|
6
6
|
type ParsedPaneCatalogArgs,
|
|
7
7
|
} from "./options";
|
|
8
|
+
import {
|
|
9
|
+
capabilityOptionSummary,
|
|
10
|
+
getPaneFunctionCapability,
|
|
11
|
+
type PaneFunctionCapability,
|
|
12
|
+
} from "./capabilities";
|
|
8
13
|
|
|
9
14
|
export interface PaneFunctionCatalog {
|
|
10
15
|
panes: ReadonlyMap<string, PaneDef>;
|
|
@@ -24,6 +29,7 @@ export interface PaneCatalogEntry {
|
|
|
24
29
|
argPlaceholder?: string;
|
|
25
30
|
keywords: string[];
|
|
26
31
|
defaultSettings: Record<string, unknown>;
|
|
32
|
+
capability: PaneFunctionCapability;
|
|
27
33
|
}
|
|
28
34
|
|
|
29
35
|
export function buildTemplateContext(context: MarketContext, symbol: string | null) {
|
|
@@ -122,6 +128,7 @@ async function buildTemplateCatalogEntry(
|
|
|
122
128
|
argPlaceholder: template.shortcut?.argPlaceholder,
|
|
123
129
|
keywords: template.keywords ?? [],
|
|
124
130
|
defaultSettings,
|
|
131
|
+
capability: getPaneFunctionCapability(template, pane),
|
|
125
132
|
};
|
|
126
133
|
}
|
|
127
134
|
|
|
@@ -149,6 +156,7 @@ export async function buildPaneCatalogEntries(
|
|
|
149
156
|
paneName: pane.name,
|
|
150
157
|
keywords: [],
|
|
151
158
|
defaultSettings: {},
|
|
159
|
+
capability: getPaneFunctionCapability(undefined, pane),
|
|
152
160
|
});
|
|
153
161
|
}
|
|
154
162
|
|
|
@@ -176,23 +184,37 @@ function paneCatalogSearchScore(entry: PaneCatalogEntry, query: string): number
|
|
|
176
184
|
entry.argKind,
|
|
177
185
|
entry.argPlaceholder,
|
|
178
186
|
...entry.keywords,
|
|
187
|
+
...entry.capability.aliases,
|
|
188
|
+
...entry.capability.intents,
|
|
189
|
+
entry.capability.outputKind,
|
|
190
|
+
...entry.capability.options.flatMap((option) => [
|
|
191
|
+
option.key,
|
|
192
|
+
option.description,
|
|
193
|
+
...(option.aliases ?? []),
|
|
194
|
+
...(option.values ?? []).flatMap((value) => [value.value, ...(value.aliases ?? [])]),
|
|
195
|
+
]),
|
|
179
196
|
...Object.keys(entry.defaultSettings),
|
|
180
197
|
].filter((value): value is string => !!value).join(" ").toLowerCase();
|
|
181
198
|
|
|
182
|
-
let score = searchable.includes(query.toLowerCase()) ?
|
|
199
|
+
let score = searchable.includes(query.toLowerCase()) ? 12 : 0;
|
|
200
|
+
let matchedTerms = 0;
|
|
183
201
|
for (const term of terms) {
|
|
184
202
|
const normalized = normalizeLookupToken(term);
|
|
185
203
|
if (exactTokens.includes(normalized)) {
|
|
186
204
|
score += 8;
|
|
205
|
+
matchedTerms += 1;
|
|
187
206
|
} else if (searchable.includes(term)) {
|
|
188
207
|
score += 2;
|
|
208
|
+
matchedTerms += 1;
|
|
189
209
|
} else if (searchable.includes(normalized)) {
|
|
190
210
|
score += 1;
|
|
191
|
-
|
|
192
|
-
return 0;
|
|
211
|
+
matchedTerms += 1;
|
|
193
212
|
}
|
|
194
213
|
}
|
|
195
214
|
|
|
215
|
+
if (matchedTerms === 0) return 0;
|
|
216
|
+
score += Math.round((matchedTerms / terms.length) * 8);
|
|
217
|
+
if (entry.capability.botSafe) score += 2;
|
|
196
218
|
return score;
|
|
197
219
|
}
|
|
198
220
|
|
|
@@ -233,11 +255,24 @@ export function renderPaneCatalogReport(entries: PaneCatalogEntry[], args: Parse
|
|
|
233
255
|
if (entry.shortcut) lines.push(` Shortcut: ${entry.shortcut}`);
|
|
234
256
|
if (entry.argKind) lines.push(` Argument: ${entry.argKind}${entry.argPlaceholder ? ` (${entry.argPlaceholder})` : ""}`);
|
|
235
257
|
if (entry.keywords.length > 0) lines.push(` Keywords: ${entry.keywords.join(", ")}`);
|
|
258
|
+
lines.push(` Bot safe: ${entry.capability.botSafe ? "yes" : "no"}`);
|
|
259
|
+
lines.push(` Output: ${entry.capability.outputKind}`);
|
|
260
|
+
lines.push(` Readiness: report=${entry.capability.reportReadiness}, screenshot=${entry.capability.screenshotReadiness}`);
|
|
261
|
+
if (entry.capability.aliases.length > 0) lines.push(` Aliases: ${entry.capability.aliases.join(", ")}`);
|
|
262
|
+
if (entry.capability.intents.length > 0) lines.push(` Intents: ${entry.capability.intents.join("; ")}`);
|
|
263
|
+
const optionSummary = capabilityOptionSummary(entry.capability);
|
|
264
|
+
if (optionSummary.length > 0) lines.push(` Options: ${optionSummary.join(", ")}`);
|
|
265
|
+
if (entry.capability.dataRequirements.length > 0) {
|
|
266
|
+
lines.push(` Requires: ${entry.capability.dataRequirements.join(", ")}`);
|
|
267
|
+
}
|
|
268
|
+
if (entry.capability.limitations.length > 0) {
|
|
269
|
+
lines.push(` Limitations: ${entry.capability.limitations.join(" ")}`);
|
|
270
|
+
}
|
|
236
271
|
lines.push(` Defaults: ${formatCatalogSettings(entry.defaultSettings)}`);
|
|
237
272
|
lines.push(` Examples: gloomberb fn ${entry.token} ${arg} | gloomberb shot ${entry.token} ${arg} --output /tmp/${entry.token.toLowerCase()}.png`);
|
|
238
273
|
lines.push("");
|
|
239
274
|
}
|
|
240
275
|
|
|
241
|
-
lines.push("
|
|
276
|
+
lines.push("Use --require-bot-safe to reject unverified functions and undeclared options. Generic UI screenshots may also accept --tab, --activeTabId, and --state options.");
|
|
242
277
|
return lines.join("\n").trimEnd();
|
|
243
278
|
}
|
|
@@ -0,0 +1,17 @@
|
|
|
1
|
+
import { describe, expect, test } from "bun:test";
|
|
2
|
+
import { clipPriceHistoryToRange } from "./data";
|
|
3
|
+
|
|
4
|
+
describe("clipPriceHistoryToRange", () => {
|
|
5
|
+
test("anchors the requested window to the newest provider observation", () => {
|
|
6
|
+
const points = [
|
|
7
|
+
{ date: new Date("2025-07-16T00:00:00Z"), close: 100 },
|
|
8
|
+
{ date: new Date("2025-07-17T00:00:00Z"), close: 101 },
|
|
9
|
+
{ date: new Date("2026-07-17T00:00:00Z"), close: 120 },
|
|
10
|
+
];
|
|
11
|
+
|
|
12
|
+
expect(clipPriceHistoryToRange(points, "1Y").map(({ date }) => date.toISOString().slice(0, 10))).toEqual([
|
|
13
|
+
"2025-07-17",
|
|
14
|
+
"2026-07-17",
|
|
15
|
+
]);
|
|
16
|
+
});
|
|
17
|
+
});
|