gloomberb 0.16.3 → 0.16.5
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 +14 -91
- package/package.json +7 -1
- package/src/{plugins/builtin/cloud → account}/auth-form.tsx +9 -9
- package/src/{plugins/builtin/cloud → account}/auth-model.ts +4 -4
- package/src/account/billing.ts +57 -0
- package/src/{plugins/builtin/cloud → account}/device-signin-dialog.tsx +18 -12
- package/src/{plugins/builtin/cloud → account}/device-signin.ts +2 -2
- package/src/{plugins/builtin/cloud → account}/email-auth-attempt.ts +2 -2
- package/src/account/session.ts +16 -0
- package/src/{plugins/builtin/cloud → account}/upgrade-dialog.tsx +42 -17
- package/src/account/upgrade-personalization.ts +57 -0
- package/src/account/upgrade-tickers.ts +124 -0
- package/src/{plugins/builtin/cloud → account}/verification-panel.tsx +6 -6
- package/src/api-client/askg.ts +43 -0
- package/src/api-client/auth.ts +15 -0
- package/src/api-client/beneficial-owners.ts +4 -0
- package/src/api-client/chat.ts +19 -0
- package/src/api-client/company-kpis.ts +14 -2
- package/src/api-client/data.ts +58 -18
- package/src/api-client/earnings.ts +6 -0
- package/src/api-client/futures-curve.ts +56 -0
- package/src/api-client/index.ts +16 -1
- package/src/api-client/market-discovery.ts +10 -1
- package/src/api-client/normalizers.ts +27 -0
- package/src/api-client/paths.ts +95 -23
- package/src/api-client/request.ts +2 -1
- package/src/api-client/research-activity.ts +46 -10
- package/src/api-client/socket.ts +39 -8
- package/src/api-client/types.ts +74 -2
- package/src/api-client/upgrade-experiment.ts +90 -0
- package/src/api-client/yield-curves.ts +8 -0
- package/src/app/global-shortcuts.ts +26 -2
- package/src/app/keybindings/actions.ts +10 -0
- package/src/app/pane-runtime/index.tsx +8 -0
- package/src/app/pane-runtime/pane-template-runtime.ts +5 -0
- package/src/app/pane-runtime/plugin-bindings.ts +65 -25
- package/src/app/pane-runtime/ticker-inspector-runtime.ts +12 -0
- package/src/app/pane-runtime/ticker-open-runtime.ts +25 -4
- package/src/app/runtime/desktop-deeplink.ts +5 -0
- package/src/app/star-prompt/model.ts +98 -0
- package/src/app/star-prompt/runtime.ts +41 -0
- package/src/app/star-prompt/status-line.tsx +190 -0
- package/src/app.tsx +13 -7
- package/src/architecture/core-builtin-allowlist.json +61 -0
- package/src/brokers/signed-in/adapter.ts +33 -2
- package/src/brokers/signed-in/client.ts +10 -0
- package/src/brokers/signed-in/sign-in-dialog.tsx +34 -14
- package/src/brokers/signed-in/sign-in.ts +62 -5
- package/src/capabilities/chart-series.ts +11 -1
- package/src/capabilities/registry.ts +8 -1
- package/src/capabilities/types.ts +2 -0
- package/src/cli/commands/crypto-hints.ts +19 -4
- package/src/cli/commands/fred-series.ts +61 -0
- package/src/cli/commands/market.ts +744 -181
- package/src/cli/commands/news-hints.ts +62 -0
- package/src/cli/commands/news-search.ts +53 -0
- package/src/cli/commands/options-chain.ts +172 -0
- package/src/cli/commands/options-leaps.ts +425 -0
- package/src/cli/commands/overview.ts +251 -40
- package/src/cli/commands/remote.ts +2 -1
- package/src/cli/commands/search.ts +109 -15
- package/src/cli/commands/system.ts +151 -24
- package/src/cli/commands/themes.ts +64 -0
- package/src/cli/commands/ticker.ts +149 -40
- package/src/cli/context.ts +45 -14
- package/src/cli/desktop-pane-shot.ts +150 -17
- package/src/cli/earnings-calendar.ts +71 -0
- package/src/cli/errors.ts +25 -2
- package/src/cli/freshness.ts +22 -8
- package/src/cli/fx-pair.ts +57 -0
- package/src/cli/glossary.ts +429 -0
- package/src/cli/help.ts +14 -1
- package/src/cli/history-rows.ts +48 -7
- package/src/cli/index-roots.ts +58 -0
- package/src/cli/index.ts +29 -12
- package/src/cli/known-gaps.ts +27 -0
- package/src/cli/listing-arg.ts +595 -26
- package/src/cli/not-a-ticker.ts +44 -0
- package/src/cli/options.ts +50 -6
- package/src/cli/pane-functions/access-gate.ts +5 -0
- package/src/cli/pane-functions/capabilities.ts +11 -4
- package/src/cli/pane-functions/catalog.ts +48 -7
- package/src/cli/pane-functions/data.ts +48 -13
- package/src/cli/pane-functions/discovery.ts +1 -0
- package/src/cli/pane-functions/dom.ts +41 -19
- package/src/cli/pane-functions/freshness.ts +531 -32
- package/src/cli/pane-functions/function-help.ts +77 -25
- package/src/cli/pane-functions/headless.ts +50 -21
- package/src/cli/pane-functions/index.ts +66 -10
- package/src/cli/pane-functions/market-session.ts +147 -0
- package/src/cli/pane-functions/options.ts +77 -25
- package/src/cli/pane-functions/report-notices.ts +81 -0
- package/src/cli/pane-functions/report.ts +19 -8
- package/src/cli/pane-functions/resolver.ts +53 -18
- package/src/cli/pane-functions/screenshot-evidence.ts +2 -0
- package/src/cli/pane-functions/screenshot.ts +199 -30
- package/src/cli/registry.ts +2 -1
- package/src/cli/report-tables.ts +3 -0
- package/src/cli/result.ts +53 -13
- package/src/cli/row-window.ts +76 -0
- package/src/cli/scroll-truncation.ts +34 -0
- package/src/cli/staged-tickers.ts +52 -0
- package/src/cli/symbol-args.ts +9 -0
- package/src/cli/symbol-list.ts +172 -0
- package/src/cli/ticker-resolution.ts +223 -30
- package/src/cli/types.ts +5 -0
- package/src/components/chart/composite/axis-overlays.tsx +6 -2
- package/src/components/chart/composite/composite-chart.tsx +83 -10
- package/src/components/chart/composite/legend.tsx +88 -8
- package/src/components/chart/composite/panel-surface.tsx +44 -17
- package/src/components/chart/composite/price-axis-labels.tsx +3 -1
- package/src/components/chart/composite/rasterizer.ts +64 -4
- package/src/components/chart/composite/series-cues.ts +71 -0
- package/src/components/chart/composite/text-renderer.ts +16 -8
- package/src/components/chart/composite/types.ts +3 -0
- package/src/components/command-bar/commands/direct/index.ts +9 -1
- package/src/components/command-bar/commands/plugin/items.ts +3 -1
- package/src/components/command-bar/commands/registry.ts +7 -0
- package/src/components/command-bar/layout-items/focused-pane.ts +38 -0
- package/src/components/command-bar/pane-templates/workflow.ts +5 -0
- package/src/components/command-bar/panel/index.tsx +11 -3
- package/src/components/command-bar/panel/runtime.ts +3 -0
- package/src/components/command-bar/panel/types.ts +2 -0
- package/src/components/command-bar/routes/root/command-items.ts +2 -0
- package/src/components/command-bar/routes/root/plugin-turn-on.ts +92 -0
- package/src/components/command-bar/routes/root/provider-search.ts +4 -3
- package/src/components/command-bar/routes/root/results.ts +40 -10
- package/src/components/command-bar/routes/root/runtime.ts +8 -0
- package/src/components/command-bar/routes/root/search-providers.ts +97 -14
- package/src/components/command-bar/routes/ticker-search/results.ts +12 -11
- package/src/components/command-bar/routes/ticker-search/route.ts +4 -3
- package/src/components/command-bar/surface/index.tsx +18 -4
- package/src/components/command-bar/theme-picker.tsx +48 -13
- package/src/components/command-bar/workflow/ops.ts +5 -3
- package/src/components/command-bar/workflow/tickers.ts +23 -4
- package/src/components/data-table/view.tsx +28 -9
- package/src/components/layout/detached-pane-shell.tsx +9 -0
- package/src/components/layout/floating-pane.tsx +9 -2
- package/src/components/layout/header.tsx +20 -5
- package/src/components/layout/market-summary.ts +23 -9
- package/src/components/layout/pane/content.tsx +40 -29
- package/src/components/layout/pane/cycle-order.ts +2 -11
- package/src/components/layout/pane/footer/index.tsx +6 -2
- package/src/components/layout/pane/footer/model.ts +35 -1
- package/src/components/layout/pane/header.tsx +26 -2
- package/src/components/layout/pane/index.tsx +12 -2
- package/src/components/layout/pane/sidebar.tsx +78 -10
- package/src/components/layout/pane/title.ts +1 -1
- package/src/components/layout/presentation.ts +22 -0
- package/src/components/layout/shell/active-drag.ts +21 -5
- package/src/components/layout/shell/drag/index.ts +43 -9
- package/src/components/layout/shell/drag/live.ts +87 -6
- package/src/components/layout/shell/drag/runtime.ts +62 -20
- package/src/components/layout/shell/index.tsx +71 -12
- package/src/components/layout/shell/layout-state.ts +5 -11
- package/src/components/layout/shell/menu.ts +33 -1
- package/src/components/layout/shell/native/pointer-runtime.ts +3 -1
- package/src/components/layout/shell/pane/actions.ts +2 -1
- package/src/components/layout/shell/pane/layers.tsx +216 -28
- package/src/components/layout/shell/pane/management-shortcuts.ts +5 -0
- package/src/components/layout/shell/pane/new-layout.ts +116 -0
- package/src/components/layout/shell/shortcuts.ts +5 -2
- package/src/components/layout/shell/terminal-pointer-runtime.ts +24 -0
- package/src/components/layout/shell/visible-layout.ts +44 -1
- package/src/components/layout/status-bar.tsx +4 -1
- package/src/components/markdown-text.tsx +69 -23
- package/src/components/metric-treemap/heat-surface.tsx +37 -9
- package/src/components/metric-treemap/heat-tiles.ts +48 -17
- package/src/components/onboarding/account-step/form-panel.tsx +1 -1
- package/src/components/onboarding/account-step/index.tsx +1 -1
- package/src/components/onboarding/account-step/qr-panel.tsx +1 -1
- package/src/components/onboarding/account-step/signed-in-panel.tsx +1 -1
- package/src/components/onboarding/onboarding-frame.tsx +33 -10
- package/src/components/onboarding/onboarding-keyboard.ts +1 -1
- package/src/components/onboarding/onboarding-wizard.tsx +50 -41
- package/src/components/onboarding/portfolio-step/positions-panel.tsx +5 -2
- package/src/components/onboarding/pro-step-layout.ts +86 -0
- package/src/components/onboarding/use-onboarding-upgrade.ts +8 -4
- package/src/components/onboarding/wizard-account.ts +2 -2
- package/src/components/pane-template-wizard.tsx +9 -1
- package/src/components/price-selector-dialog.tsx +11 -2
- package/src/components/sign-in-gate.tsx +3 -3
- package/src/components/ticker/list-table-view.tsx +24 -1
- package/src/components/ui/action-row.tsx +2 -1
- package/src/components/ui/button.tsx +17 -1
- package/src/components/ui/choice-dialog.tsx +6 -4
- package/src/components/ui/confirm-dialog.tsx +28 -18
- package/src/components/ui/data-table/index.tsx +49 -0
- package/src/components/ui/data-table/opentui/index.tsx +37 -6
- package/src/components/ui/data-table/types.ts +20 -1
- package/src/components/ui/data-table/visible-range.ts +2 -0
- package/src/components/ui/dialog-actions.tsx +64 -0
- package/src/components/ui/display.tsx +17 -3
- package/src/components/ui/frame.tsx +35 -2
- package/src/components/ui/icon.tsx +13 -2
- package/src/components/ui/index.ts +1 -1
- package/src/components/ui/text-prompt-dialog.tsx +11 -9
- package/src/core/connection-health.ts +1 -1
- package/src/core/state/app/layout-reducer.ts +89 -3
- package/src/core/state/app/state.ts +8 -5
- package/src/core/state/app/types.ts +13 -2
- package/src/data/cached-query.ts +2 -0
- package/src/data/config/layout.ts +55 -21
- package/src/data/config/store/fold-panes.ts +149 -0
- package/src/data/config/store/migrations.ts +7 -0
- package/src/data/config/store/node.ts +27 -6
- package/src/data/config/store/normalize.ts +44 -5
- package/src/data/ticker-repository.ts +5 -0
- package/src/data/ticker-store.ts +15 -0
- package/src/docs/content.ts +215 -0
- package/src/docs/load.ts +139 -0
- package/src/docs/requests.ts +39 -0
- package/src/docs/snapshot.chunk.ts +8 -0
- package/src/docs/snapshot.json +7416 -0
- package/src/docs/topics.ts +216 -0
- package/src/i18n/es.ts +75 -5
- package/src/i18n/ja.ts +75 -5
- package/src/i18n/ko.ts +75 -5
- package/src/i18n/zh-cn.ts +75 -5
- package/src/i18n/zh-tw.ts +75 -5
- package/src/layout/desks.ts +2 -3
- package/src/layout/pane-layout-move.ts +264 -0
- package/src/layout/pane-manager/dock-tree.ts +18 -0
- package/src/layout/pane-manager/hidden-panes.ts +160 -0
- package/src/layout/pane-manager/index.ts +2 -0
- package/src/market-data/coordinator/chart.ts +10 -4
- package/src/market-data/coordinator/entries.ts +7 -1
- package/src/market-data/coordinator/index.ts +6 -3
- package/src/market-data/coordinator/quotes.ts +2 -2
- package/src/{plugins/builtin/futures/contracts.ts → market-data/futures-board.ts} +81 -28
- package/src/market-data/futures-contract.ts +151 -0
- package/src/market-data/hooks.tsx +10 -2
- package/src/market-data/market/format.ts +39 -21
- package/src/market-data/market/freshness.ts +193 -30
- package/src/market-data/market/status.ts +59 -23
- package/src/market-data/options-alternatives.ts +69 -0
- package/src/market-data/published-apac-sessions.ts +23 -1
- package/src/market-data/quotes/contributions.ts +22 -2
- package/src/market-data/quotes/metadata.ts +8 -9
- package/src/market-data/quotes/resolution.ts +2 -0
- package/src/market-data/quotes/screener-live-quotes.ts +61 -9
- package/src/market-data/result-types.ts +2 -0
- package/src/plugins/builtin/account-management/keyboard.ts +3 -0
- package/src/plugins/builtin/account-management/model.ts +2 -56
- package/src/plugins/builtin/account-management/navigation.ts +1 -1
- package/src/plugins/builtin/account-management/pane.tsx +37 -8
- package/src/plugins/builtin/account-management/password-dialog.tsx +1 -1
- package/src/plugins/builtin/alerts/cli.ts +313 -47
- package/src/plugins/builtin/alerts/events-pane.tsx +45 -7
- package/src/plugins/builtin/alerts/events.ts +23 -2
- package/src/plugins/builtin/alerts/history-pane.tsx +7 -2
- package/src/plugins/builtin/alerts/history.ts +2 -0
- package/src/plugins/builtin/alerts/index.tsx +41 -9
- package/src/plugins/builtin/alerts/pane.tsx +8 -0
- package/src/plugins/builtin/alerts/quotes.ts +3 -0
- package/src/plugins/builtin/alerts/research-builder.ts +8 -3
- package/src/plugins/builtin/alerts/research-rules.ts +18 -2
- package/src/plugins/builtin/alerts/scheduled-check.ts +122 -0
- package/src/plugins/builtin/alerts/scheduled-sources.ts +25 -0
- package/src/plugins/builtin/alerts/scheduled.ts +254 -0
- package/src/plugins/builtin/alerts/targets.ts +92 -0
- package/src/plugins/builtin/analytics/index.tsx +4 -2
- package/src/plugins/builtin/analytics/risk-headless.ts +33 -13
- package/src/plugins/builtin/analytics/risk-math.ts +91 -27
- package/src/plugins/builtin/analytics/risk-model.ts +71 -12
- package/src/plugins/builtin/analytics/risk-pane.tsx +23 -12
- package/src/plugins/builtin/attention/index.tsx +2 -0
- package/src/plugins/builtin/attention/pane.tsx +3 -1
- package/src/plugins/builtin/attention/series.ts +26 -0
- package/src/plugins/builtin/awards/index.tsx +2 -0
- package/src/plugins/builtin/awards/pane.tsx +3 -1
- package/src/plugins/builtin/awards/series.ts +29 -0
- package/src/plugins/builtin/backtest/pane.tsx +1 -1
- package/src/plugins/builtin/bond-calculator/model.ts +2 -1
- package/src/plugins/builtin/broker-manager/detail.tsx +4 -0
- package/src/plugins/builtin/broker-manager/index.tsx +7 -3
- package/src/plugins/builtin/broker-manager/model.ts +8 -0
- package/src/plugins/builtin/broker-manager/pane-actions.tsx +8 -2
- package/src/plugins/builtin/broker-manager/sign-in-end.ts +82 -0
- package/src/plugins/builtin/broker-manager/table.ts +5 -0
- package/src/plugins/builtin/builtin-plugin-meta.ts +121 -11
- package/src/plugins/builtin/catalysts/pane.tsx +3 -1
- package/src/plugins/builtin/cds/client.ts +70 -13
- package/src/plugins/builtin/cds/headless.ts +116 -19
- package/src/plugins/builtin/cds/index.tsx +3 -1
- package/src/plugins/builtin/cds/model.ts +193 -31
- package/src/plugins/builtin/cds/pane.tsx +56 -14
- package/src/plugins/builtin/cds/series.ts +19 -0
- package/src/plugins/builtin/central-bank-rates/index.tsx +2 -0
- package/src/plugins/builtin/central-bank-rates/series.ts +42 -0
- package/src/plugins/builtin/chart-composer/catalog-inventory.ts +192 -255
- package/src/plugins/builtin/chart-composer/data-catalog-pane.tsx +84 -46
- package/src/plugins/builtin/chart-composer/editor.tsx +5 -4
- package/src/plugins/builtin/chart-composer/field-series.ts +40 -0
- package/src/plugins/builtin/chart-composer/headless.ts +8 -3
- package/src/plugins/builtin/chart-composer/index.tsx +9 -2
- package/src/plugins/builtin/chart-composer/pane.tsx +1 -1
- package/src/plugins/builtin/chart-composer/series-catalog.ts +58 -50
- package/src/plugins/builtin/chart-composer/series-expression.ts +18 -10
- package/src/plugins/builtin/chart-composer/use-series-catalog.ts +59 -3
- package/src/plugins/builtin/chart-composer/user-series.ts +84 -0
- package/src/plugins/builtin/chat/channels.ts +34 -36
- package/src/plugins/builtin/chat/command-bar.ts +138 -0
- package/src/plugins/builtin/chat/composer-commands.ts +21 -1
- package/src/plugins/builtin/chat/content/composer-runtime.ts +11 -1
- package/src/plugins/builtin/chat/content/footer.tsx +5 -3
- package/src/plugins/builtin/chat/content/index.tsx +21 -1
- package/src/plugins/builtin/chat/content/mentions.ts +2 -1
- package/src/plugins/builtin/chat/content/new-dm-dialog.tsx +10 -2
- package/src/plugins/builtin/chat/content/user-map.ts +3 -1
- package/src/plugins/builtin/chat/controller/index.ts +50 -0
- package/src/plugins/builtin/chat/conversations.ts +256 -0
- package/src/plugins/builtin/chat/discord-command.ts +91 -0
- package/src/plugins/builtin/chat/edit-window.ts +12 -6
- package/src/plugins/builtin/chat/ghost-user.ts +14 -0
- package/src/plugins/builtin/chat/index.tsx +40 -2
- package/src/plugins/builtin/chat/layout.ts +2 -0
- package/src/plugins/builtin/chat/message/desktop.tsx +2 -1
- package/src/plugins/builtin/chat/message/header.tsx +24 -15
- package/src/plugins/builtin/chat/message/profile-popover.tsx +2 -1
- package/src/plugins/builtin/chat/message/render-state.ts +3 -0
- package/src/plugins/builtin/chat/pane-requests.ts +60 -0
- package/src/plugins/builtin/chat/pane-state.ts +32 -2
- package/src/plugins/builtin/chat/pane.tsx +8 -0
- package/src/plugins/builtin/cloud/askg/controller.ts +223 -23
- package/src/plugins/builtin/cloud/askg/conversation-store.ts +21 -0
- package/src/plugins/builtin/cloud/askg/executor.ts +57 -3
- package/src/plugins/builtin/cloud/askg/manifest.ts +33 -7
- package/src/plugins/builtin/cloud/askg/model.ts +156 -78
- package/src/plugins/builtin/cloud/askg/pane.tsx +772 -377
- package/src/plugins/builtin/cloud/askg/protocol.ts +50 -3
- package/src/plugins/builtin/cloud/askg/tool-display.ts +440 -0
- package/src/plugins/builtin/cloud/askg/tool-timeline.tsx +403 -0
- package/src/plugins/builtin/cloud/askg/undo.ts +2 -0
- package/src/plugins/builtin/cloud/auth-actions.tsx +1 -1
- package/src/plugins/builtin/cloud/auth-commands.ts +1 -1
- package/src/plugins/builtin/cloud/auth-dialog.tsx +3 -3
- package/src/plugins/builtin/cloud/company-picker.tsx +1 -9
- package/src/plugins/builtin/cloud/mcp-connect/command.ts +24 -0
- package/src/plugins/builtin/cloud/mcp-connect/dialog.tsx +363 -0
- package/src/plugins/builtin/cloud/mcp-connect/model.ts +135 -0
- package/src/plugins/builtin/cloud/mcp-connect/sections.ts +62 -0
- package/src/plugins/builtin/cloud/plugin.tsx +36 -1
- package/src/plugins/builtin/cloud/terminal-relay/acm-tab.tsx +89 -0
- package/src/plugins/builtin/cloud/terminal-relay/client.ts +97 -0
- package/src/plugins/builtin/cloud/terminal-relay/connect-section.tsx +57 -0
- package/src/plugins/builtin/cloud/terminal-relay/engine.ts +734 -0
- package/src/plugins/builtin/cloud/terminal-relay/grants.ts +137 -0
- package/src/plugins/builtin/cloud/terminal-relay/host.tsx +81 -0
- package/src/plugins/builtin/cloud/terminal-relay/indicator.tsx +82 -0
- package/src/plugins/builtin/cloud/terminal-relay/manifest.ts +239 -0
- package/src/plugins/builtin/cloud/terminal-relay/policy.ts +162 -0
- package/src/plugins/builtin/cloud/terminal-relay/prompts.tsx +192 -0
- package/src/plugins/builtin/cloud/terminal-relay/redact.ts +73 -0
- package/src/plugins/builtin/cloud/terminal-relay/summary.ts +62 -0
- package/src/plugins/builtin/cloud/thesis/exposure.ts +1 -1
- package/src/plugins/builtin/cloud/thesis/prompts.tsx +2 -1
- package/src/plugins/builtin/comment-letters/client.ts +1 -3
- package/src/plugins/builtin/company-attention/app-rank.tsx +1 -1
- package/src/plugins/builtin/company-attention/headless.ts +19 -5
- package/src/plugins/builtin/company-attention/index.tsx +2 -0
- package/src/plugins/builtin/company-attention/model.ts +26 -7
- package/src/plugins/builtin/company-attention/pane.tsx +12 -9
- package/src/plugins/builtin/company-attention/series.ts +52 -0
- package/src/plugins/builtin/company-kpis/client.ts +23 -8
- package/src/plugins/builtin/company-kpis/headless.ts +3 -1
- package/src/plugins/builtin/company-kpis/pane.tsx +19 -9
- package/src/plugins/builtin/company-kpis/screenshot-evidence.ts +10 -3
- package/src/plugins/builtin/composite-plugins.ts +116 -67
- package/src/plugins/builtin/cot/index.tsx +3 -1
- package/src/plugins/builtin/cot/model.ts +40 -11
- package/src/plugins/builtin/cot/series.ts +27 -0
- package/src/plugins/builtin/credit-boards/cdx-pane.tsx +4 -4
- package/src/plugins/builtin/credit-boards/index.tsx +23 -21
- package/src/plugins/builtin/credit-boards/model.ts +0 -1
- package/src/plugins/builtin/credit-boards/pane.tsx +30 -0
- package/src/plugins/builtin/credit-boards/series.ts +66 -0
- package/src/plugins/builtin/credit-boards/sovr-pane.tsx +4 -4
- package/src/plugins/builtin/credit-conditions/index.tsx +2 -0
- package/src/plugins/builtin/credit-conditions/series.ts +26 -0
- package/src/plugins/builtin/credit-documents/headless.ts +31 -1
- package/src/plugins/builtin/credit-documents/pane.tsx +3 -1
- package/src/plugins/builtin/crypto-board/headless.ts +2 -3
- package/src/plugins/builtin/crypto-board/index.tsx +2 -0
- package/src/plugins/builtin/crypto-board/model.ts +12 -0
- package/src/plugins/builtin/crypto-board/pane.tsx +19 -12
- package/src/plugins/builtin/crypto-board/series.ts +48 -0
- package/src/plugins/builtin/custom-view/live-quotes.ts +2 -2
- package/src/plugins/builtin/debt-maturities/client.ts +37 -9
- package/src/plugins/builtin/debt-maturities/headless.ts +3 -1
- package/src/plugins/builtin/debt-maturities/index.tsx +2 -0
- package/src/plugins/builtin/debt-maturities/pane.tsx +5 -4
- package/src/plugins/builtin/debt-maturities/series.ts +45 -0
- package/src/plugins/builtin/dividend-yield/headless.ts +2 -2
- package/src/plugins/builtin/dividend-yield/index.tsx +3 -1
- package/src/plugins/builtin/dividend-yield/pane.tsx +1 -1
- package/src/plugins/builtin/dividend-yield/series.ts +20 -0
- package/src/plugins/builtin/docs/blocks.tsx +181 -0
- package/src/plugins/builtin/docs/index.tsx +68 -0
- package/src/plugins/builtin/docs/pane.tsx +426 -0
- package/src/plugins/builtin/docs/targets.ts +72 -0
- package/src/plugins/builtin/docs/use-docs.ts +60 -0
- package/src/plugins/builtin/doe/index.tsx +2 -0
- package/src/plugins/builtin/doe/series.ts +62 -0
- package/src/plugins/builtin/earnings/client.ts +3 -2
- package/src/plugins/builtin/earnings/format.ts +1 -5
- package/src/plugins/builtin/earnings/headless.ts +58 -6
- package/src/plugins/builtin/earnings/history-model.ts +15 -1
- package/src/plugins/builtin/earnings/history-table.ts +13 -2
- package/src/plugins/builtin/earnings/history.tsx +7 -3
- package/src/plugins/builtin/earnings-calls/data.ts +28 -7
- package/src/plugins/builtin/earnings-calls/headless.ts +3 -2
- package/src/plugins/builtin/earnings-calls/pane.tsx +10 -5
- package/src/plugins/builtin/econ/calendar-model.ts +42 -17
- package/src/plugins/builtin/econ/detail-view.tsx +2 -2
- package/src/plugins/builtin/econ/fred-catalog.ts +189 -0
- package/src/plugins/builtin/econ/fred-series-map.ts +0 -46
- package/src/plugins/builtin/econ/index.tsx +70 -22
- package/src/plugins/builtin/econ-statistics/defs.ts +5 -0
- package/src/plugins/builtin/econ-statistics/headless.ts +30 -5
- package/src/plugins/builtin/econ-statistics/pane.tsx +1 -1
- package/src/plugins/builtin/econ-statistics/stats.ts +1 -0
- package/src/plugins/builtin/econ-statistics/view.ts +17 -0
- package/src/plugins/builtin/equity-screener/pane.tsx +4 -11
- package/src/plugins/builtin/executives/data.ts +17 -6
- package/src/plugins/builtin/executives/pane.tsx +16 -7
- package/src/plugins/builtin/exposure/holdings.ts +1 -1
- package/src/plugins/builtin/exposure/pane.tsx +3 -1
- package/src/plugins/builtin/fear-greed/index.tsx +4 -0
- package/src/plugins/builtin/fear-greed/series.ts +52 -0
- package/src/plugins/builtin/filing-events/pane.tsx +22 -5
- package/src/plugins/builtin/futures/index.tsx +43 -3
- package/src/plugins/builtin/futures/model.ts +1 -1
- package/src/plugins/builtin/futures/returns.ts +1 -1
- package/src/plugins/builtin/futures/series.ts +13 -0
- package/src/plugins/builtin/futures/table.tsx +1 -1
- package/src/plugins/builtin/futures/use-front-returns.ts +1 -1
- package/src/plugins/builtin/futures-curve/client.ts +12 -3
- package/src/plugins/builtin/futures-curve/headless.ts +70 -9
- package/src/plugins/builtin/futures-curve/index.tsx +1 -1
- package/src/plugins/builtin/futures-curve/model.ts +66 -11
- package/src/plugins/builtin/futures-curve/pane.tsx +52 -18
- package/src/plugins/builtin/fx-matrix/index.tsx +22 -1
- package/src/plugins/builtin/fx-matrix/pairs.ts +1 -1
- package/src/plugins/builtin/fx-matrix/settings.ts +42 -2
- package/src/plugins/builtin/gpu/board.tsx +13 -10
- package/src/plugins/builtin/gpu/changes.tsx +4 -4
- package/src/plugins/builtin/gpu/client.ts +19 -1
- package/src/plugins/builtin/gpu/equities.tsx +14 -10
- package/src/plugins/builtin/gpu/headless.ts +64 -27
- package/src/plugins/builtin/gpu/history.tsx +3 -3
- package/src/plugins/builtin/gpu/index.tsx +2 -0
- package/src/plugins/builtin/gpu/model.ts +114 -20
- package/src/plugins/builtin/gpu/pane.tsx +28 -12
- package/src/plugins/builtin/gpu/series.ts +38 -0
- package/src/plugins/builtin/help/function-card.tsx +25 -6
- package/src/plugins/builtin/help/index.tsx +18 -8
- package/src/plugins/builtin/holders/beneficial-client.ts +29 -7
- package/src/plugins/builtin/holders/beneficial-model.ts +90 -3
- package/src/plugins/builtin/holders/beneficial-report.ts +57 -5
- package/src/plugins/builtin/holders/beneficial-view.tsx +62 -14
- package/src/plugins/builtin/holders/client.ts +22 -3
- package/src/plugins/builtin/holders/format.ts +18 -3
- package/src/plugins/builtin/holders/headless.ts +42 -134
- package/src/plugins/builtin/holders/pane.tsx +14 -4
- package/src/plugins/builtin/holders/report-header.ts +40 -5
- package/src/plugins/builtin/holders/report-rows.ts +240 -0
- package/src/plugins/builtin/insider/client.ts +35 -20
- package/src/plugins/builtin/insider/headless.ts +41 -11
- package/src/plugins/builtin/insider/index.tsx +27 -10
- package/src/plugins/builtin/insider/insider-data.ts +10 -0
- package/src/plugins/builtin/insider/issuer.ts +49 -0
- package/src/plugins/builtin/insider/model.ts +3 -0
- package/src/plugins/builtin/iv-history/charts.tsx +21 -7
- package/src/plugins/builtin/iv-history/client.ts +26 -6
- package/src/plugins/builtin/iv-history/format.ts +33 -2
- package/src/plugins/builtin/iv-history/headless.ts +27 -12
- package/src/plugins/builtin/iv-history/index.tsx +5 -3
- package/src/plugins/builtin/iv-history/model.ts +172 -20
- package/src/plugins/builtin/iv-history/pane.tsx +11 -3
- package/src/plugins/builtin/iv-history/screen-pane.tsx +45 -25
- package/src/plugins/builtin/iv-history/series.ts +29 -0
- package/src/plugins/builtin/jobs/headless.ts +28 -3
- package/src/plugins/builtin/jobs/index.tsx +3 -1
- package/src/plugins/builtin/jobs/pane.tsx +1 -1
- package/src/plugins/builtin/jobs/series.ts +19 -0
- package/src/plugins/builtin/kelly-sizer/headless.ts +149 -0
- package/src/plugins/builtin/kelly-sizer/history.ts +80 -0
- package/src/plugins/builtin/kelly-sizer/index.tsx +2 -0
- package/src/plugins/builtin/kelly-sizer/pane.tsx +111 -40
- package/src/plugins/builtin/kelly-sizer/portfolio.ts +0 -39
- package/src/plugins/builtin/kelly-sizer/sections.tsx +14 -0
- package/src/plugins/builtin/kelly-sizer/types.ts +9 -1
- package/src/plugins/builtin/layout-manager/index.tsx +9 -1
- package/src/plugins/builtin/macro-day/client.ts +68 -3
- package/src/plugins/builtin/macro-day/headless.ts +18 -12
- package/src/plugins/builtin/macro-day/index.tsx +3 -0
- package/src/plugins/builtin/macro-day/model.ts +66 -15
- package/src/plugins/builtin/macro-day/pane.tsx +34 -20
- package/src/plugins/builtin/macro-day/release-table.ts +40 -0
- package/src/plugins/builtin/macro-day/releases.ts +62 -44
- package/src/plugins/builtin/market-heatmap/data.ts +25 -5
- package/src/plugins/builtin/market-heatmap/evidence.ts +90 -0
- package/src/plugins/builtin/market-heatmap/index.tsx +144 -63
- package/src/plugins/builtin/market-heatmap/model.ts +102 -3
- package/src/plugins/builtin/market-heatmap/portfolio.ts +12 -2
- package/src/plugins/builtin/market-movers/client.ts +7 -5
- package/src/plugins/builtin/market-movers/headless.ts +31 -4
- package/src/plugins/builtin/market-movers/index.tsx +11 -3
- package/src/plugins/builtin/market-movers/model.ts +101 -17
- package/src/plugins/builtin/market-movers/screener.ts +31 -0
- package/src/plugins/builtin/market-movers/table.ts +50 -23
- package/src/plugins/builtin/market-valuation/chart-series.ts +29 -69
- package/src/plugins/builtin/market-valuation/index.tsx +3 -3
- package/src/plugins/builtin/market-valuation/indicators.ts +0 -5
- package/src/plugins/builtin/members/headless.ts +7 -2
- package/src/plugins/builtin/members/model.ts +31 -3
- package/src/plugins/builtin/members/pane.tsx +3 -6
- package/src/plugins/builtin/mna/headless.ts +15 -3
- package/src/plugins/builtin/money-markets/index.tsx +2 -0
- package/src/plugins/builtin/money-markets/series.ts +41 -0
- package/src/plugins/builtin/news/headless.ts +9 -2
- package/src/plugins/builtin/news/wire/news/footer.ts +10 -0
- package/src/plugins/builtin/notes/cli.ts +12 -7
- package/src/plugins/builtin/openfda/client.ts +1 -1
- package/src/plugins/builtin/options/carry.ts +95 -0
- package/src/plugins/builtin/options/index.tsx +58 -5
- package/src/plugins/builtin/options/strike-window.ts +183 -0
- package/src/plugins/builtin/options/table.ts +55 -3
- package/src/plugins/builtin/options/types.ts +8 -1
- package/src/plugins/builtin/options/view.tsx +162 -13
- package/src/plugins/builtin/options-calculator/inputs.ts +2 -1
- package/src/plugins/builtin/options-positioning/client.ts +7 -3
- package/src/plugins/builtin/options-positioning/headless.ts +5 -2
- package/src/plugins/builtin/options-positioning/pane.tsx +2 -2
- package/src/plugins/builtin/options-scenario/charts.tsx +2 -2
- package/src/plugins/builtin/options-scenario/client.ts +75 -18
- package/src/plugins/builtin/options-scenario/headless.ts +72 -24
- package/src/plugins/builtin/options-scenario/hedge.ts +285 -0
- package/src/plugins/builtin/options-scenario/index.tsx +9 -2
- package/src/plugins/builtin/options-scenario/model.ts +33 -0
- package/src/plugins/builtin/options-scenario/pane.tsx +40 -16
- package/src/plugins/builtin/pe-band/model.ts +2 -2
- package/src/plugins/builtin/pe-band/report-dates.ts +11 -7
- package/src/plugins/builtin/perps/client.ts +40 -6
- package/src/plugins/builtin/perps/equity-row.tsx +33 -8
- package/src/plugins/builtin/perps/freshness.ts +66 -0
- package/src/plugins/builtin/perps/headless.ts +45 -30
- package/src/plugins/builtin/perps/index.tsx +18 -1
- package/src/plugins/builtin/perps/model.ts +32 -6
- package/src/plugins/builtin/perps/pane.tsx +76 -20
- package/src/plugins/builtin/perps/series.ts +76 -0
- package/src/plugins/builtin/plugin-marketplace/model.ts +64 -21
- package/src/plugins/builtin/plugin-marketplace/packs.ts +118 -0
- package/src/plugins/builtin/plugin-marketplace/pane.tsx +357 -39
- package/src/plugins/builtin/plugin-marketplace/store.ts +7 -1
- package/src/plugins/builtin/plugin-module.ts +90 -4
- package/src/plugins/builtin/portfolio-list/account-metrics.ts +1 -1
- package/src/plugins/builtin/portfolio-list/cli/bulk-symbols.ts +273 -0
- package/src/plugins/builtin/portfolio-list/cli/import-13f.ts +109 -0
- package/src/plugins/builtin/portfolio-list/cli/portfolio-command.ts +400 -99
- package/src/plugins/builtin/portfolio-list/cli/render.ts +281 -43
- package/src/plugins/builtin/portfolio-list/cli/shared.ts +26 -16
- package/src/plugins/builtin/portfolio-list/cli/watchlist-command.ts +120 -47
- package/src/plugins/builtin/portfolio-list/column-values.ts +1 -1
- package/src/plugins/builtin/portfolio-list/grid.tsx +1 -1
- package/src/plugins/builtin/portfolio-list/headless.ts +70 -9
- package/src/plugins/builtin/portfolio-list/imported-from.ts +8 -0
- package/src/plugins/builtin/portfolio-list/live-valuation.ts +6 -2
- package/src/plugins/builtin/portfolio-list/pane/index.tsx +6 -1
- package/src/plugins/builtin/portfolio-list/quick-add/index.tsx +17 -1
- package/src/plugins/builtin/portfolio-list/summary/totals.ts +1 -1
- package/src/plugins/builtin/portfolio-list/table.tsx +7 -1
- package/src/plugins/builtin/power/client.ts +16 -0
- package/src/plugins/builtin/power/evidence.ts +6 -2
- package/src/plugins/builtin/power/headless.ts +71 -7
- package/src/plugins/builtin/power/index.tsx +4 -1
- package/src/plugins/builtin/power/model.ts +72 -1
- package/src/plugins/builtin/power/pane.tsx +32 -9
- package/src/plugins/builtin/rate-path/headless.ts +11 -3
- package/src/plugins/builtin/realized-vol/headless.ts +8 -0
- package/src/plugins/builtin/realized-vol/pane.tsx +1 -1
- package/src/plugins/builtin/research/corporate-actions-pane.tsx +7 -4
- package/src/plugins/builtin/research/equity-diagnostic-pane.tsx +1 -1
- package/src/plugins/builtin/research/event-model.ts +68 -24
- package/src/plugins/builtin/research/events-headless.ts +2 -1
- package/src/plugins/builtin/research/headless.ts +2 -1
- package/src/plugins/builtin/revenue-breakdown/client.ts +13 -6
- package/src/plugins/builtin/revenue-breakdown/headless.ts +4 -1
- package/src/plugins/builtin/revenue-breakdown/pane.tsx +7 -4
- package/src/plugins/builtin/reverse-dcf/headless.ts +5 -1
- package/src/plugins/builtin/reverse-dcf/pane.tsx +1 -1
- package/src/plugins/builtin/risk-factors/data.ts +23 -9
- package/src/plugins/builtin/risk-factors/headless.ts +5 -2
- package/src/plugins/builtin/risk-factors/pane.tsx +6 -5
- package/src/plugins/builtin/seasonality/client.ts +15 -7
- package/src/plugins/builtin/seasonality/headless.ts +36 -12
- package/src/plugins/builtin/seasonality/index.tsx +2 -2
- package/src/plugins/builtin/seasonality/model.ts +119 -0
- package/src/plugins/builtin/seasonality/pane.tsx +108 -37
- package/src/plugins/builtin/sec/index.tsx +5 -5
- package/src/plugins/builtin/sectors/client.ts +10 -2
- package/src/plugins/builtin/sectors/headless.ts +35 -6
- package/src/plugins/builtin/sectors/index.tsx +18 -1
- package/src/plugins/builtin/sectors/sector-model.ts +150 -41
- package/src/plugins/builtin/series-inventory.ts +91 -0
- package/src/plugins/builtin/shared/cloud-upgrade.ts +1 -1
- package/src/plugins/builtin/shared/command-tab.ts +69 -0
- package/src/plugins/builtin/shared/earnings-report.ts +55 -0
- package/src/plugins/builtin/shared/fred-points.ts +20 -0
- package/src/plugins/builtin/shared/fx-rate-freshness.ts +101 -0
- package/src/plugins/builtin/shared/headless-market-data.ts +33 -1
- package/src/plugins/builtin/shared/members-menu.tsx +4 -4
- package/src/plugins/builtin/shared/open-description.ts +29 -0
- package/src/plugins/builtin/shared/report-freshness.ts +59 -2
- package/src/plugins/builtin/shared/series-warning.ts +5 -0
- package/src/plugins/builtin/shared/ticker-request.ts +25 -1
- package/src/plugins/builtin/shared/use-quote-board.ts +25 -5
- package/src/plugins/builtin/shared/volatility/options.ts +1 -46
- package/src/plugins/builtin/short-interest/headless.ts +1 -0
- package/src/plugins/builtin/short-interest/index.tsx +21 -4
- package/src/plugins/builtin/short-interest/series.ts +36 -0
- package/src/plugins/builtin/short-interest/surface.tsx +4 -4
- package/src/plugins/builtin/short-interest/watch-headless.ts +1 -0
- package/src/plugins/builtin/short-interest/watch-model.ts +9 -5
- package/src/plugins/builtin/short-volume/headless.ts +1 -0
- package/src/plugins/builtin/short-volume/index.tsx +3 -10
- package/src/plugins/builtin/short-volume/series.ts +23 -0
- package/src/plugins/builtin/social-mentions/index.tsx +2 -0
- package/src/plugins/builtin/social-mentions/series.ts +23 -0
- package/src/plugins/builtin/supply-chain/graph-pane.tsx +3 -2
- package/src/plugins/builtin/supply-chain/model.ts +1 -1
- package/src/plugins/builtin/supply-chain/pane.tsx +3 -1
- package/src/plugins/builtin/thirteenf/api.ts +1 -0
- package/src/plugins/builtin/thirteenf/data.ts +6 -4
- package/src/plugins/builtin/thirteenf/headless.ts +217 -36
- package/src/plugins/builtin/thirteenf/model.ts +39 -1
- package/src/plugins/builtin/thirteenf/overlap.ts +75 -0
- package/src/plugins/builtin/thirteenf/pane.tsx +10 -1
- package/src/plugins/builtin/thirteenf/report-notes.ts +103 -1
- package/src/plugins/builtin/thirteenf/types.ts +2 -0
- package/src/plugins/builtin/ticker-detail/headless.ts +43 -21
- package/src/plugins/builtin/ticker-detail/index.tsx +3 -0
- package/src/plugins/builtin/ticker-detail/overview/components.tsx +1 -1
- package/src/plugins/builtin/ticker-detail/overview/futures-contract.ts +31 -0
- package/src/plugins/builtin/ticker-detail/overview/model.ts +3 -3
- package/src/plugins/builtin/ticker-detail/overview/pane.tsx +2 -1
- package/src/plugins/builtin/ticker-detail/overview-tab.tsx +48 -4
- package/src/plugins/builtin/ticker-detail/pane.tsx +4 -5
- package/src/plugins/builtin/ticker-detail/quote-monitor/card.tsx +94 -6
- package/src/plugins/builtin/ticker-detail/quote-monitor/index.tsx +13 -3
- package/src/plugins/builtin/time-sales/headless.ts +1 -0
- package/src/plugins/builtin/treasury-auctions/cache.ts +5 -2
- package/src/plugins/builtin/treasury-auctions/client.ts +22 -8
- package/src/plugins/builtin/treasury-auctions/headless.ts +56 -6
- package/src/plugins/builtin/treasury-auctions/index.tsx +12 -9
- package/src/plugins/builtin/treasury-auctions/model.ts +205 -30
- package/src/plugins/builtin/treasury-auctions/pane.tsx +35 -11
- package/src/plugins/builtin/treasury-auctions/types.ts +11 -1
- package/src/plugins/builtin/vol-surface/charts.tsx +1 -3
- package/src/plugins/builtin/vol-surface/client.ts +6 -2
- package/src/plugins/builtin/vol-surface/evidence.ts +11 -6
- package/src/plugins/builtin/vol-surface/headless.ts +125 -20
- package/src/plugins/builtin/vol-surface/model.ts +23 -11
- package/src/plugins/builtin/vol-surface/pane.tsx +38 -27
- package/src/plugins/builtin/vol-surface/tables.ts +124 -0
- package/src/plugins/builtin/volatility/index.tsx +2 -0
- package/src/plugins/builtin/volatility/series.ts +84 -0
- package/src/plugins/builtin/world-indices/client.ts +22 -4
- package/src/plugins/builtin/world-indices/headless.ts +54 -27
- package/src/plugins/builtin/world-indices/model.ts +4 -2
- package/src/plugins/builtin/world-indices/table.tsx +13 -2
- package/src/plugins/builtin/world-venue-map/geo-series.ts +27 -2
- package/src/plugins/builtin/world-venue-map/headless.ts +4 -1
- package/src/plugins/builtin/world-venue-map/index.ts +3 -2
- package/src/plugins/builtin/world-venue-map/layered-pane.tsx +8 -4
- package/src/plugins/builtin/world-venue-map/layers.ts +29 -0
- package/src/plugins/builtin/yield-curve/chart.ts +2 -2
- package/src/plugins/builtin/yield-curve/curves.ts +21 -8
- package/src/plugins/builtin/yield-curve/headless.ts +71 -18
- package/src/plugins/builtin/yield-curve/index.tsx +4 -2
- package/src/plugins/builtin/yield-curve/series.ts +86 -0
- package/src/plugins/builtin-editorial.ts +126 -0
- package/src/plugins/catalog-backend.ts +16 -9
- package/src/plugins/catalog-browser.ts +129 -64
- package/src/plugins/catalog-manifest.ts +73 -40
- package/src/plugins/catalog-ui.ts +26 -6
- package/src/plugins/extracted-plugins.ts +7 -1
- package/src/plugins/ownership.ts +150 -7
- package/src/plugins/plugin-functions.ts +54 -0
- package/src/plugins/plugin-off.ts +36 -0
- package/src/plugins/registry/host-actions.ts +16 -0
- package/src/plugins/registry/index.ts +173 -28
- package/src/plugins/registry/plugin-state.ts +25 -1
- package/src/plugins/runtime/context.tsx +29 -0
- package/src/{plugins/builtin/portfolio-list → portfolio}/position-metrics.ts +6 -6
- package/src/portfolio/position-value.ts +40 -0
- package/src/public/__snapshots__/public-api.test.ts.snap +7 -0
- package/src/public/time-series.ts +17 -0
- package/src/react/auto-refresh.ts +13 -3
- package/src/react/input.ts +48 -1
- package/src/remote/app-host.tsx +25 -4
- package/src/remote/confirm-change.tsx +85 -0
- package/src/remote/controller-utils.ts +8 -1
- package/src/remote/controller.ts +126 -59
- package/src/remote/matching.ts +69 -0
- package/src/remote/pane-screenshot.ts +47 -0
- package/src/remote/schema.ts +63 -1
- package/src/remote/semantic-tree.tsx +14 -0
- package/src/remote/types.ts +32 -0
- package/src/remote/watchlist.ts +306 -0
- package/src/renderers/browser/main.tsx +3 -2
- package/src/renderers/cloudflare/worker.ts +1 -1
- package/src/renderers/dom/data-table/frozen-column.ts +3 -1
- package/src/renderers/dom/data-table/index.tsx +33 -6
- package/src/renderers/dom/data-table/row.tsx +27 -1
- package/src/renderers/dom/desktop/control-styles.ts +63 -1
- package/src/renderers/dom/desktop/controls.tsx +30 -23
- package/src/renderers/dom/desktop/dialog-actions.tsx +170 -0
- package/src/renderers/dom/desktop/icons.tsx +21 -0
- package/src/renderers/dom/desktop/query-bar.tsx +59 -32
- package/src/renderers/dom/dom-ui-host.tsx +3 -0
- package/src/renderers/dom/host/box.tsx +4 -1
- package/src/renderers/dom/host/chart-surface.tsx +6 -2
- package/src/renderers/dom/host/drag-shield.ts +17 -6
- package/src/renderers/dom/host/live-frame.ts +14 -2
- package/src/renderers/dom/host/overflow-fade.ts +14 -1
- package/src/renderers/dom/host/size-observer.ts +26 -0
- package/src/renderers/dom/host/surface-3d.tsx +7 -2
- package/src/renderers/dom/host/text.tsx +1 -1
- package/src/renderers/dom/input-host.tsx +6 -1
- package/src/renderers/dom/styles.css +74 -0
- package/src/renderers/electrobun/bun/desktop/backend.ts +5 -1
- package/src/renderers/electrobun/bun/desktop/detached-windows.ts +12 -1
- package/src/renderers/electrobun/bun/desktop/initialization.ts +2 -1
- package/src/renderers/electrobun/shared/protocol.ts +2 -0
- package/src/renderers/electrobun/view/cli-pane-shot-entry.tsx +18 -3
- package/src/renderers/electrobun/view/cli-pane-shot-frame.tsx +109 -5
- package/src/renderers/electrobun/view/cli-pane-shot-health.ts +10 -26
- package/src/renderers/electrobun/view/main.tsx +6 -1
- package/src/renderers/opentui/input-host.tsx +6 -1
- package/src/renderers/opentui/start.tsx +9 -0
- package/src/series/capability.ts +75 -0
- package/src/series/csv.ts +160 -0
- package/src/series/files.ts +107 -0
- package/src/series/registry.ts +198 -0
- package/src/series/resolve.ts +107 -0
- package/src/series/standalone.ts +48 -0
- package/src/series/types.ts +145 -0
- package/src/series/validate.ts +171 -0
- package/src/shares/portable-layout.ts +16 -6
- package/src/sources/gloomberb-cloud/index.ts +26 -17
- package/src/sources/gloomberb-cloud/normalizers.ts +5 -1
- package/src/sources/history-result.ts +1 -0
- package/src/sources/listing-symbols.ts +14 -5
- package/src/sources/provider-errors.ts +88 -3
- package/src/sources/provider-router/batches.ts +4 -1
- package/src/sources/provider-router/cache.ts +4 -2
- package/src/sources/provider-router/cached-routes.ts +9 -5
- package/src/sources/provider-router/financial-routes.ts +12 -5
- package/src/sources/provider-router/financials.ts +55 -15
- package/src/sources/provider-router/history.ts +68 -34
- package/src/sources/provider-router/index.ts +1 -1
- package/src/sources/provider-router/primary.ts +23 -5
- package/src/sources/provider-router/search.ts +1 -0
- package/src/sources/sec-edgar.ts +68 -8
- package/src/sync/core-contributors.ts +5 -3
- package/src/test-support/cli-context.ts +2 -1
- package/src/test-support/data-provider.ts +34 -0
- package/src/test-support/shell-pane-keys.tsx +1 -0
- package/src/theme/series-colors.ts +46 -0
- package/src/theme/themes.ts +149 -0
- package/src/tickers/company-name.ts +75 -0
- package/src/tickers/instrument-kind.ts +25 -0
- package/src/tickers/open-target.ts +3 -2
- package/src/tickers/search/index.ts +67 -9
- package/src/tickers/search/ranking.ts +78 -18
- package/src/tickers/search/types.ts +10 -2
- package/src/tickers/starter-symbols.ts +8 -0
- package/src/tickers/us-listing.ts +34 -0
- package/src/time-series/hooks.ts +9 -0
- package/src/time-series/resolve.ts +96 -30
- package/src/time-series/types.ts +4 -2
- package/src/time-series/use-chart-resolution.ts +32 -0
- package/src/types/config.ts +67 -1
- package/src/types/data-provider.ts +5 -0
- package/src/types/financials.ts +52 -1
- package/src/types/headless.ts +72 -0
- package/src/types/instrument.ts +8 -0
- package/src/types/plugin.ts +68 -3
- package/src/types/price-history.ts +7 -0
- package/src/types/ticker.ts +14 -0
- package/src/ui/host.tsx +26 -4
- package/src/ui/index.tsx +2 -0
- package/src/ui/live-resize.ts +81 -0
- package/src/ui/live-stretch.ts +121 -0
- package/src/ui/measured-cells.ts +58 -0
- package/src/ui/pane-fill.ts +11 -0
- package/src/utils/basis-points.ts +17 -0
- package/src/utils/cli-output.ts +21 -2
- package/src/utils/concurrency.ts +25 -0
- package/src/utils/crypto-pair.ts +20 -0
- package/src/utils/currency-pair.ts +19 -0
- package/src/utils/decimal-comma.ts +19 -0
- package/src/utils/dom-screenshot-css.ts +265 -0
- package/src/utils/dom-screenshot-rasters.ts +276 -0
- package/src/utils/dom-screenshot.ts +437 -52
- package/src/utils/exchange-rate-snapshot.ts +6 -2
- package/src/utils/exchanges.ts +120 -1
- package/src/utils/format.ts +17 -3
- package/src/utils/fundamentals.ts +66 -0
- package/src/utils/futures-generic.ts +6 -12
- package/src/utils/fx-market-hours.ts +44 -0
- package/src/utils/option-expiry.ts +126 -0
- package/src/utils/price-history.ts +130 -40
- package/src/utils/rpc-timeout-error.ts +6 -2
- package/src/utils/sec-eps-basis.ts +178 -36
- package/src/utils/sec.ts +98 -40
- package/src/utils/throttled-fetch.ts +51 -22
- package/src/utils/utc-time.ts +51 -4
|
@@ -1,6 +1,8 @@
|
|
|
1
1
|
import { useRef } from "react";
|
|
2
2
|
import { Box, Text, useUiCapabilities, type BoxRenderable } from "../../../../ui";
|
|
3
3
|
import { t } from "../../../../i18n";
|
|
4
|
+
import { displayWidth } from "../../../../utils/format";
|
|
5
|
+
import { chatAuthorName, isDiscordGhost } from "../ghost-user";
|
|
4
6
|
import { Button } from "../../../../components/ui";
|
|
5
7
|
import { MESSAGE_ACTION_WIDTH } from "../layout";
|
|
6
8
|
import type { ChatMessageRenderState } from "./render-state";
|
|
@@ -82,7 +84,9 @@ export function ChatMessageHeader({
|
|
|
82
84
|
/** The terminal sizes the author cell to its label. */
|
|
83
85
|
fitAuthorWidth?: boolean;
|
|
84
86
|
}) {
|
|
85
|
-
const authorLabel = msg.user
|
|
87
|
+
const authorLabel = chatAuthorName(msg.user);
|
|
88
|
+
// A Discord ghost has no Gloom profile to open and no one to message.
|
|
89
|
+
const hasProfile = !isDiscordGhost(msg.user);
|
|
86
90
|
const { nativeContextMenu } = useUiCapabilities();
|
|
87
91
|
// The card opens beside the name the pointer is on.
|
|
88
92
|
const nameRef = useRef<BoxRenderable | null>(null);
|
|
@@ -90,26 +94,31 @@ export function ChatMessageHeader({
|
|
|
90
94
|
<Box {...rowProps} flexDirection="row" height={1} paddingLeft={1}>
|
|
91
95
|
<Box
|
|
92
96
|
ref={nameRef}
|
|
93
|
-
width={fitAuthorWidth ? authorLabel
|
|
97
|
+
width={fitAuthorWidth ? displayWidth(authorLabel) : undefined}
|
|
94
98
|
height={1}
|
|
95
|
-
|
|
96
|
-
|
|
97
|
-
|
|
98
|
-
|
|
99
|
-
|
|
100
|
-
|
|
101
|
-
|
|
102
|
-
|
|
103
|
-
|
|
104
|
-
|
|
105
|
-
|
|
106
|
-
|
|
107
|
-
|
|
99
|
+
{...(hasProfile
|
|
100
|
+
? {
|
|
101
|
+
onMouseOver: () => onUserHover(msg.user, nameRef.current),
|
|
102
|
+
onMouseMove: () => onUserHover(msg.user, nameRef.current),
|
|
103
|
+
onMouseOut: onUserHoverEnd,
|
|
104
|
+
"data-gloom-context-menu-surface": "true",
|
|
105
|
+
onMouseDown: (event: { button?: number; preventDefault?: () => void; stopPropagation?: () => void }) => {
|
|
106
|
+
event.preventDefault?.();
|
|
107
|
+
event.stopPropagation?.();
|
|
108
|
+
// A native menu opens on the right-click's contextmenu event instead.
|
|
109
|
+
if (event.button === 2 && nativeContextMenu === true) return;
|
|
110
|
+
onUserActivate?.(msg.user, nameRef.current);
|
|
111
|
+
},
|
|
112
|
+
onContextMenu: (event: { preventDefault?: () => void; stopPropagation?: () => void }) => onUserContextMenu?.(msg.user, event, nameRef.current),
|
|
113
|
+
style: { cursor: "pointer" },
|
|
114
|
+
}
|
|
115
|
+
: {})}
|
|
108
116
|
>
|
|
109
117
|
<Text fg={state.authorColor} attributes={state.authorAttributes}>
|
|
110
118
|
{authorLabel}
|
|
111
119
|
</Text>
|
|
112
120
|
</Box>
|
|
121
|
+
{msg.origin === "discord" && <Text fg={state.originTagColor}> Discord</Text>}
|
|
113
122
|
<Text fg={state.headerStatusColor}> {state.headerStatus}</Text>
|
|
114
123
|
{(state.showReplyAction || (state.showRetryAction && actionProps.retryMessage)) && <Text fg={state.headerStatusColor}> </Text>}
|
|
115
124
|
<ChatMessageActions state={state} {...actionProps} />
|
|
@@ -5,6 +5,7 @@ import { colors } from "../../../../theme/colors";
|
|
|
5
5
|
import type { ChatUserSummary, PublicPortfolioAnalytics } from "../../../../api-client";
|
|
6
6
|
import { displayWidth, formatNumber, truncateToDisplayWidth } from "../../../../utils/format";
|
|
7
7
|
import { truncateWithEllipsis } from "../../../../utils/text-wrap";
|
|
8
|
+
import { isDiscordGhost } from "../ghost-user";
|
|
8
9
|
import type { ChatUserAnchor } from "./types";
|
|
9
10
|
|
|
10
11
|
/**
|
|
@@ -24,7 +25,7 @@ function hasPortfolioAnalytics(analytics: PublicPortfolioAnalytics | null | unde
|
|
|
24
25
|
}
|
|
25
26
|
|
|
26
27
|
export function hasPublicChatProfileInfo(user: ChatUserSummary): boolean {
|
|
27
|
-
if (user.profilePublic === false) return false;
|
|
28
|
+
if (user.profilePublic === false || isDiscordGhost(user)) return false;
|
|
28
29
|
return Boolean(user.bio?.trim() || user.title?.trim() || user.company?.trim() || hasPortfolioAnalytics(user.portfolioAnalytics));
|
|
29
30
|
}
|
|
30
31
|
|
|
@@ -20,6 +20,8 @@ export interface ChatMessageRenderState {
|
|
|
20
20
|
replyAuthorColor: string;
|
|
21
21
|
headerStatus: string;
|
|
22
22
|
headerStatusColor: string;
|
|
23
|
+
/** The dim "Discord" tag beside the author of a message that came from Discord. */
|
|
24
|
+
originTagColor: string;
|
|
23
25
|
authorColor: string;
|
|
24
26
|
authorAttributes: number;
|
|
25
27
|
bodyColor: string;
|
|
@@ -82,6 +84,7 @@ export function getChatMessageRenderState({
|
|
|
82
84
|
: hasFailed
|
|
83
85
|
? colors.negative
|
|
84
86
|
: colors.textMuted,
|
|
87
|
+
originTagColor: isSelected ? selectedTextColor : colors.textDim,
|
|
85
88
|
authorColor: isSelected ? selectedTextColor : hasFailed ? colors.negative : colors.positive,
|
|
86
89
|
authorAttributes: (isSending ? TextAttributes.DIM : 0) | TextAttributes.BOLD,
|
|
87
90
|
bodyColor: isSelected ? selectedTextColor : hasFailed ? colors.negative : isSending ? colors.textDim : colors.text,
|
|
@@ -0,0 +1,60 @@
|
|
|
1
|
+
import { useSyncExternalStore } from "react";
|
|
2
|
+
|
|
3
|
+
/**
|
|
4
|
+
* Something a Chat pane should do once it has the keyboard, asked for from
|
|
5
|
+
* outside it: the command bar opens a conversation to write in, or the New DM
|
|
6
|
+
* dialog. The pane that is focused on that conversation takes it.
|
|
7
|
+
*/
|
|
8
|
+
export type ChatPaneRequest =
|
|
9
|
+
| { action: "compose"; channelId: string }
|
|
10
|
+
| { action: "new-dm" };
|
|
11
|
+
|
|
12
|
+
interface PendingChatPaneRequest {
|
|
13
|
+
request: ChatPaneRequest;
|
|
14
|
+
at: number;
|
|
15
|
+
}
|
|
16
|
+
|
|
17
|
+
/** A request no pane took by then (the pane never opened) must not fire later. */
|
|
18
|
+
const REQUEST_TTL_MS = 10_000;
|
|
19
|
+
|
|
20
|
+
let pending: PendingChatPaneRequest | null = null;
|
|
21
|
+
const listeners = new Set<() => void>();
|
|
22
|
+
|
|
23
|
+
function emit(): void {
|
|
24
|
+
for (const listener of listeners) listener();
|
|
25
|
+
}
|
|
26
|
+
|
|
27
|
+
export function requestChatPaneAction(request: ChatPaneRequest, now = Date.now()): void {
|
|
28
|
+
pending = { request, at: now };
|
|
29
|
+
emit();
|
|
30
|
+
}
|
|
31
|
+
|
|
32
|
+
/**
|
|
33
|
+
* Hands the request to the pane on `channelId` and clears it. Null when there
|
|
34
|
+
* is none for that pane or it went stale.
|
|
35
|
+
*/
|
|
36
|
+
export function takeChatPaneRequest(channelId: string, now = Date.now()): ChatPaneRequest | null {
|
|
37
|
+
if (!pending) return null;
|
|
38
|
+
const { request, at } = pending;
|
|
39
|
+
if (now - at > REQUEST_TTL_MS) {
|
|
40
|
+
pending = null;
|
|
41
|
+
emit();
|
|
42
|
+
return null;
|
|
43
|
+
}
|
|
44
|
+
if (request.action === "compose" && request.channelId !== channelId) return null;
|
|
45
|
+
pending = null;
|
|
46
|
+
emit();
|
|
47
|
+
return request;
|
|
48
|
+
}
|
|
49
|
+
|
|
50
|
+
function subscribe(listener: () => void): () => void {
|
|
51
|
+
listeners.add(listener);
|
|
52
|
+
return () => {
|
|
53
|
+
listeners.delete(listener);
|
|
54
|
+
};
|
|
55
|
+
}
|
|
56
|
+
|
|
57
|
+
/** The request waiting for a pane, so a pane can take it once it has the keyboard. */
|
|
58
|
+
export function usePendingChatPaneRequest(): ChatPaneRequest | null {
|
|
59
|
+
return useSyncExternalStore(subscribe, () => pending?.request ?? null);
|
|
60
|
+
}
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
import { updatePaneInstance } from "../../../pane-settings";
|
|
2
|
-
import { removePane } from "../../../layout/pane-manager";
|
|
3
|
-
import type { AppConfig } from "../../../types/config";
|
|
2
|
+
import { isPaneInLayout, removePane } from "../../../layout/pane-manager";
|
|
3
|
+
import type { AppConfig, LayoutConfig, PaneInstanceConfig } from "../../../types/config";
|
|
4
4
|
import { LAST_VISITED_CHAT_CHANNEL_KEY, normalizeChannelId } from "./channels";
|
|
5
5
|
|
|
6
6
|
type ChatPaneSettings = Record<string, unknown>;
|
|
@@ -32,6 +32,36 @@ export function clearChatPaneTargetMessage(
|
|
|
32
32
|
return nextSettings;
|
|
33
33
|
}
|
|
34
34
|
|
|
35
|
+
function paneChannelId(instance: PaneInstanceConfig): string | null {
|
|
36
|
+
return typeof instance.settings?.channelId === "string" ? normalizeChannelId(instance.settings.channelId) : null;
|
|
37
|
+
}
|
|
38
|
+
|
|
39
|
+
/**
|
|
40
|
+
* The Chat pane the command bar shows a conversation in: the one already on
|
|
41
|
+
* it, else the focused one, else the one in front. Null when none is open, so
|
|
42
|
+
* the caller opens one.
|
|
43
|
+
*/
|
|
44
|
+
export function pickChatPaneToReuse(
|
|
45
|
+
layout: LayoutConfig,
|
|
46
|
+
focusedPaneId: string | null,
|
|
47
|
+
channelId: string | null,
|
|
48
|
+
): PaneInstanceConfig | null {
|
|
49
|
+
const chatPanes = layout.instances.filter((instance) => (
|
|
50
|
+
instance.paneId === "chat" && isPaneInLayout(layout, instance.instanceId)
|
|
51
|
+
));
|
|
52
|
+
if (chatPanes.length === 0) return null;
|
|
53
|
+
const onChannel = channelId ? chatPanes.find((instance) => paneChannelId(instance) === channelId) : undefined;
|
|
54
|
+
if (onChannel) return onChannel;
|
|
55
|
+
const focused = chatPanes.find((instance) => instance.instanceId === focusedPaneId);
|
|
56
|
+
if (focused) return focused;
|
|
57
|
+
// A floating pane without a stacking order sits at the default of 50; docked panes sit below every one.
|
|
58
|
+
const zIndexOf = (instance: PaneInstanceConfig) => {
|
|
59
|
+
const entry = layout.floating.find((floating) => floating.instanceId === instance.instanceId);
|
|
60
|
+
return entry ? entry.zIndex ?? 50 : -1;
|
|
61
|
+
};
|
|
62
|
+
return [...chatPanes].sort((left, right) => zIndexOf(right) - zIndexOf(left))[0] ?? null;
|
|
63
|
+
}
|
|
64
|
+
|
|
35
65
|
function setChatPaneJump(
|
|
36
66
|
settings: ChatPaneSettings | undefined,
|
|
37
67
|
channelId: string,
|
|
@@ -77,6 +77,14 @@ export function ChatPane({ focused, width, height }: PaneProps) {
|
|
|
77
77
|
}, [dispatch, paneId, stateRef]);
|
|
78
78
|
const [channelId, setLocalChannelId] = useState(initialChannelIdRef.current);
|
|
79
79
|
const pendingChannelIdRef = useRef<string | null>(null);
|
|
80
|
+
// A channel set from outside the pane (the command bar, the unread list)
|
|
81
|
+
// usually arrives with focus. Taking it in the same render keeps the pane
|
|
82
|
+
// from showing the old channel focused for a frame, which marks it read.
|
|
83
|
+
const [followedChannelId, setFollowedChannelId] = useState(persistedChannelId);
|
|
84
|
+
if (followedChannelId !== persistedChannelId) {
|
|
85
|
+
setFollowedChannelId(persistedChannelId);
|
|
86
|
+
if (!pendingChannelIdRef.current && channelId !== persistedChannelId) setLocalChannelId(persistedChannelId);
|
|
87
|
+
}
|
|
80
88
|
|
|
81
89
|
useEffect(() => {
|
|
82
90
|
if (rawPaneChannelId) return;
|
|
@@ -4,22 +4,28 @@ import {
|
|
|
4
4
|
type ASKGToolResultOutcome,
|
|
5
5
|
type ASKGTransport,
|
|
6
6
|
} from "../../../../api-client/askg";
|
|
7
|
-
import type
|
|
7
|
+
import { toolCallRemainingMs, type ASKGToolExecutor, type ASKGToolPreview } from "./executor";
|
|
8
8
|
import {
|
|
9
9
|
activeTurn,
|
|
10
10
|
askgReducer,
|
|
11
|
+
canRateTurn,
|
|
11
12
|
EMPTY_ASKG_CONVERSATION,
|
|
12
13
|
isTurnRunning,
|
|
14
|
+
NOT_APPROVED_IN_TIME_NOTE,
|
|
13
15
|
requiresLocalConfirmation,
|
|
14
16
|
type ASKGAction,
|
|
15
17
|
type ASKGConversationState,
|
|
16
18
|
type ASKGErrorState,
|
|
19
|
+
type ASKGTurnFeedback,
|
|
17
20
|
} from "./model";
|
|
18
21
|
import {
|
|
19
22
|
ASKG_CLIENT_CAPABILITIES,
|
|
20
23
|
ASKG_PROTOCOL_VERSION,
|
|
21
24
|
type ASKGCapabilities,
|
|
22
25
|
type ASKGClientDescriptor,
|
|
26
|
+
type ASKGFeedbackRating,
|
|
27
|
+
type ASKGFeedbackReason,
|
|
28
|
+
type ASKGFeedbackRequest,
|
|
23
29
|
type ASKGSessionContext,
|
|
24
30
|
type ASKGSessionStartResponse,
|
|
25
31
|
type ASKGSseEvent,
|
|
@@ -37,6 +43,18 @@ const MAX_HISTORY_TURNS = 8;
|
|
|
37
43
|
const DEFAULT_TURN_WALL_CLOCK_MS = 120_000;
|
|
38
44
|
/** Sessions are renegotiated a little before they expire. */
|
|
39
45
|
const SESSION_EXPIRY_GRACE_MS = 5_000;
|
|
46
|
+
/**
|
|
47
|
+
* A confirmation prompt closes this long before the server stops waiting for
|
|
48
|
+
* its call, so an approval still leaves time for the write and its result.
|
|
49
|
+
*/
|
|
50
|
+
export const CONFIRMATION_CLOSE_MARGIN_MS = 2_000;
|
|
51
|
+
|
|
52
|
+
/**
|
|
53
|
+
* How a confirmation prompt ended. `expired` is this app's own deadline for
|
|
54
|
+
* the call; `abandoned` is the turn giving up on it (the call timed out on the
|
|
55
|
+
* server, the turn ended, was cancelled or lost its stream).
|
|
56
|
+
*/
|
|
57
|
+
type ConfirmationAnswer = "approved" | "declined" | "expired" | "abandoned";
|
|
40
58
|
|
|
41
59
|
export interface ASKGControllerManifest {
|
|
42
60
|
tools: ClientToolManifest[];
|
|
@@ -104,6 +122,16 @@ function turnCapabilities(session: ASKGSessionStartResponse): ASKGCapabilities |
|
|
|
104
122
|
return session.capabilities?.scripts === 1 ? { scripts: 1 } : null;
|
|
105
123
|
}
|
|
106
124
|
|
|
125
|
+
/**
|
|
126
|
+
* Refusals that say ratings cannot work from here at all: signed out, no plan
|
|
127
|
+
* that reaches Ask Gloom, or a protocol this build does not speak. The control
|
|
128
|
+
* goes away rather than failing on every click.
|
|
129
|
+
*/
|
|
130
|
+
function feedbackUnavailable(error: unknown): boolean {
|
|
131
|
+
return error instanceof ASKGTransportError
|
|
132
|
+
&& (error.code === "unauthorized" || error.code === "tier_required" || error.code === "protocol");
|
|
133
|
+
}
|
|
134
|
+
|
|
107
135
|
function errorState(error: unknown): ASKGErrorState {
|
|
108
136
|
if (error instanceof ASKGTransportError) {
|
|
109
137
|
return {
|
|
@@ -131,11 +159,13 @@ export class ASKGSessionController {
|
|
|
131
159
|
private session: ASKGSessionStartResponse | null = null;
|
|
132
160
|
private sessionRequest: Promise<ASKGSessionStartResponse> | null = null;
|
|
133
161
|
private manifest: ASKGControllerManifest | null = null;
|
|
134
|
-
private readonly confirmations = new Map<string, (
|
|
135
|
-
/** Calls whose turn ended while they were still waiting to be approved. */
|
|
136
|
-
private readonly abandonedCalls = new Set<string>();
|
|
162
|
+
private readonly confirmations = new Map<string, (answer: ConfirmationAnswer) => void>();
|
|
137
163
|
private readonly toolTasks = new Set<Promise<void>>();
|
|
138
164
|
private turnAbort: AbortController | null = null;
|
|
165
|
+
/** Ratings of one answer go out in the order they were made. */
|
|
166
|
+
private readonly feedbackQueues = new Map<string, Promise<void>>();
|
|
167
|
+
/** The latest rating request per answer; an older answer never wins. */
|
|
168
|
+
private readonly feedbackVersions = new Map<string, number>();
|
|
139
169
|
private disposed = false;
|
|
140
170
|
private readonly now: () => number;
|
|
141
171
|
private readonly createId: () => string;
|
|
@@ -188,6 +218,7 @@ export class ASKGSessionController {
|
|
|
188
218
|
model: session.model,
|
|
189
219
|
limits: session.limits,
|
|
190
220
|
acceptedTools: session.acceptedTools,
|
|
221
|
+
feedback: session.capabilities?.feedback === 1,
|
|
191
222
|
});
|
|
192
223
|
return session;
|
|
193
224
|
})();
|
|
@@ -266,6 +297,8 @@ export class ASKGSessionController {
|
|
|
266
297
|
signal: abort.signal,
|
|
267
298
|
onEvent: (event) => this.handleEvent(event),
|
|
268
299
|
});
|
|
300
|
+
// The stream is over, so no approval can reach this turn any more.
|
|
301
|
+
this.abandonPendingConfirmations();
|
|
269
302
|
// Tool calls delivered late in the stream may still be running.
|
|
270
303
|
await Promise.allSettled([...this.toolTasks]);
|
|
271
304
|
} catch (error) {
|
|
@@ -311,14 +344,14 @@ export class ASKGSessionController {
|
|
|
311
344
|
}
|
|
312
345
|
|
|
313
346
|
/**
|
|
314
|
-
* Asks a failed question again. The
|
|
315
|
-
* above the retry, so a transcript reads as the conversation the
|
|
316
|
-
* rather than as a list of attempts.
|
|
347
|
+
* Asks a failed or stopped question again. The attempt is dropped rather
|
|
348
|
+
* than kept above the retry, so a transcript reads as the conversation the
|
|
349
|
+
* user had rather than as a list of attempts.
|
|
317
350
|
*/
|
|
318
351
|
async retryTurn(turnId: string): Promise<void> {
|
|
319
352
|
if (this.disposed || isTurnRunning(this.state)) return;
|
|
320
353
|
const turn = this.state.turns.find((entry) => entry.id === turnId);
|
|
321
|
-
if (!turn || turn.status !== "error") return;
|
|
354
|
+
if (!turn || (turn.status !== "error" && turn.status !== "cancelled")) return;
|
|
322
355
|
this.dispatch({ type: "drop-turn", turnId });
|
|
323
356
|
await this.ask(turn.prompt);
|
|
324
357
|
}
|
|
@@ -330,6 +363,13 @@ export class ASKGSessionController {
|
|
|
330
363
|
this.abandonPendingConfirmations();
|
|
331
364
|
return;
|
|
332
365
|
}
|
|
366
|
+
// The server reports a delegated call it gave up on (timed out, or its
|
|
367
|
+
// script ended) like one it got a result for. A prompt still open for it
|
|
368
|
+
// closes: an approval could no longer reach the turn.
|
|
369
|
+
if (event.type === "tool-executed") {
|
|
370
|
+
this.settleConfirmation(event.toolCallId, "abandoned");
|
|
371
|
+
return;
|
|
372
|
+
}
|
|
333
373
|
if (event.type !== "tool-call") return;
|
|
334
374
|
const task = this.runToolCall(event).finally(() => {
|
|
335
375
|
this.toolTasks.delete(task);
|
|
@@ -364,12 +404,43 @@ export class ASKGSessionController {
|
|
|
364
404
|
|
|
365
405
|
try {
|
|
366
406
|
let confirmed = false;
|
|
407
|
+
let confirmedChange: string | undefined;
|
|
367
408
|
if (requiresLocalConfirmation(call)) {
|
|
368
|
-
|
|
369
|
-
|
|
370
|
-
|
|
371
|
-
|
|
372
|
-
|
|
409
|
+
const preview = await this.previewCall(call, signal);
|
|
410
|
+
// The turn ended or moved on while the app looked.
|
|
411
|
+
if (signal?.aborted || this.toolRowStatus(call.toolCallId) !== "pending") return;
|
|
412
|
+
if (preview?.kind === "refusal") {
|
|
413
|
+
await this.deliver(failure(preview.message));
|
|
414
|
+
return;
|
|
415
|
+
}
|
|
416
|
+
if (preview?.kind === "change") confirmedChange = preview.confirmKey;
|
|
417
|
+
// Nothing to approve: the operation re-checks and asks in the app itself if that changed.
|
|
418
|
+
if (preview?.kind === "no-change") {
|
|
419
|
+
confirmed = true;
|
|
420
|
+
} else {
|
|
421
|
+
this.dispatch({
|
|
422
|
+
type: "tool-awaiting-confirmation",
|
|
423
|
+
toolCallId: call.toolCallId,
|
|
424
|
+
...(preview?.kind === "change" ? { preview: preview.summary } : {}),
|
|
425
|
+
});
|
|
426
|
+
const answer = await this.awaitConfirmation(
|
|
427
|
+
call.toolCallId,
|
|
428
|
+
startedAt + toolCallRemainingMs(call, startedAt),
|
|
429
|
+
);
|
|
430
|
+
if (answer === "abandoned") return;
|
|
431
|
+
if (answer === "expired") {
|
|
432
|
+
await this.deliver({
|
|
433
|
+
turnId: call.turnId,
|
|
434
|
+
toolCallId: call.toolCallId,
|
|
435
|
+
status: "timeout",
|
|
436
|
+
truncated: false,
|
|
437
|
+
elapsedMs: Math.max(0, this.now() - startedAt),
|
|
438
|
+
note: NOT_APPROVED_IN_TIME_NOTE,
|
|
439
|
+
});
|
|
440
|
+
return;
|
|
441
|
+
}
|
|
442
|
+
confirmed = answer === "approved";
|
|
443
|
+
}
|
|
373
444
|
if (!confirmed) {
|
|
374
445
|
await this.deliver({
|
|
375
446
|
turnId: call.turnId,
|
|
@@ -393,6 +464,7 @@ export class ASKGSessionController {
|
|
|
393
464
|
}
|
|
394
465
|
const payload = await executor.execute(call, {
|
|
395
466
|
confirmed: confirmed || !requiresLocalConfirmation(call),
|
|
467
|
+
...(confirmedChange ? { confirmedChange } : {}),
|
|
396
468
|
...(signal ? { signal } : {}),
|
|
397
469
|
});
|
|
398
470
|
await this.deliver(payload);
|
|
@@ -405,6 +477,28 @@ export class ASKGSessionController {
|
|
|
405
477
|
}
|
|
406
478
|
}
|
|
407
479
|
|
|
480
|
+
/**
|
|
481
|
+
* The operation's own account of a call that needs approval, when it has
|
|
482
|
+
* one. Null keeps the server's description.
|
|
483
|
+
*/
|
|
484
|
+
private async previewCall(call: ASKGToolCallEvent, signal?: AbortSignal): Promise<ASKGToolPreview | null> {
|
|
485
|
+
try {
|
|
486
|
+
const manifest = this.manifest ?? await this.options.loadManifest();
|
|
487
|
+
this.manifest = manifest;
|
|
488
|
+
return await this.options.getExecutor(manifest)?.preview?.(call, signal) ?? null;
|
|
489
|
+
} catch {
|
|
490
|
+
return null;
|
|
491
|
+
}
|
|
492
|
+
}
|
|
493
|
+
|
|
494
|
+
private toolRowStatus(toolCallId: string): string | undefined {
|
|
495
|
+
for (const turn of this.state.turns) {
|
|
496
|
+
const row = turn.tools.find((entry) => entry.toolCallId === toolCallId);
|
|
497
|
+
if (row) return row.status;
|
|
498
|
+
}
|
|
499
|
+
return undefined;
|
|
500
|
+
}
|
|
501
|
+
|
|
408
502
|
/** Records a tool result locally, then posts it to the turn loop. */
|
|
409
503
|
private async deliver(payload: ToolResultPayload): Promise<void> {
|
|
410
504
|
this.dispatch({ type: "tool-result", payload });
|
|
@@ -424,25 +518,131 @@ export class ASKGSessionController {
|
|
|
424
518
|
}
|
|
425
519
|
}
|
|
426
520
|
|
|
427
|
-
/**
|
|
428
|
-
|
|
521
|
+
/**
|
|
522
|
+
* Waits for the person's answer to one call. The prompt closes on its own
|
|
523
|
+
* a little before the server stops waiting (`deadlineAt`, by this clock),
|
|
524
|
+
* so an approval always has time to land; an older server that waits less
|
|
525
|
+
* than the call declared says so in the frame, and is honoured the same way.
|
|
526
|
+
*/
|
|
527
|
+
private awaitConfirmation(toolCallId: string, deadlineAt: number): Promise<ConfirmationAnswer> {
|
|
528
|
+
return new Promise<ConfirmationAnswer>((resolve) => {
|
|
529
|
+
const timer = setTimeout(
|
|
530
|
+
() => this.settleConfirmation(toolCallId, "expired"),
|
|
531
|
+
Math.max(0, deadlineAt - CONFIRMATION_CLOSE_MARGIN_MS - this.now()),
|
|
532
|
+
);
|
|
533
|
+
this.confirmations.set(toolCallId, (answer) => {
|
|
534
|
+
clearTimeout(timer);
|
|
535
|
+
resolve(answer);
|
|
536
|
+
});
|
|
537
|
+
});
|
|
538
|
+
}
|
|
539
|
+
|
|
540
|
+
/** Ends one prompt. Only the first answer counts; a later one does nothing. */
|
|
541
|
+
private settleConfirmation(toolCallId: string, answer: ConfirmationAnswer): void {
|
|
429
542
|
const resolve = this.confirmations.get(toolCallId);
|
|
430
543
|
if (!resolve) return;
|
|
431
544
|
this.confirmations.delete(toolCallId);
|
|
432
|
-
resolve(
|
|
545
|
+
resolve(answer);
|
|
433
546
|
}
|
|
434
547
|
|
|
435
|
-
|
|
436
|
-
|
|
437
|
-
|
|
438
|
-
resolve(false);
|
|
439
|
-
}
|
|
548
|
+
/** Answers a `user-data` or `broker` confirmation prompt. */
|
|
549
|
+
resolveConfirmation(toolCallId: string, approved: boolean): void {
|
|
550
|
+
this.settleConfirmation(toolCallId, approved ? "approved" : "declined");
|
|
440
551
|
}
|
|
441
552
|
|
|
442
553
|
/** Drops confirmations whose answer can no longer reach the turn. */
|
|
443
554
|
private abandonPendingConfirmations(): void {
|
|
444
|
-
for (const toolCallId of this.confirmations.keys())
|
|
445
|
-
|
|
555
|
+
for (const toolCallId of [...this.confirmations.keys()]) {
|
|
556
|
+
this.settleConfirmation(toolCallId, "abandoned");
|
|
557
|
+
}
|
|
558
|
+
}
|
|
559
|
+
|
|
560
|
+
/**
|
|
561
|
+
* Rates one answer. The control shows the choice at once; a refusal puts the
|
|
562
|
+
* previous one back without a word, because a rating is not worth an error.
|
|
563
|
+
* A thumbs down keeps the reason it already had, a thumbs up drops it.
|
|
564
|
+
*/
|
|
565
|
+
rateAnswer(turnId: string, rating: ASKGFeedbackRating): Promise<void> {
|
|
566
|
+
const current = this.state.turns.find((turn) => turn.id === turnId)?.feedback;
|
|
567
|
+
const reason = rating === "down" && current?.rating === "down" ? current.reason : null;
|
|
568
|
+
return this.sendFeedback(turnId, { rating, reason }, {
|
|
569
|
+
rating,
|
|
570
|
+
reason,
|
|
571
|
+
shared: current?.shared ?? false,
|
|
572
|
+
pending: "rating",
|
|
573
|
+
});
|
|
574
|
+
}
|
|
575
|
+
|
|
576
|
+
/** Says why an answer got a thumbs down. */
|
|
577
|
+
chooseFeedbackReason(turnId: string, reason: ASKGFeedbackReason): Promise<void> {
|
|
578
|
+
const current = this.state.turns.find((turn) => turn.id === turnId)?.feedback;
|
|
579
|
+
return this.sendFeedback(turnId, { rating: "down", reason }, {
|
|
580
|
+
rating: "down",
|
|
581
|
+
reason,
|
|
582
|
+
shared: current?.shared ?? false,
|
|
583
|
+
pending: "rating",
|
|
584
|
+
});
|
|
585
|
+
}
|
|
586
|
+
|
|
587
|
+
/**
|
|
588
|
+
* Sends one answer to Gloom with its rating. Only the consent travels: the
|
|
589
|
+
* platform copies the question, the answer and which tools ran from its own
|
|
590
|
+
* transcript, so nothing else on this machine can go with it.
|
|
591
|
+
*/
|
|
592
|
+
shareAnswer(turnId: string): Promise<void> {
|
|
593
|
+
const current = this.state.turns.find((turn) => turn.id === turnId)?.feedback;
|
|
594
|
+
if (!current?.rating || current.shared) return Promise.resolve();
|
|
595
|
+
return this.sendFeedback(
|
|
596
|
+
turnId,
|
|
597
|
+
{ rating: current.rating, reason: current.reason, share: true },
|
|
598
|
+
{ rating: current.rating, reason: current.reason, shared: false, pending: "share" },
|
|
599
|
+
);
|
|
600
|
+
}
|
|
601
|
+
|
|
602
|
+
private sendFeedback(
|
|
603
|
+
turnId: string,
|
|
604
|
+
request: ASKGFeedbackRequest,
|
|
605
|
+
optimistic: ASKGTurnFeedback,
|
|
606
|
+
): Promise<void> {
|
|
607
|
+
const turn = this.state.turns.find((entry) => entry.id === turnId);
|
|
608
|
+
if (this.disposed || !turn || !canRateTurn(this.state, turn) || !turn.remoteTurnId) {
|
|
609
|
+
return Promise.resolve();
|
|
610
|
+
}
|
|
611
|
+
const remoteTurnId = turn.remoteTurnId;
|
|
612
|
+
const previous = turn.feedback ? { ...turn.feedback, pending: null } : null;
|
|
613
|
+
const version = (this.feedbackVersions.get(turnId) ?? 0) + 1;
|
|
614
|
+
this.feedbackVersions.set(turnId, version);
|
|
615
|
+
this.dispatch({ type: "feedback", turnId, feedback: optimistic });
|
|
616
|
+
|
|
617
|
+
const send = async () => {
|
|
618
|
+
const latest = () => this.feedbackVersions.get(turnId) === version;
|
|
619
|
+
try {
|
|
620
|
+
const stored = await this.options.transport.sendFeedback(remoteTurnId, request);
|
|
621
|
+
if (!latest()) return;
|
|
622
|
+
if (!stored) {
|
|
623
|
+
// No answer of this person's under that id: nothing here can rate it.
|
|
624
|
+
this.dispatch({ type: "feedback", turnId, feedback: previous });
|
|
625
|
+
this.dispatch({ type: "feedback-unavailable" });
|
|
626
|
+
return;
|
|
627
|
+
}
|
|
628
|
+
this.dispatch({
|
|
629
|
+
type: "feedback",
|
|
630
|
+
turnId,
|
|
631
|
+
feedback: {
|
|
632
|
+
...stored,
|
|
633
|
+
pending: null,
|
|
634
|
+
...(request.share && !stored.shared ? { shareFailed: true } : {}),
|
|
635
|
+
},
|
|
636
|
+
});
|
|
637
|
+
} catch (error) {
|
|
638
|
+
if (!latest()) return;
|
|
639
|
+
this.dispatch({ type: "feedback", turnId, feedback: previous });
|
|
640
|
+
if (feedbackUnavailable(error)) this.dispatch({ type: "feedback-unavailable" });
|
|
641
|
+
}
|
|
642
|
+
};
|
|
643
|
+
const queued = (this.feedbackQueues.get(turnId) ?? Promise.resolve()).then(send);
|
|
644
|
+
this.feedbackQueues.set(turnId, queued);
|
|
645
|
+
return queued;
|
|
446
646
|
}
|
|
447
647
|
|
|
448
648
|
setExpanded(toolCallId: string, expanded: boolean): void {
|
|
@@ -46,6 +46,7 @@ export class ASKGConversationListStore {
|
|
|
46
46
|
private persistence: PluginPersistence | null = null;
|
|
47
47
|
private transport: ASKGTransport | null = null;
|
|
48
48
|
private inFlight: Promise<void> | null = null;
|
|
49
|
+
private openConversationId: string | null = null;
|
|
49
50
|
|
|
50
51
|
getSnapshot(): ASKGConversationListSnapshot {
|
|
51
52
|
return this.snapshot;
|
|
@@ -126,6 +127,7 @@ export class ASKGConversationListStore {
|
|
|
126
127
|
async delete(id: string): Promise<void> {
|
|
127
128
|
const transport = this.transport;
|
|
128
129
|
if (!transport) return;
|
|
130
|
+
if (this.openConversationId === id) this.openConversationId = null;
|
|
129
131
|
const previous = this.snapshot.conversations;
|
|
130
132
|
this.remove(id);
|
|
131
133
|
try {
|
|
@@ -178,11 +180,30 @@ export class ASKGConversationListStore {
|
|
|
178
180
|
this.persistence?.setState(WIDTH_STATE_KEY, width);
|
|
179
181
|
}
|
|
180
182
|
|
|
183
|
+
/**
|
|
184
|
+
* The conversation an Ask Gloom pane last showed. Closing the pane (Esc Esc
|
|
185
|
+
* is two keys) must not lose the answer on screen, so the next pane this
|
|
186
|
+
* app session opens picks it up again. Kept in memory only: a fresh launch
|
|
187
|
+
* starts a fresh conversation, and every older one is in the list.
|
|
188
|
+
*/
|
|
189
|
+
rememberOpen(id: string | null): void {
|
|
190
|
+
this.openConversationId = id;
|
|
191
|
+
}
|
|
192
|
+
|
|
193
|
+
rememberedOpen(): string | null {
|
|
194
|
+
const id = this.openConversationId;
|
|
195
|
+
if (!id) return null;
|
|
196
|
+
// A conversation deleted since is not brought back.
|
|
197
|
+
if (this.snapshot.loaded && !this.snapshot.conversations.some((conversation) => conversation.id === id)) return null;
|
|
198
|
+
return id;
|
|
199
|
+
}
|
|
200
|
+
|
|
181
201
|
/** Test hook: drops the persisted handle, the transport and the rows. */
|
|
182
202
|
reset(): void {
|
|
183
203
|
this.persistence = null;
|
|
184
204
|
this.transport = null;
|
|
185
205
|
this.inFlight = null;
|
|
206
|
+
this.openConversationId = null;
|
|
186
207
|
this.snapshot = EMPTY;
|
|
187
208
|
}
|
|
188
209
|
|