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.
Files changed (820) hide show
  1. package/README.md +14 -91
  2. package/package.json +7 -1
  3. package/src/{plugins/builtin/cloud → account}/auth-form.tsx +9 -9
  4. package/src/{plugins/builtin/cloud → account}/auth-model.ts +4 -4
  5. package/src/account/billing.ts +57 -0
  6. package/src/{plugins/builtin/cloud → account}/device-signin-dialog.tsx +18 -12
  7. package/src/{plugins/builtin/cloud → account}/device-signin.ts +2 -2
  8. package/src/{plugins/builtin/cloud → account}/email-auth-attempt.ts +2 -2
  9. package/src/account/session.ts +16 -0
  10. package/src/{plugins/builtin/cloud → account}/upgrade-dialog.tsx +42 -17
  11. package/src/account/upgrade-personalization.ts +57 -0
  12. package/src/account/upgrade-tickers.ts +124 -0
  13. package/src/{plugins/builtin/cloud → account}/verification-panel.tsx +6 -6
  14. package/src/api-client/askg.ts +43 -0
  15. package/src/api-client/auth.ts +15 -0
  16. package/src/api-client/beneficial-owners.ts +4 -0
  17. package/src/api-client/chat.ts +19 -0
  18. package/src/api-client/company-kpis.ts +14 -2
  19. package/src/api-client/data.ts +58 -18
  20. package/src/api-client/earnings.ts +6 -0
  21. package/src/api-client/futures-curve.ts +56 -0
  22. package/src/api-client/index.ts +16 -1
  23. package/src/api-client/market-discovery.ts +10 -1
  24. package/src/api-client/normalizers.ts +27 -0
  25. package/src/api-client/paths.ts +95 -23
  26. package/src/api-client/request.ts +2 -1
  27. package/src/api-client/research-activity.ts +46 -10
  28. package/src/api-client/socket.ts +39 -8
  29. package/src/api-client/types.ts +74 -2
  30. package/src/api-client/upgrade-experiment.ts +90 -0
  31. package/src/api-client/yield-curves.ts +8 -0
  32. package/src/app/global-shortcuts.ts +26 -2
  33. package/src/app/keybindings/actions.ts +10 -0
  34. package/src/app/pane-runtime/index.tsx +8 -0
  35. package/src/app/pane-runtime/pane-template-runtime.ts +5 -0
  36. package/src/app/pane-runtime/plugin-bindings.ts +65 -25
  37. package/src/app/pane-runtime/ticker-inspector-runtime.ts +12 -0
  38. package/src/app/pane-runtime/ticker-open-runtime.ts +25 -4
  39. package/src/app/runtime/desktop-deeplink.ts +5 -0
  40. package/src/app/star-prompt/model.ts +98 -0
  41. package/src/app/star-prompt/runtime.ts +41 -0
  42. package/src/app/star-prompt/status-line.tsx +190 -0
  43. package/src/app.tsx +13 -7
  44. package/src/architecture/core-builtin-allowlist.json +61 -0
  45. package/src/brokers/signed-in/adapter.ts +33 -2
  46. package/src/brokers/signed-in/client.ts +10 -0
  47. package/src/brokers/signed-in/sign-in-dialog.tsx +34 -14
  48. package/src/brokers/signed-in/sign-in.ts +62 -5
  49. package/src/capabilities/chart-series.ts +11 -1
  50. package/src/capabilities/registry.ts +8 -1
  51. package/src/capabilities/types.ts +2 -0
  52. package/src/cli/commands/crypto-hints.ts +19 -4
  53. package/src/cli/commands/fred-series.ts +61 -0
  54. package/src/cli/commands/market.ts +744 -181
  55. package/src/cli/commands/news-hints.ts +62 -0
  56. package/src/cli/commands/news-search.ts +53 -0
  57. package/src/cli/commands/options-chain.ts +172 -0
  58. package/src/cli/commands/options-leaps.ts +425 -0
  59. package/src/cli/commands/overview.ts +251 -40
  60. package/src/cli/commands/remote.ts +2 -1
  61. package/src/cli/commands/search.ts +109 -15
  62. package/src/cli/commands/system.ts +151 -24
  63. package/src/cli/commands/themes.ts +64 -0
  64. package/src/cli/commands/ticker.ts +149 -40
  65. package/src/cli/context.ts +45 -14
  66. package/src/cli/desktop-pane-shot.ts +150 -17
  67. package/src/cli/earnings-calendar.ts +71 -0
  68. package/src/cli/errors.ts +25 -2
  69. package/src/cli/freshness.ts +22 -8
  70. package/src/cli/fx-pair.ts +57 -0
  71. package/src/cli/glossary.ts +429 -0
  72. package/src/cli/help.ts +14 -1
  73. package/src/cli/history-rows.ts +48 -7
  74. package/src/cli/index-roots.ts +58 -0
  75. package/src/cli/index.ts +29 -12
  76. package/src/cli/known-gaps.ts +27 -0
  77. package/src/cli/listing-arg.ts +595 -26
  78. package/src/cli/not-a-ticker.ts +44 -0
  79. package/src/cli/options.ts +50 -6
  80. package/src/cli/pane-functions/access-gate.ts +5 -0
  81. package/src/cli/pane-functions/capabilities.ts +11 -4
  82. package/src/cli/pane-functions/catalog.ts +48 -7
  83. package/src/cli/pane-functions/data.ts +48 -13
  84. package/src/cli/pane-functions/discovery.ts +1 -0
  85. package/src/cli/pane-functions/dom.ts +41 -19
  86. package/src/cli/pane-functions/freshness.ts +531 -32
  87. package/src/cli/pane-functions/function-help.ts +77 -25
  88. package/src/cli/pane-functions/headless.ts +50 -21
  89. package/src/cli/pane-functions/index.ts +66 -10
  90. package/src/cli/pane-functions/market-session.ts +147 -0
  91. package/src/cli/pane-functions/options.ts +77 -25
  92. package/src/cli/pane-functions/report-notices.ts +81 -0
  93. package/src/cli/pane-functions/report.ts +19 -8
  94. package/src/cli/pane-functions/resolver.ts +53 -18
  95. package/src/cli/pane-functions/screenshot-evidence.ts +2 -0
  96. package/src/cli/pane-functions/screenshot.ts +199 -30
  97. package/src/cli/registry.ts +2 -1
  98. package/src/cli/report-tables.ts +3 -0
  99. package/src/cli/result.ts +53 -13
  100. package/src/cli/row-window.ts +76 -0
  101. package/src/cli/scroll-truncation.ts +34 -0
  102. package/src/cli/staged-tickers.ts +52 -0
  103. package/src/cli/symbol-args.ts +9 -0
  104. package/src/cli/symbol-list.ts +172 -0
  105. package/src/cli/ticker-resolution.ts +223 -30
  106. package/src/cli/types.ts +5 -0
  107. package/src/components/chart/composite/axis-overlays.tsx +6 -2
  108. package/src/components/chart/composite/composite-chart.tsx +83 -10
  109. package/src/components/chart/composite/legend.tsx +88 -8
  110. package/src/components/chart/composite/panel-surface.tsx +44 -17
  111. package/src/components/chart/composite/price-axis-labels.tsx +3 -1
  112. package/src/components/chart/composite/rasterizer.ts +64 -4
  113. package/src/components/chart/composite/series-cues.ts +71 -0
  114. package/src/components/chart/composite/text-renderer.ts +16 -8
  115. package/src/components/chart/composite/types.ts +3 -0
  116. package/src/components/command-bar/commands/direct/index.ts +9 -1
  117. package/src/components/command-bar/commands/plugin/items.ts +3 -1
  118. package/src/components/command-bar/commands/registry.ts +7 -0
  119. package/src/components/command-bar/layout-items/focused-pane.ts +38 -0
  120. package/src/components/command-bar/pane-templates/workflow.ts +5 -0
  121. package/src/components/command-bar/panel/index.tsx +11 -3
  122. package/src/components/command-bar/panel/runtime.ts +3 -0
  123. package/src/components/command-bar/panel/types.ts +2 -0
  124. package/src/components/command-bar/routes/root/command-items.ts +2 -0
  125. package/src/components/command-bar/routes/root/plugin-turn-on.ts +92 -0
  126. package/src/components/command-bar/routes/root/provider-search.ts +4 -3
  127. package/src/components/command-bar/routes/root/results.ts +40 -10
  128. package/src/components/command-bar/routes/root/runtime.ts +8 -0
  129. package/src/components/command-bar/routes/root/search-providers.ts +97 -14
  130. package/src/components/command-bar/routes/ticker-search/results.ts +12 -11
  131. package/src/components/command-bar/routes/ticker-search/route.ts +4 -3
  132. package/src/components/command-bar/surface/index.tsx +18 -4
  133. package/src/components/command-bar/theme-picker.tsx +48 -13
  134. package/src/components/command-bar/workflow/ops.ts +5 -3
  135. package/src/components/command-bar/workflow/tickers.ts +23 -4
  136. package/src/components/data-table/view.tsx +28 -9
  137. package/src/components/layout/detached-pane-shell.tsx +9 -0
  138. package/src/components/layout/floating-pane.tsx +9 -2
  139. package/src/components/layout/header.tsx +20 -5
  140. package/src/components/layout/market-summary.ts +23 -9
  141. package/src/components/layout/pane/content.tsx +40 -29
  142. package/src/components/layout/pane/cycle-order.ts +2 -11
  143. package/src/components/layout/pane/footer/index.tsx +6 -2
  144. package/src/components/layout/pane/footer/model.ts +35 -1
  145. package/src/components/layout/pane/header.tsx +26 -2
  146. package/src/components/layout/pane/index.tsx +12 -2
  147. package/src/components/layout/pane/sidebar.tsx +78 -10
  148. package/src/components/layout/pane/title.ts +1 -1
  149. package/src/components/layout/presentation.ts +22 -0
  150. package/src/components/layout/shell/active-drag.ts +21 -5
  151. package/src/components/layout/shell/drag/index.ts +43 -9
  152. package/src/components/layout/shell/drag/live.ts +87 -6
  153. package/src/components/layout/shell/drag/runtime.ts +62 -20
  154. package/src/components/layout/shell/index.tsx +71 -12
  155. package/src/components/layout/shell/layout-state.ts +5 -11
  156. package/src/components/layout/shell/menu.ts +33 -1
  157. package/src/components/layout/shell/native/pointer-runtime.ts +3 -1
  158. package/src/components/layout/shell/pane/actions.ts +2 -1
  159. package/src/components/layout/shell/pane/layers.tsx +216 -28
  160. package/src/components/layout/shell/pane/management-shortcuts.ts +5 -0
  161. package/src/components/layout/shell/pane/new-layout.ts +116 -0
  162. package/src/components/layout/shell/shortcuts.ts +5 -2
  163. package/src/components/layout/shell/terminal-pointer-runtime.ts +24 -0
  164. package/src/components/layout/shell/visible-layout.ts +44 -1
  165. package/src/components/layout/status-bar.tsx +4 -1
  166. package/src/components/markdown-text.tsx +69 -23
  167. package/src/components/metric-treemap/heat-surface.tsx +37 -9
  168. package/src/components/metric-treemap/heat-tiles.ts +48 -17
  169. package/src/components/onboarding/account-step/form-panel.tsx +1 -1
  170. package/src/components/onboarding/account-step/index.tsx +1 -1
  171. package/src/components/onboarding/account-step/qr-panel.tsx +1 -1
  172. package/src/components/onboarding/account-step/signed-in-panel.tsx +1 -1
  173. package/src/components/onboarding/onboarding-frame.tsx +33 -10
  174. package/src/components/onboarding/onboarding-keyboard.ts +1 -1
  175. package/src/components/onboarding/onboarding-wizard.tsx +50 -41
  176. package/src/components/onboarding/portfolio-step/positions-panel.tsx +5 -2
  177. package/src/components/onboarding/pro-step-layout.ts +86 -0
  178. package/src/components/onboarding/use-onboarding-upgrade.ts +8 -4
  179. package/src/components/onboarding/wizard-account.ts +2 -2
  180. package/src/components/pane-template-wizard.tsx +9 -1
  181. package/src/components/price-selector-dialog.tsx +11 -2
  182. package/src/components/sign-in-gate.tsx +3 -3
  183. package/src/components/ticker/list-table-view.tsx +24 -1
  184. package/src/components/ui/action-row.tsx +2 -1
  185. package/src/components/ui/button.tsx +17 -1
  186. package/src/components/ui/choice-dialog.tsx +6 -4
  187. package/src/components/ui/confirm-dialog.tsx +28 -18
  188. package/src/components/ui/data-table/index.tsx +49 -0
  189. package/src/components/ui/data-table/opentui/index.tsx +37 -6
  190. package/src/components/ui/data-table/types.ts +20 -1
  191. package/src/components/ui/data-table/visible-range.ts +2 -0
  192. package/src/components/ui/dialog-actions.tsx +64 -0
  193. package/src/components/ui/display.tsx +17 -3
  194. package/src/components/ui/frame.tsx +35 -2
  195. package/src/components/ui/icon.tsx +13 -2
  196. package/src/components/ui/index.ts +1 -1
  197. package/src/components/ui/text-prompt-dialog.tsx +11 -9
  198. package/src/core/connection-health.ts +1 -1
  199. package/src/core/state/app/layout-reducer.ts +89 -3
  200. package/src/core/state/app/state.ts +8 -5
  201. package/src/core/state/app/types.ts +13 -2
  202. package/src/data/cached-query.ts +2 -0
  203. package/src/data/config/layout.ts +55 -21
  204. package/src/data/config/store/fold-panes.ts +149 -0
  205. package/src/data/config/store/migrations.ts +7 -0
  206. package/src/data/config/store/node.ts +27 -6
  207. package/src/data/config/store/normalize.ts +44 -5
  208. package/src/data/ticker-repository.ts +5 -0
  209. package/src/data/ticker-store.ts +15 -0
  210. package/src/docs/content.ts +215 -0
  211. package/src/docs/load.ts +139 -0
  212. package/src/docs/requests.ts +39 -0
  213. package/src/docs/snapshot.chunk.ts +8 -0
  214. package/src/docs/snapshot.json +7416 -0
  215. package/src/docs/topics.ts +216 -0
  216. package/src/i18n/es.ts +75 -5
  217. package/src/i18n/ja.ts +75 -5
  218. package/src/i18n/ko.ts +75 -5
  219. package/src/i18n/zh-cn.ts +75 -5
  220. package/src/i18n/zh-tw.ts +75 -5
  221. package/src/layout/desks.ts +2 -3
  222. package/src/layout/pane-layout-move.ts +264 -0
  223. package/src/layout/pane-manager/dock-tree.ts +18 -0
  224. package/src/layout/pane-manager/hidden-panes.ts +160 -0
  225. package/src/layout/pane-manager/index.ts +2 -0
  226. package/src/market-data/coordinator/chart.ts +10 -4
  227. package/src/market-data/coordinator/entries.ts +7 -1
  228. package/src/market-data/coordinator/index.ts +6 -3
  229. package/src/market-data/coordinator/quotes.ts +2 -2
  230. package/src/{plugins/builtin/futures/contracts.ts → market-data/futures-board.ts} +81 -28
  231. package/src/market-data/futures-contract.ts +151 -0
  232. package/src/market-data/hooks.tsx +10 -2
  233. package/src/market-data/market/format.ts +39 -21
  234. package/src/market-data/market/freshness.ts +193 -30
  235. package/src/market-data/market/status.ts +59 -23
  236. package/src/market-data/options-alternatives.ts +69 -0
  237. package/src/market-data/published-apac-sessions.ts +23 -1
  238. package/src/market-data/quotes/contributions.ts +22 -2
  239. package/src/market-data/quotes/metadata.ts +8 -9
  240. package/src/market-data/quotes/resolution.ts +2 -0
  241. package/src/market-data/quotes/screener-live-quotes.ts +61 -9
  242. package/src/market-data/result-types.ts +2 -0
  243. package/src/plugins/builtin/account-management/keyboard.ts +3 -0
  244. package/src/plugins/builtin/account-management/model.ts +2 -56
  245. package/src/plugins/builtin/account-management/navigation.ts +1 -1
  246. package/src/plugins/builtin/account-management/pane.tsx +37 -8
  247. package/src/plugins/builtin/account-management/password-dialog.tsx +1 -1
  248. package/src/plugins/builtin/alerts/cli.ts +313 -47
  249. package/src/plugins/builtin/alerts/events-pane.tsx +45 -7
  250. package/src/plugins/builtin/alerts/events.ts +23 -2
  251. package/src/plugins/builtin/alerts/history-pane.tsx +7 -2
  252. package/src/plugins/builtin/alerts/history.ts +2 -0
  253. package/src/plugins/builtin/alerts/index.tsx +41 -9
  254. package/src/plugins/builtin/alerts/pane.tsx +8 -0
  255. package/src/plugins/builtin/alerts/quotes.ts +3 -0
  256. package/src/plugins/builtin/alerts/research-builder.ts +8 -3
  257. package/src/plugins/builtin/alerts/research-rules.ts +18 -2
  258. package/src/plugins/builtin/alerts/scheduled-check.ts +122 -0
  259. package/src/plugins/builtin/alerts/scheduled-sources.ts +25 -0
  260. package/src/plugins/builtin/alerts/scheduled.ts +254 -0
  261. package/src/plugins/builtin/alerts/targets.ts +92 -0
  262. package/src/plugins/builtin/analytics/index.tsx +4 -2
  263. package/src/plugins/builtin/analytics/risk-headless.ts +33 -13
  264. package/src/plugins/builtin/analytics/risk-math.ts +91 -27
  265. package/src/plugins/builtin/analytics/risk-model.ts +71 -12
  266. package/src/plugins/builtin/analytics/risk-pane.tsx +23 -12
  267. package/src/plugins/builtin/attention/index.tsx +2 -0
  268. package/src/plugins/builtin/attention/pane.tsx +3 -1
  269. package/src/plugins/builtin/attention/series.ts +26 -0
  270. package/src/plugins/builtin/awards/index.tsx +2 -0
  271. package/src/plugins/builtin/awards/pane.tsx +3 -1
  272. package/src/plugins/builtin/awards/series.ts +29 -0
  273. package/src/plugins/builtin/backtest/pane.tsx +1 -1
  274. package/src/plugins/builtin/bond-calculator/model.ts +2 -1
  275. package/src/plugins/builtin/broker-manager/detail.tsx +4 -0
  276. package/src/plugins/builtin/broker-manager/index.tsx +7 -3
  277. package/src/plugins/builtin/broker-manager/model.ts +8 -0
  278. package/src/plugins/builtin/broker-manager/pane-actions.tsx +8 -2
  279. package/src/plugins/builtin/broker-manager/sign-in-end.ts +82 -0
  280. package/src/plugins/builtin/broker-manager/table.ts +5 -0
  281. package/src/plugins/builtin/builtin-plugin-meta.ts +121 -11
  282. package/src/plugins/builtin/catalysts/pane.tsx +3 -1
  283. package/src/plugins/builtin/cds/client.ts +70 -13
  284. package/src/plugins/builtin/cds/headless.ts +116 -19
  285. package/src/plugins/builtin/cds/index.tsx +3 -1
  286. package/src/plugins/builtin/cds/model.ts +193 -31
  287. package/src/plugins/builtin/cds/pane.tsx +56 -14
  288. package/src/plugins/builtin/cds/series.ts +19 -0
  289. package/src/plugins/builtin/central-bank-rates/index.tsx +2 -0
  290. package/src/plugins/builtin/central-bank-rates/series.ts +42 -0
  291. package/src/plugins/builtin/chart-composer/catalog-inventory.ts +192 -255
  292. package/src/plugins/builtin/chart-composer/data-catalog-pane.tsx +84 -46
  293. package/src/plugins/builtin/chart-composer/editor.tsx +5 -4
  294. package/src/plugins/builtin/chart-composer/field-series.ts +40 -0
  295. package/src/plugins/builtin/chart-composer/headless.ts +8 -3
  296. package/src/plugins/builtin/chart-composer/index.tsx +9 -2
  297. package/src/plugins/builtin/chart-composer/pane.tsx +1 -1
  298. package/src/plugins/builtin/chart-composer/series-catalog.ts +58 -50
  299. package/src/plugins/builtin/chart-composer/series-expression.ts +18 -10
  300. package/src/plugins/builtin/chart-composer/use-series-catalog.ts +59 -3
  301. package/src/plugins/builtin/chart-composer/user-series.ts +84 -0
  302. package/src/plugins/builtin/chat/channels.ts +34 -36
  303. package/src/plugins/builtin/chat/command-bar.ts +138 -0
  304. package/src/plugins/builtin/chat/composer-commands.ts +21 -1
  305. package/src/plugins/builtin/chat/content/composer-runtime.ts +11 -1
  306. package/src/plugins/builtin/chat/content/footer.tsx +5 -3
  307. package/src/plugins/builtin/chat/content/index.tsx +21 -1
  308. package/src/plugins/builtin/chat/content/mentions.ts +2 -1
  309. package/src/plugins/builtin/chat/content/new-dm-dialog.tsx +10 -2
  310. package/src/plugins/builtin/chat/content/user-map.ts +3 -1
  311. package/src/plugins/builtin/chat/controller/index.ts +50 -0
  312. package/src/plugins/builtin/chat/conversations.ts +256 -0
  313. package/src/plugins/builtin/chat/discord-command.ts +91 -0
  314. package/src/plugins/builtin/chat/edit-window.ts +12 -6
  315. package/src/plugins/builtin/chat/ghost-user.ts +14 -0
  316. package/src/plugins/builtin/chat/index.tsx +40 -2
  317. package/src/plugins/builtin/chat/layout.ts +2 -0
  318. package/src/plugins/builtin/chat/message/desktop.tsx +2 -1
  319. package/src/plugins/builtin/chat/message/header.tsx +24 -15
  320. package/src/plugins/builtin/chat/message/profile-popover.tsx +2 -1
  321. package/src/plugins/builtin/chat/message/render-state.ts +3 -0
  322. package/src/plugins/builtin/chat/pane-requests.ts +60 -0
  323. package/src/plugins/builtin/chat/pane-state.ts +32 -2
  324. package/src/plugins/builtin/chat/pane.tsx +8 -0
  325. package/src/plugins/builtin/cloud/askg/controller.ts +223 -23
  326. package/src/plugins/builtin/cloud/askg/conversation-store.ts +21 -0
  327. package/src/plugins/builtin/cloud/askg/executor.ts +57 -3
  328. package/src/plugins/builtin/cloud/askg/manifest.ts +33 -7
  329. package/src/plugins/builtin/cloud/askg/model.ts +156 -78
  330. package/src/plugins/builtin/cloud/askg/pane.tsx +772 -377
  331. package/src/plugins/builtin/cloud/askg/protocol.ts +50 -3
  332. package/src/plugins/builtin/cloud/askg/tool-display.ts +440 -0
  333. package/src/plugins/builtin/cloud/askg/tool-timeline.tsx +403 -0
  334. package/src/plugins/builtin/cloud/askg/undo.ts +2 -0
  335. package/src/plugins/builtin/cloud/auth-actions.tsx +1 -1
  336. package/src/plugins/builtin/cloud/auth-commands.ts +1 -1
  337. package/src/plugins/builtin/cloud/auth-dialog.tsx +3 -3
  338. package/src/plugins/builtin/cloud/company-picker.tsx +1 -9
  339. package/src/plugins/builtin/cloud/mcp-connect/command.ts +24 -0
  340. package/src/plugins/builtin/cloud/mcp-connect/dialog.tsx +363 -0
  341. package/src/plugins/builtin/cloud/mcp-connect/model.ts +135 -0
  342. package/src/plugins/builtin/cloud/mcp-connect/sections.ts +62 -0
  343. package/src/plugins/builtin/cloud/plugin.tsx +36 -1
  344. package/src/plugins/builtin/cloud/terminal-relay/acm-tab.tsx +89 -0
  345. package/src/plugins/builtin/cloud/terminal-relay/client.ts +97 -0
  346. package/src/plugins/builtin/cloud/terminal-relay/connect-section.tsx +57 -0
  347. package/src/plugins/builtin/cloud/terminal-relay/engine.ts +734 -0
  348. package/src/plugins/builtin/cloud/terminal-relay/grants.ts +137 -0
  349. package/src/plugins/builtin/cloud/terminal-relay/host.tsx +81 -0
  350. package/src/plugins/builtin/cloud/terminal-relay/indicator.tsx +82 -0
  351. package/src/plugins/builtin/cloud/terminal-relay/manifest.ts +239 -0
  352. package/src/plugins/builtin/cloud/terminal-relay/policy.ts +162 -0
  353. package/src/plugins/builtin/cloud/terminal-relay/prompts.tsx +192 -0
  354. package/src/plugins/builtin/cloud/terminal-relay/redact.ts +73 -0
  355. package/src/plugins/builtin/cloud/terminal-relay/summary.ts +62 -0
  356. package/src/plugins/builtin/cloud/thesis/exposure.ts +1 -1
  357. package/src/plugins/builtin/cloud/thesis/prompts.tsx +2 -1
  358. package/src/plugins/builtin/comment-letters/client.ts +1 -3
  359. package/src/plugins/builtin/company-attention/app-rank.tsx +1 -1
  360. package/src/plugins/builtin/company-attention/headless.ts +19 -5
  361. package/src/plugins/builtin/company-attention/index.tsx +2 -0
  362. package/src/plugins/builtin/company-attention/model.ts +26 -7
  363. package/src/plugins/builtin/company-attention/pane.tsx +12 -9
  364. package/src/plugins/builtin/company-attention/series.ts +52 -0
  365. package/src/plugins/builtin/company-kpis/client.ts +23 -8
  366. package/src/plugins/builtin/company-kpis/headless.ts +3 -1
  367. package/src/plugins/builtin/company-kpis/pane.tsx +19 -9
  368. package/src/plugins/builtin/company-kpis/screenshot-evidence.ts +10 -3
  369. package/src/plugins/builtin/composite-plugins.ts +116 -67
  370. package/src/plugins/builtin/cot/index.tsx +3 -1
  371. package/src/plugins/builtin/cot/model.ts +40 -11
  372. package/src/plugins/builtin/cot/series.ts +27 -0
  373. package/src/plugins/builtin/credit-boards/cdx-pane.tsx +4 -4
  374. package/src/plugins/builtin/credit-boards/index.tsx +23 -21
  375. package/src/plugins/builtin/credit-boards/model.ts +0 -1
  376. package/src/plugins/builtin/credit-boards/pane.tsx +30 -0
  377. package/src/plugins/builtin/credit-boards/series.ts +66 -0
  378. package/src/plugins/builtin/credit-boards/sovr-pane.tsx +4 -4
  379. package/src/plugins/builtin/credit-conditions/index.tsx +2 -0
  380. package/src/plugins/builtin/credit-conditions/series.ts +26 -0
  381. package/src/plugins/builtin/credit-documents/headless.ts +31 -1
  382. package/src/plugins/builtin/credit-documents/pane.tsx +3 -1
  383. package/src/plugins/builtin/crypto-board/headless.ts +2 -3
  384. package/src/plugins/builtin/crypto-board/index.tsx +2 -0
  385. package/src/plugins/builtin/crypto-board/model.ts +12 -0
  386. package/src/plugins/builtin/crypto-board/pane.tsx +19 -12
  387. package/src/plugins/builtin/crypto-board/series.ts +48 -0
  388. package/src/plugins/builtin/custom-view/live-quotes.ts +2 -2
  389. package/src/plugins/builtin/debt-maturities/client.ts +37 -9
  390. package/src/plugins/builtin/debt-maturities/headless.ts +3 -1
  391. package/src/plugins/builtin/debt-maturities/index.tsx +2 -0
  392. package/src/plugins/builtin/debt-maturities/pane.tsx +5 -4
  393. package/src/plugins/builtin/debt-maturities/series.ts +45 -0
  394. package/src/plugins/builtin/dividend-yield/headless.ts +2 -2
  395. package/src/plugins/builtin/dividend-yield/index.tsx +3 -1
  396. package/src/plugins/builtin/dividend-yield/pane.tsx +1 -1
  397. package/src/plugins/builtin/dividend-yield/series.ts +20 -0
  398. package/src/plugins/builtin/docs/blocks.tsx +181 -0
  399. package/src/plugins/builtin/docs/index.tsx +68 -0
  400. package/src/plugins/builtin/docs/pane.tsx +426 -0
  401. package/src/plugins/builtin/docs/targets.ts +72 -0
  402. package/src/plugins/builtin/docs/use-docs.ts +60 -0
  403. package/src/plugins/builtin/doe/index.tsx +2 -0
  404. package/src/plugins/builtin/doe/series.ts +62 -0
  405. package/src/plugins/builtin/earnings/client.ts +3 -2
  406. package/src/plugins/builtin/earnings/format.ts +1 -5
  407. package/src/plugins/builtin/earnings/headless.ts +58 -6
  408. package/src/plugins/builtin/earnings/history-model.ts +15 -1
  409. package/src/plugins/builtin/earnings/history-table.ts +13 -2
  410. package/src/plugins/builtin/earnings/history.tsx +7 -3
  411. package/src/plugins/builtin/earnings-calls/data.ts +28 -7
  412. package/src/plugins/builtin/earnings-calls/headless.ts +3 -2
  413. package/src/plugins/builtin/earnings-calls/pane.tsx +10 -5
  414. package/src/plugins/builtin/econ/calendar-model.ts +42 -17
  415. package/src/plugins/builtin/econ/detail-view.tsx +2 -2
  416. package/src/plugins/builtin/econ/fred-catalog.ts +189 -0
  417. package/src/plugins/builtin/econ/fred-series-map.ts +0 -46
  418. package/src/plugins/builtin/econ/index.tsx +70 -22
  419. package/src/plugins/builtin/econ-statistics/defs.ts +5 -0
  420. package/src/plugins/builtin/econ-statistics/headless.ts +30 -5
  421. package/src/plugins/builtin/econ-statistics/pane.tsx +1 -1
  422. package/src/plugins/builtin/econ-statistics/stats.ts +1 -0
  423. package/src/plugins/builtin/econ-statistics/view.ts +17 -0
  424. package/src/plugins/builtin/equity-screener/pane.tsx +4 -11
  425. package/src/plugins/builtin/executives/data.ts +17 -6
  426. package/src/plugins/builtin/executives/pane.tsx +16 -7
  427. package/src/plugins/builtin/exposure/holdings.ts +1 -1
  428. package/src/plugins/builtin/exposure/pane.tsx +3 -1
  429. package/src/plugins/builtin/fear-greed/index.tsx +4 -0
  430. package/src/plugins/builtin/fear-greed/series.ts +52 -0
  431. package/src/plugins/builtin/filing-events/pane.tsx +22 -5
  432. package/src/plugins/builtin/futures/index.tsx +43 -3
  433. package/src/plugins/builtin/futures/model.ts +1 -1
  434. package/src/plugins/builtin/futures/returns.ts +1 -1
  435. package/src/plugins/builtin/futures/series.ts +13 -0
  436. package/src/plugins/builtin/futures/table.tsx +1 -1
  437. package/src/plugins/builtin/futures/use-front-returns.ts +1 -1
  438. package/src/plugins/builtin/futures-curve/client.ts +12 -3
  439. package/src/plugins/builtin/futures-curve/headless.ts +70 -9
  440. package/src/plugins/builtin/futures-curve/index.tsx +1 -1
  441. package/src/plugins/builtin/futures-curve/model.ts +66 -11
  442. package/src/plugins/builtin/futures-curve/pane.tsx +52 -18
  443. package/src/plugins/builtin/fx-matrix/index.tsx +22 -1
  444. package/src/plugins/builtin/fx-matrix/pairs.ts +1 -1
  445. package/src/plugins/builtin/fx-matrix/settings.ts +42 -2
  446. package/src/plugins/builtin/gpu/board.tsx +13 -10
  447. package/src/plugins/builtin/gpu/changes.tsx +4 -4
  448. package/src/plugins/builtin/gpu/client.ts +19 -1
  449. package/src/plugins/builtin/gpu/equities.tsx +14 -10
  450. package/src/plugins/builtin/gpu/headless.ts +64 -27
  451. package/src/plugins/builtin/gpu/history.tsx +3 -3
  452. package/src/plugins/builtin/gpu/index.tsx +2 -0
  453. package/src/plugins/builtin/gpu/model.ts +114 -20
  454. package/src/plugins/builtin/gpu/pane.tsx +28 -12
  455. package/src/plugins/builtin/gpu/series.ts +38 -0
  456. package/src/plugins/builtin/help/function-card.tsx +25 -6
  457. package/src/plugins/builtin/help/index.tsx +18 -8
  458. package/src/plugins/builtin/holders/beneficial-client.ts +29 -7
  459. package/src/plugins/builtin/holders/beneficial-model.ts +90 -3
  460. package/src/plugins/builtin/holders/beneficial-report.ts +57 -5
  461. package/src/plugins/builtin/holders/beneficial-view.tsx +62 -14
  462. package/src/plugins/builtin/holders/client.ts +22 -3
  463. package/src/plugins/builtin/holders/format.ts +18 -3
  464. package/src/plugins/builtin/holders/headless.ts +42 -134
  465. package/src/plugins/builtin/holders/pane.tsx +14 -4
  466. package/src/plugins/builtin/holders/report-header.ts +40 -5
  467. package/src/plugins/builtin/holders/report-rows.ts +240 -0
  468. package/src/plugins/builtin/insider/client.ts +35 -20
  469. package/src/plugins/builtin/insider/headless.ts +41 -11
  470. package/src/plugins/builtin/insider/index.tsx +27 -10
  471. package/src/plugins/builtin/insider/insider-data.ts +10 -0
  472. package/src/plugins/builtin/insider/issuer.ts +49 -0
  473. package/src/plugins/builtin/insider/model.ts +3 -0
  474. package/src/plugins/builtin/iv-history/charts.tsx +21 -7
  475. package/src/plugins/builtin/iv-history/client.ts +26 -6
  476. package/src/plugins/builtin/iv-history/format.ts +33 -2
  477. package/src/plugins/builtin/iv-history/headless.ts +27 -12
  478. package/src/plugins/builtin/iv-history/index.tsx +5 -3
  479. package/src/plugins/builtin/iv-history/model.ts +172 -20
  480. package/src/plugins/builtin/iv-history/pane.tsx +11 -3
  481. package/src/plugins/builtin/iv-history/screen-pane.tsx +45 -25
  482. package/src/plugins/builtin/iv-history/series.ts +29 -0
  483. package/src/plugins/builtin/jobs/headless.ts +28 -3
  484. package/src/plugins/builtin/jobs/index.tsx +3 -1
  485. package/src/plugins/builtin/jobs/pane.tsx +1 -1
  486. package/src/plugins/builtin/jobs/series.ts +19 -0
  487. package/src/plugins/builtin/kelly-sizer/headless.ts +149 -0
  488. package/src/plugins/builtin/kelly-sizer/history.ts +80 -0
  489. package/src/plugins/builtin/kelly-sizer/index.tsx +2 -0
  490. package/src/plugins/builtin/kelly-sizer/pane.tsx +111 -40
  491. package/src/plugins/builtin/kelly-sizer/portfolio.ts +0 -39
  492. package/src/plugins/builtin/kelly-sizer/sections.tsx +14 -0
  493. package/src/plugins/builtin/kelly-sizer/types.ts +9 -1
  494. package/src/plugins/builtin/layout-manager/index.tsx +9 -1
  495. package/src/plugins/builtin/macro-day/client.ts +68 -3
  496. package/src/plugins/builtin/macro-day/headless.ts +18 -12
  497. package/src/plugins/builtin/macro-day/index.tsx +3 -0
  498. package/src/plugins/builtin/macro-day/model.ts +66 -15
  499. package/src/plugins/builtin/macro-day/pane.tsx +34 -20
  500. package/src/plugins/builtin/macro-day/release-table.ts +40 -0
  501. package/src/plugins/builtin/macro-day/releases.ts +62 -44
  502. package/src/plugins/builtin/market-heatmap/data.ts +25 -5
  503. package/src/plugins/builtin/market-heatmap/evidence.ts +90 -0
  504. package/src/plugins/builtin/market-heatmap/index.tsx +144 -63
  505. package/src/plugins/builtin/market-heatmap/model.ts +102 -3
  506. package/src/plugins/builtin/market-heatmap/portfolio.ts +12 -2
  507. package/src/plugins/builtin/market-movers/client.ts +7 -5
  508. package/src/plugins/builtin/market-movers/headless.ts +31 -4
  509. package/src/plugins/builtin/market-movers/index.tsx +11 -3
  510. package/src/plugins/builtin/market-movers/model.ts +101 -17
  511. package/src/plugins/builtin/market-movers/screener.ts +31 -0
  512. package/src/plugins/builtin/market-movers/table.ts +50 -23
  513. package/src/plugins/builtin/market-valuation/chart-series.ts +29 -69
  514. package/src/plugins/builtin/market-valuation/index.tsx +3 -3
  515. package/src/plugins/builtin/market-valuation/indicators.ts +0 -5
  516. package/src/plugins/builtin/members/headless.ts +7 -2
  517. package/src/plugins/builtin/members/model.ts +31 -3
  518. package/src/plugins/builtin/members/pane.tsx +3 -6
  519. package/src/plugins/builtin/mna/headless.ts +15 -3
  520. package/src/plugins/builtin/money-markets/index.tsx +2 -0
  521. package/src/plugins/builtin/money-markets/series.ts +41 -0
  522. package/src/plugins/builtin/news/headless.ts +9 -2
  523. package/src/plugins/builtin/news/wire/news/footer.ts +10 -0
  524. package/src/plugins/builtin/notes/cli.ts +12 -7
  525. package/src/plugins/builtin/openfda/client.ts +1 -1
  526. package/src/plugins/builtin/options/carry.ts +95 -0
  527. package/src/plugins/builtin/options/index.tsx +58 -5
  528. package/src/plugins/builtin/options/strike-window.ts +183 -0
  529. package/src/plugins/builtin/options/table.ts +55 -3
  530. package/src/plugins/builtin/options/types.ts +8 -1
  531. package/src/plugins/builtin/options/view.tsx +162 -13
  532. package/src/plugins/builtin/options-calculator/inputs.ts +2 -1
  533. package/src/plugins/builtin/options-positioning/client.ts +7 -3
  534. package/src/plugins/builtin/options-positioning/headless.ts +5 -2
  535. package/src/plugins/builtin/options-positioning/pane.tsx +2 -2
  536. package/src/plugins/builtin/options-scenario/charts.tsx +2 -2
  537. package/src/plugins/builtin/options-scenario/client.ts +75 -18
  538. package/src/plugins/builtin/options-scenario/headless.ts +72 -24
  539. package/src/plugins/builtin/options-scenario/hedge.ts +285 -0
  540. package/src/plugins/builtin/options-scenario/index.tsx +9 -2
  541. package/src/plugins/builtin/options-scenario/model.ts +33 -0
  542. package/src/plugins/builtin/options-scenario/pane.tsx +40 -16
  543. package/src/plugins/builtin/pe-band/model.ts +2 -2
  544. package/src/plugins/builtin/pe-band/report-dates.ts +11 -7
  545. package/src/plugins/builtin/perps/client.ts +40 -6
  546. package/src/plugins/builtin/perps/equity-row.tsx +33 -8
  547. package/src/plugins/builtin/perps/freshness.ts +66 -0
  548. package/src/plugins/builtin/perps/headless.ts +45 -30
  549. package/src/plugins/builtin/perps/index.tsx +18 -1
  550. package/src/plugins/builtin/perps/model.ts +32 -6
  551. package/src/plugins/builtin/perps/pane.tsx +76 -20
  552. package/src/plugins/builtin/perps/series.ts +76 -0
  553. package/src/plugins/builtin/plugin-marketplace/model.ts +64 -21
  554. package/src/plugins/builtin/plugin-marketplace/packs.ts +118 -0
  555. package/src/plugins/builtin/plugin-marketplace/pane.tsx +357 -39
  556. package/src/plugins/builtin/plugin-marketplace/store.ts +7 -1
  557. package/src/plugins/builtin/plugin-module.ts +90 -4
  558. package/src/plugins/builtin/portfolio-list/account-metrics.ts +1 -1
  559. package/src/plugins/builtin/portfolio-list/cli/bulk-symbols.ts +273 -0
  560. package/src/plugins/builtin/portfolio-list/cli/import-13f.ts +109 -0
  561. package/src/plugins/builtin/portfolio-list/cli/portfolio-command.ts +400 -99
  562. package/src/plugins/builtin/portfolio-list/cli/render.ts +281 -43
  563. package/src/plugins/builtin/portfolio-list/cli/shared.ts +26 -16
  564. package/src/plugins/builtin/portfolio-list/cli/watchlist-command.ts +120 -47
  565. package/src/plugins/builtin/portfolio-list/column-values.ts +1 -1
  566. package/src/plugins/builtin/portfolio-list/grid.tsx +1 -1
  567. package/src/plugins/builtin/portfolio-list/headless.ts +70 -9
  568. package/src/plugins/builtin/portfolio-list/imported-from.ts +8 -0
  569. package/src/plugins/builtin/portfolio-list/live-valuation.ts +6 -2
  570. package/src/plugins/builtin/portfolio-list/pane/index.tsx +6 -1
  571. package/src/plugins/builtin/portfolio-list/quick-add/index.tsx +17 -1
  572. package/src/plugins/builtin/portfolio-list/summary/totals.ts +1 -1
  573. package/src/plugins/builtin/portfolio-list/table.tsx +7 -1
  574. package/src/plugins/builtin/power/client.ts +16 -0
  575. package/src/plugins/builtin/power/evidence.ts +6 -2
  576. package/src/plugins/builtin/power/headless.ts +71 -7
  577. package/src/plugins/builtin/power/index.tsx +4 -1
  578. package/src/plugins/builtin/power/model.ts +72 -1
  579. package/src/plugins/builtin/power/pane.tsx +32 -9
  580. package/src/plugins/builtin/rate-path/headless.ts +11 -3
  581. package/src/plugins/builtin/realized-vol/headless.ts +8 -0
  582. package/src/plugins/builtin/realized-vol/pane.tsx +1 -1
  583. package/src/plugins/builtin/research/corporate-actions-pane.tsx +7 -4
  584. package/src/plugins/builtin/research/equity-diagnostic-pane.tsx +1 -1
  585. package/src/plugins/builtin/research/event-model.ts +68 -24
  586. package/src/plugins/builtin/research/events-headless.ts +2 -1
  587. package/src/plugins/builtin/research/headless.ts +2 -1
  588. package/src/plugins/builtin/revenue-breakdown/client.ts +13 -6
  589. package/src/plugins/builtin/revenue-breakdown/headless.ts +4 -1
  590. package/src/plugins/builtin/revenue-breakdown/pane.tsx +7 -4
  591. package/src/plugins/builtin/reverse-dcf/headless.ts +5 -1
  592. package/src/plugins/builtin/reverse-dcf/pane.tsx +1 -1
  593. package/src/plugins/builtin/risk-factors/data.ts +23 -9
  594. package/src/plugins/builtin/risk-factors/headless.ts +5 -2
  595. package/src/plugins/builtin/risk-factors/pane.tsx +6 -5
  596. package/src/plugins/builtin/seasonality/client.ts +15 -7
  597. package/src/plugins/builtin/seasonality/headless.ts +36 -12
  598. package/src/plugins/builtin/seasonality/index.tsx +2 -2
  599. package/src/plugins/builtin/seasonality/model.ts +119 -0
  600. package/src/plugins/builtin/seasonality/pane.tsx +108 -37
  601. package/src/plugins/builtin/sec/index.tsx +5 -5
  602. package/src/plugins/builtin/sectors/client.ts +10 -2
  603. package/src/plugins/builtin/sectors/headless.ts +35 -6
  604. package/src/plugins/builtin/sectors/index.tsx +18 -1
  605. package/src/plugins/builtin/sectors/sector-model.ts +150 -41
  606. package/src/plugins/builtin/series-inventory.ts +91 -0
  607. package/src/plugins/builtin/shared/cloud-upgrade.ts +1 -1
  608. package/src/plugins/builtin/shared/command-tab.ts +69 -0
  609. package/src/plugins/builtin/shared/earnings-report.ts +55 -0
  610. package/src/plugins/builtin/shared/fred-points.ts +20 -0
  611. package/src/plugins/builtin/shared/fx-rate-freshness.ts +101 -0
  612. package/src/plugins/builtin/shared/headless-market-data.ts +33 -1
  613. package/src/plugins/builtin/shared/members-menu.tsx +4 -4
  614. package/src/plugins/builtin/shared/open-description.ts +29 -0
  615. package/src/plugins/builtin/shared/report-freshness.ts +59 -2
  616. package/src/plugins/builtin/shared/series-warning.ts +5 -0
  617. package/src/plugins/builtin/shared/ticker-request.ts +25 -1
  618. package/src/plugins/builtin/shared/use-quote-board.ts +25 -5
  619. package/src/plugins/builtin/shared/volatility/options.ts +1 -46
  620. package/src/plugins/builtin/short-interest/headless.ts +1 -0
  621. package/src/plugins/builtin/short-interest/index.tsx +21 -4
  622. package/src/plugins/builtin/short-interest/series.ts +36 -0
  623. package/src/plugins/builtin/short-interest/surface.tsx +4 -4
  624. package/src/plugins/builtin/short-interest/watch-headless.ts +1 -0
  625. package/src/plugins/builtin/short-interest/watch-model.ts +9 -5
  626. package/src/plugins/builtin/short-volume/headless.ts +1 -0
  627. package/src/plugins/builtin/short-volume/index.tsx +3 -10
  628. package/src/plugins/builtin/short-volume/series.ts +23 -0
  629. package/src/plugins/builtin/social-mentions/index.tsx +2 -0
  630. package/src/plugins/builtin/social-mentions/series.ts +23 -0
  631. package/src/plugins/builtin/supply-chain/graph-pane.tsx +3 -2
  632. package/src/plugins/builtin/supply-chain/model.ts +1 -1
  633. package/src/plugins/builtin/supply-chain/pane.tsx +3 -1
  634. package/src/plugins/builtin/thirteenf/api.ts +1 -0
  635. package/src/plugins/builtin/thirteenf/data.ts +6 -4
  636. package/src/plugins/builtin/thirteenf/headless.ts +217 -36
  637. package/src/plugins/builtin/thirteenf/model.ts +39 -1
  638. package/src/plugins/builtin/thirteenf/overlap.ts +75 -0
  639. package/src/plugins/builtin/thirteenf/pane.tsx +10 -1
  640. package/src/plugins/builtin/thirteenf/report-notes.ts +103 -1
  641. package/src/plugins/builtin/thirteenf/types.ts +2 -0
  642. package/src/plugins/builtin/ticker-detail/headless.ts +43 -21
  643. package/src/plugins/builtin/ticker-detail/index.tsx +3 -0
  644. package/src/plugins/builtin/ticker-detail/overview/components.tsx +1 -1
  645. package/src/plugins/builtin/ticker-detail/overview/futures-contract.ts +31 -0
  646. package/src/plugins/builtin/ticker-detail/overview/model.ts +3 -3
  647. package/src/plugins/builtin/ticker-detail/overview/pane.tsx +2 -1
  648. package/src/plugins/builtin/ticker-detail/overview-tab.tsx +48 -4
  649. package/src/plugins/builtin/ticker-detail/pane.tsx +4 -5
  650. package/src/plugins/builtin/ticker-detail/quote-monitor/card.tsx +94 -6
  651. package/src/plugins/builtin/ticker-detail/quote-monitor/index.tsx +13 -3
  652. package/src/plugins/builtin/time-sales/headless.ts +1 -0
  653. package/src/plugins/builtin/treasury-auctions/cache.ts +5 -2
  654. package/src/plugins/builtin/treasury-auctions/client.ts +22 -8
  655. package/src/plugins/builtin/treasury-auctions/headless.ts +56 -6
  656. package/src/plugins/builtin/treasury-auctions/index.tsx +12 -9
  657. package/src/plugins/builtin/treasury-auctions/model.ts +205 -30
  658. package/src/plugins/builtin/treasury-auctions/pane.tsx +35 -11
  659. package/src/plugins/builtin/treasury-auctions/types.ts +11 -1
  660. package/src/plugins/builtin/vol-surface/charts.tsx +1 -3
  661. package/src/plugins/builtin/vol-surface/client.ts +6 -2
  662. package/src/plugins/builtin/vol-surface/evidence.ts +11 -6
  663. package/src/plugins/builtin/vol-surface/headless.ts +125 -20
  664. package/src/plugins/builtin/vol-surface/model.ts +23 -11
  665. package/src/plugins/builtin/vol-surface/pane.tsx +38 -27
  666. package/src/plugins/builtin/vol-surface/tables.ts +124 -0
  667. package/src/plugins/builtin/volatility/index.tsx +2 -0
  668. package/src/plugins/builtin/volatility/series.ts +84 -0
  669. package/src/plugins/builtin/world-indices/client.ts +22 -4
  670. package/src/plugins/builtin/world-indices/headless.ts +54 -27
  671. package/src/plugins/builtin/world-indices/model.ts +4 -2
  672. package/src/plugins/builtin/world-indices/table.tsx +13 -2
  673. package/src/plugins/builtin/world-venue-map/geo-series.ts +27 -2
  674. package/src/plugins/builtin/world-venue-map/headless.ts +4 -1
  675. package/src/plugins/builtin/world-venue-map/index.ts +3 -2
  676. package/src/plugins/builtin/world-venue-map/layered-pane.tsx +8 -4
  677. package/src/plugins/builtin/world-venue-map/layers.ts +29 -0
  678. package/src/plugins/builtin/yield-curve/chart.ts +2 -2
  679. package/src/plugins/builtin/yield-curve/curves.ts +21 -8
  680. package/src/plugins/builtin/yield-curve/headless.ts +71 -18
  681. package/src/plugins/builtin/yield-curve/index.tsx +4 -2
  682. package/src/plugins/builtin/yield-curve/series.ts +86 -0
  683. package/src/plugins/builtin-editorial.ts +126 -0
  684. package/src/plugins/catalog-backend.ts +16 -9
  685. package/src/plugins/catalog-browser.ts +129 -64
  686. package/src/plugins/catalog-manifest.ts +73 -40
  687. package/src/plugins/catalog-ui.ts +26 -6
  688. package/src/plugins/extracted-plugins.ts +7 -1
  689. package/src/plugins/ownership.ts +150 -7
  690. package/src/plugins/plugin-functions.ts +54 -0
  691. package/src/plugins/plugin-off.ts +36 -0
  692. package/src/plugins/registry/host-actions.ts +16 -0
  693. package/src/plugins/registry/index.ts +173 -28
  694. package/src/plugins/registry/plugin-state.ts +25 -1
  695. package/src/plugins/runtime/context.tsx +29 -0
  696. package/src/{plugins/builtin/portfolio-list → portfolio}/position-metrics.ts +6 -6
  697. package/src/portfolio/position-value.ts +40 -0
  698. package/src/public/__snapshots__/public-api.test.ts.snap +7 -0
  699. package/src/public/time-series.ts +17 -0
  700. package/src/react/auto-refresh.ts +13 -3
  701. package/src/react/input.ts +48 -1
  702. package/src/remote/app-host.tsx +25 -4
  703. package/src/remote/confirm-change.tsx +85 -0
  704. package/src/remote/controller-utils.ts +8 -1
  705. package/src/remote/controller.ts +126 -59
  706. package/src/remote/matching.ts +69 -0
  707. package/src/remote/pane-screenshot.ts +47 -0
  708. package/src/remote/schema.ts +63 -1
  709. package/src/remote/semantic-tree.tsx +14 -0
  710. package/src/remote/types.ts +32 -0
  711. package/src/remote/watchlist.ts +306 -0
  712. package/src/renderers/browser/main.tsx +3 -2
  713. package/src/renderers/cloudflare/worker.ts +1 -1
  714. package/src/renderers/dom/data-table/frozen-column.ts +3 -1
  715. package/src/renderers/dom/data-table/index.tsx +33 -6
  716. package/src/renderers/dom/data-table/row.tsx +27 -1
  717. package/src/renderers/dom/desktop/control-styles.ts +63 -1
  718. package/src/renderers/dom/desktop/controls.tsx +30 -23
  719. package/src/renderers/dom/desktop/dialog-actions.tsx +170 -0
  720. package/src/renderers/dom/desktop/icons.tsx +21 -0
  721. package/src/renderers/dom/desktop/query-bar.tsx +59 -32
  722. package/src/renderers/dom/dom-ui-host.tsx +3 -0
  723. package/src/renderers/dom/host/box.tsx +4 -1
  724. package/src/renderers/dom/host/chart-surface.tsx +6 -2
  725. package/src/renderers/dom/host/drag-shield.ts +17 -6
  726. package/src/renderers/dom/host/live-frame.ts +14 -2
  727. package/src/renderers/dom/host/overflow-fade.ts +14 -1
  728. package/src/renderers/dom/host/size-observer.ts +26 -0
  729. package/src/renderers/dom/host/surface-3d.tsx +7 -2
  730. package/src/renderers/dom/host/text.tsx +1 -1
  731. package/src/renderers/dom/input-host.tsx +6 -1
  732. package/src/renderers/dom/styles.css +74 -0
  733. package/src/renderers/electrobun/bun/desktop/backend.ts +5 -1
  734. package/src/renderers/electrobun/bun/desktop/detached-windows.ts +12 -1
  735. package/src/renderers/electrobun/bun/desktop/initialization.ts +2 -1
  736. package/src/renderers/electrobun/shared/protocol.ts +2 -0
  737. package/src/renderers/electrobun/view/cli-pane-shot-entry.tsx +18 -3
  738. package/src/renderers/electrobun/view/cli-pane-shot-frame.tsx +109 -5
  739. package/src/renderers/electrobun/view/cli-pane-shot-health.ts +10 -26
  740. package/src/renderers/electrobun/view/main.tsx +6 -1
  741. package/src/renderers/opentui/input-host.tsx +6 -1
  742. package/src/renderers/opentui/start.tsx +9 -0
  743. package/src/series/capability.ts +75 -0
  744. package/src/series/csv.ts +160 -0
  745. package/src/series/files.ts +107 -0
  746. package/src/series/registry.ts +198 -0
  747. package/src/series/resolve.ts +107 -0
  748. package/src/series/standalone.ts +48 -0
  749. package/src/series/types.ts +145 -0
  750. package/src/series/validate.ts +171 -0
  751. package/src/shares/portable-layout.ts +16 -6
  752. package/src/sources/gloomberb-cloud/index.ts +26 -17
  753. package/src/sources/gloomberb-cloud/normalizers.ts +5 -1
  754. package/src/sources/history-result.ts +1 -0
  755. package/src/sources/listing-symbols.ts +14 -5
  756. package/src/sources/provider-errors.ts +88 -3
  757. package/src/sources/provider-router/batches.ts +4 -1
  758. package/src/sources/provider-router/cache.ts +4 -2
  759. package/src/sources/provider-router/cached-routes.ts +9 -5
  760. package/src/sources/provider-router/financial-routes.ts +12 -5
  761. package/src/sources/provider-router/financials.ts +55 -15
  762. package/src/sources/provider-router/history.ts +68 -34
  763. package/src/sources/provider-router/index.ts +1 -1
  764. package/src/sources/provider-router/primary.ts +23 -5
  765. package/src/sources/provider-router/search.ts +1 -0
  766. package/src/sources/sec-edgar.ts +68 -8
  767. package/src/sync/core-contributors.ts +5 -3
  768. package/src/test-support/cli-context.ts +2 -1
  769. package/src/test-support/data-provider.ts +34 -0
  770. package/src/test-support/shell-pane-keys.tsx +1 -0
  771. package/src/theme/series-colors.ts +46 -0
  772. package/src/theme/themes.ts +149 -0
  773. package/src/tickers/company-name.ts +75 -0
  774. package/src/tickers/instrument-kind.ts +25 -0
  775. package/src/tickers/open-target.ts +3 -2
  776. package/src/tickers/search/index.ts +67 -9
  777. package/src/tickers/search/ranking.ts +78 -18
  778. package/src/tickers/search/types.ts +10 -2
  779. package/src/tickers/starter-symbols.ts +8 -0
  780. package/src/tickers/us-listing.ts +34 -0
  781. package/src/time-series/hooks.ts +9 -0
  782. package/src/time-series/resolve.ts +96 -30
  783. package/src/time-series/types.ts +4 -2
  784. package/src/time-series/use-chart-resolution.ts +32 -0
  785. package/src/types/config.ts +67 -1
  786. package/src/types/data-provider.ts +5 -0
  787. package/src/types/financials.ts +52 -1
  788. package/src/types/headless.ts +72 -0
  789. package/src/types/instrument.ts +8 -0
  790. package/src/types/plugin.ts +68 -3
  791. package/src/types/price-history.ts +7 -0
  792. package/src/types/ticker.ts +14 -0
  793. package/src/ui/host.tsx +26 -4
  794. package/src/ui/index.tsx +2 -0
  795. package/src/ui/live-resize.ts +81 -0
  796. package/src/ui/live-stretch.ts +121 -0
  797. package/src/ui/measured-cells.ts +58 -0
  798. package/src/ui/pane-fill.ts +11 -0
  799. package/src/utils/basis-points.ts +17 -0
  800. package/src/utils/cli-output.ts +21 -2
  801. package/src/utils/concurrency.ts +25 -0
  802. package/src/utils/crypto-pair.ts +20 -0
  803. package/src/utils/currency-pair.ts +19 -0
  804. package/src/utils/decimal-comma.ts +19 -0
  805. package/src/utils/dom-screenshot-css.ts +265 -0
  806. package/src/utils/dom-screenshot-rasters.ts +276 -0
  807. package/src/utils/dom-screenshot.ts +437 -52
  808. package/src/utils/exchange-rate-snapshot.ts +6 -2
  809. package/src/utils/exchanges.ts +120 -1
  810. package/src/utils/format.ts +17 -3
  811. package/src/utils/fundamentals.ts +66 -0
  812. package/src/utils/futures-generic.ts +6 -12
  813. package/src/utils/fx-market-hours.ts +44 -0
  814. package/src/utils/option-expiry.ts +126 -0
  815. package/src/utils/price-history.ts +130 -40
  816. package/src/utils/rpc-timeout-error.ts +6 -2
  817. package/src/utils/sec-eps-basis.ts +178 -36
  818. package/src/utils/sec.ts +98 -40
  819. package/src/utils/throttled-fetch.ts +51 -22
  820. package/src/utils/utc-time.ts +51 -4
@@ -59,7 +59,7 @@ export type {
59
59
  /** Server-side caps for `/assist/command`; enforced here so a 422 is never sent. */
60
60
  const ASSIST_QUERY_MAX_LENGTH = 200;
61
61
  const ASSIST_COMMAND_LIMIT = 150;
62
- const ASSIST_ARG_OPTION_LIMIT = 40;
62
+ const ASSIST_ARG_OPTION_LIMIT = 64;
63
63
  const ASSIST_ARG_OPTION_VALUE_MAX_LENGTH = 40;
64
64
  const ASSIST_ARG_OPTION_LABEL_MAX_LENGTH = 60;
65
65
  const ASSIST_REQUEST_TIMEOUT_MS = 6_000;
@@ -425,6 +425,8 @@ class GloomApiClient {
425
425
  async recordExperimentExposure(payload: {
426
426
  eventId: string; surface: "web" | "desktop" | "tui" | "cli"; anonymousId?: string;
427
427
  attribution?: Record<string, string>; experiment: string; variant?: string;
428
+ /** Where the experiment showed, by a content-free id like an upgrade placement. */
429
+ placement?: string;
428
430
  }, signal?: AbortSignal): Promise<import("./web-experiments").ExperimentAnswer> {
429
431
  return this.request("/activity/research", {
430
432
  method: "POST",
@@ -441,6 +443,7 @@ class GloomApiClient {
441
443
  getCalendarFeed = this.auth.getCalendarFeed.bind(this.auth);
442
444
  ensureCalendarFeed = this.auth.ensureCalendarFeed.bind(this.auth);
443
445
  rotateCalendarFeed = this.auth.rotateCalendarFeed.bind(this.auth);
446
+ createMcpKey = this.auth.createMcpKey.bind(this.auth);
444
447
 
445
448
  async getSyncSnapshot(): Promise<CloudSyncSnapshotResponse> {
446
449
  return this.request<CloudSyncSnapshotResponse>("/sync/snapshot", { method: "GET" });
@@ -643,6 +646,9 @@ class GloomApiClient {
643
646
  connectChannel = this.chat.connectChannel.bind(this.chat);
644
647
  subscribeChatNotifications = this.chat.subscribeNotifications.bind(this.chat);
645
648
  subscribeChatPresence = this.chat.subscribePresence.bind(this.chat);
649
+ getChatDiscordLink = this.chat.getDiscordLink.bind(this.chat);
650
+ unlinkChatDiscord = this.chat.unlinkDiscord.bind(this.chat);
651
+ setChatDiscordMirror = this.chat.setDiscordMirror.bind(this.chat);
646
652
  subscribeQuotes = this.socket.subscribeQuotes.bind(this.socket);
647
653
 
648
654
  listTeams = this.teams.listTeams.bind(this.teams);
@@ -668,6 +674,10 @@ class GloomApiClient {
668
674
  subscribeTeamUpdates = this.teams.subscribeTeamUpdates.bind(this.teams);
669
675
  subscribeTeamNotifications = this.teams.subscribeTeamNotifications.bind(this.teams);
670
676
  subscribeCloudEvent = this.teams.subscribeCloudEvent.bind(this.teams);
677
+ /** The Cloud socket's own lifecycle and frames, for protocols layered on it (the terminal relay). */
678
+ subscribeSocketConnection = this.socket.subscribeConnection.bind(this.socket);
679
+ sendSocketFrame = this.socket.sendFrame.bind(this.socket);
680
+ socketServerOffers = this.socket.serverOffers.bind(this.socket);
671
681
  listCloudNotes = this.notes.listNotes.bind(this.notes);
672
682
  getCloudNote = this.notes.getNote.bind(this.notes);
673
683
  putCloudNote = this.notes.putNote.bind(this.notes);
@@ -731,10 +741,12 @@ class GloomApiClient {
731
741
  getCloudHistory = this.data.getCloudHistory.bind(this.data);
732
742
  getCloudExchangeRate = this.data.getCloudExchangeRate.bind(this.data);
733
743
  getCloudEconomicCalendar = this.data.getCloudEconomicCalendar.bind(this.data);
744
+ getCloudMacroReleaseDays = this.data.getCloudMacroReleaseDays.bind(this.data);
734
745
  getCloudEquityDiagnostic = this.data.getCloudEquityDiagnostic.bind(this.data);
735
746
  getCloudEarningsCalendar = this.data.getCloudEarningsCalendar.bind(this.data);
736
747
  getCloudEarningsHistory = this.data.getCloudEarningsHistory.bind(this.data);
737
748
  getCloudFredSeries = this.data.getCloudFredSeries.bind(this.data);
749
+ getCloudFredSeriesCatalog = this.data.getCloudFredSeriesCatalog.bind(this.data);
738
750
  getCloudCryptoMarkets = this.data.getCloudCryptoMarkets.bind(this.data);
739
751
  getCloudCentralBankRates = this.data.getCloudCentralBankRates.bind(this.data);
740
752
  getMobileAlertHistory = this.data.getMobileAlertHistory.bind(this.data);
@@ -763,6 +775,7 @@ class GloomApiClient {
763
775
  getCloudSocialMentionPosts = this.data.getCloudSocialMentionPosts.bind(this.data);
764
776
  getCloudFuturesCurve = this.data.getCloudFuturesCurve.bind(this.data);
765
777
  getCloudFuturesCurveAsOf = this.data.getCloudFuturesCurveAsOf.bind(this.data);
778
+ getCloudFuturesContract = this.data.getCloudFuturesContract.bind(this.data);
766
779
  getCloudRatePath = this.data.getCloudRatePath.bind(this.data);
767
780
  getCloudShiller = this.data.getCloudShiller.bind(this.data);
768
781
  getCloudCotBoard = this.data.getCloudCotBoard.bind(this.data);
@@ -803,6 +816,7 @@ class GloomApiClient {
803
816
  getCloudTape = this.data.getCloudTape.bind(this.data);
804
817
  getCloudYieldCurve = this.data.getCloudYieldCurve.bind(this.data);
805
818
  getCloudCurve = this.data.getCloudCurve.bind(this.data);
819
+ getCloudCurveHistory = this.data.getCloudCurveHistory.bind(this.data);
806
820
  getCloudWorldCurves = this.data.getCloudWorldCurves.bind(this.data);
807
821
  getCloudCds = this.data.getCloudCds.bind(this.data);
808
822
  getCloudCdsHistory = this.data.getCloudCdsHistory.bind(this.data);
@@ -831,6 +845,7 @@ class GloomApiClient {
831
845
  updateCloudSavedSearch = this.data.updateCloudSavedSearch.bind(this.data);
832
846
  deleteCloudSavedSearch = this.data.deleteCloudSavedSearch.bind(this.data);
833
847
  getCloudNews = this.data.getCloudNews.bind(this.data);
848
+ searchCloudNews = this.data.searchCloudNews.bind(this.data);
834
849
  getCloudNewsStory = this.data.getCloudNewsStory.bind(this.data);
835
850
  getCloudTickerTweets = this.data.getCloudTickerTweets.bind(this.data);
836
851
  searchCloudTweets = this.data.searchCloudTweets.bind(this.data);
@@ -1,4 +1,4 @@
1
- import type { CloudCorporateActionsPayload, CloudQuotePayload } from "./types";
1
+ import type { CloudCorporateActionsPayload, CloudMoverSessionFields, CloudQuotePayload } from "./types";
2
2
 
3
3
  export interface ScreenerQuote {
4
4
  symbol: string;
@@ -19,6 +19,8 @@ export interface ScreenerQuote {
19
19
  lastUpdated?: number;
20
20
  /** Session-fixed, so the price column reads its decimals from it rather than from each tick. */
21
21
  previousClose?: number;
22
+ /** The quote's sessions beside the live print the list ranks by, when the server sends them. */
23
+ sessions?: CloudMoverSessionFields;
22
24
  }
23
25
 
24
26
 
@@ -63,6 +65,13 @@ export interface MarketHeatmapResult {
63
65
  session?: "REGULAR" | "PRE" | "POST" | "CLOSED" | null;
64
66
  /** The completed regular session every stored tile describes outside the regular session, as a New York date; null while it trades. */
65
67
  regularSessionDate?: string | null;
68
+ /**
69
+ * When that session closed, in epoch milliseconds: its real close from the
70
+ * exchange calendar, so an early close reads 13:00 New York. Null while a
71
+ * session trades and when the snapshot names no session; an older server
72
+ * leaves it out.
73
+ */
74
+ regularSessionClosedAt?: number | null;
66
75
  assets: MarketHeatmapAsset[];
67
76
  }
68
77
 
@@ -1,7 +1,10 @@
1
1
  import type {
2
+ ChatAccountType,
2
3
  ChatAttachment,
3
4
  ChatChannel,
5
+ ChatDiscordLink,
4
6
  ChatMessage,
7
+ ChatMessageOrigin,
5
8
  ChatNotification,
6
9
  ChatStateResponse,
7
10
  CloudSavedSearch,
@@ -74,9 +77,20 @@ export function normalizeChatAttachments(value: unknown): ChatAttachment[] {
74
77
  });
75
78
  }
76
79
 
80
+ const CHAT_ACCOUNT_TYPES: readonly string[] = ["human", "managed_llm", "discord"] satisfies ChatAccountType[];
81
+ const CHAT_MESSAGE_ORIGINS: readonly string[] = ["app", "discord"] satisfies ChatMessageOrigin[];
82
+
83
+ /** A value a newer server adds that this client does not know reads as absent: a human, a message from the app. */
84
+ function chatUserWithKnownAccountType(user: ChatMessage["user"]): ChatMessage["user"] {
85
+ if (!user || user.accountType === undefined || CHAT_ACCOUNT_TYPES.includes(user.accountType)) return user;
86
+ const { accountType: _unknown, ...known } = user;
87
+ return known;
88
+ }
89
+
77
90
  export function normalizeChatMessage(message: ChatMessage): ChatMessage {
78
91
  const normalized: ChatMessage = {
79
92
  ...message,
93
+ user: chatUserWithKnownAccountType(message.user),
80
94
  content: typeof message.content === "string" ? message.content : "",
81
95
  createdAt: normalizeTimestamp(message.createdAt),
82
96
  ...(message.editedAt
@@ -84,12 +98,25 @@ export function normalizeChatMessage(message: ChatMessage): ChatMessage {
84
98
  : {}),
85
99
  };
86
100
  if ("attachments" in message) normalized.attachments = normalizeChatAttachments(message.attachments);
101
+ if (message.origin !== undefined && !CHAT_MESSAGE_ORIGINS.includes(message.origin)) delete normalized.origin;
87
102
  if (message.attachmentReview !== "pending" && message.attachmentReview !== "failed") {
88
103
  delete normalized.attachmentReview;
89
104
  }
90
105
  return normalized;
91
106
  }
92
107
 
108
+ /** The link answer of a server that knows Discord: mirroring is on and linking available unless it says otherwise. */
109
+ export function normalizeChatDiscordLink(value: unknown): ChatDiscordLink {
110
+ const raw = value && typeof value === "object" ? value as Record<string, unknown> : {};
111
+ const username = typeof raw.discordUsername === "string" ? raw.discordUsername.trim() : "";
112
+ return {
113
+ linked: raw.linked === true,
114
+ ...(username ? { discordUsername: username } : {}),
115
+ mirror: raw.mirror !== false,
116
+ available: raw.available !== false,
117
+ };
118
+ }
119
+
93
120
  export function normalizeChatMessages(messages: ChatMessage[]): ChatMessage[] {
94
121
  return messages.map((message) => normalizeChatMessage(message));
95
122
  }
@@ -7,6 +7,7 @@ import { isUsListingExchange, normalizeSymbol, parsePublicTickerKey, publicTicke
7
7
  import { nonUsSecListingVenue } from "../utils/sec";
8
8
  import type { HistoryRetention } from "../sources/history-retention";
9
9
  import type { CloudBeneficialOwnersParams } from "./beneficial-owners";
10
+ import type { RevenueBreakdownView } from "./revenue-breakdown";
10
11
 
11
12
  export type CloudHistoryParams = {
12
13
  interval?: string;
@@ -58,7 +59,15 @@ export type CloudCongressHouseParams = {
58
59
  minAmount?: number;
59
60
  };
60
61
 
61
- export type CloudEarningsCallsParams = {
62
+ /** The listing an issuer lookup is for, so a listing abroad never reads a US namesake. */
63
+ export type IssuerListingParams = {
64
+ /** The listing's venue. Sent only for a venue outside the US, with `name`. */
65
+ exchange?: string;
66
+ /** The listing's company name, from its ticker or its own quote. */
67
+ name?: string;
68
+ };
69
+
70
+ export type CloudEarningsCallsParams = IssuerListingParams & {
62
71
  ticker?: string;
63
72
  limit?: number;
64
73
  offset?: number;
@@ -305,11 +314,42 @@ export function cloudJobsMoversPath(limit?: number, offset?: number): string {
305
314
  return appendQuery("/cloud/jobs", search);
306
315
  }
307
316
 
317
+ /** A listing outside the US, as an issuer lookup names it: its bare symbol, venue and company. */
318
+ export interface ListingAbroad {
319
+ symbol: string;
320
+ exchange: string;
321
+ name?: string;
322
+ }
323
+
324
+ /**
325
+ * The listing abroad a ticker names, from its key or the given venue: AI in
326
+ * Paris is Air Liquide, AI in New York is C3.ai. Null for a US listing, a
327
+ * routing destination or a symbol with no venue, which keep their US lookup.
328
+ */
329
+ export function listingAbroad(ticker: string, exchange?: string, name?: string | null): ListingAbroad | null {
330
+ const venue = nonUsSecListingVenue(ticker, exchange);
331
+ if (!venue) return null;
332
+ const company = name?.trim();
333
+ return { symbol: parsePublicTickerKey(ticker).symbol, exchange: venue, ...(company ? { name: company } : {}) };
334
+ }
335
+
336
+ /** Sets a listing abroad's venue and company on an issuer lookup. */
337
+ function setListingAbroad(search: URLSearchParams, listing: ListingAbroad | null): void {
338
+ if (!listing) return;
339
+ search.set("exchange", listing.exchange);
340
+ if (listing.name) search.set("name", listing.name);
341
+ }
342
+
343
+ /** A US listing or a bare symbol looks up its US ticker as before; a listing abroad names its venue and company. */
308
344
  export function cloudEarningsCallsPath(
309
345
  params: CloudEarningsCallsParams = {},
310
346
  ): string {
311
347
  const search = new URLSearchParams();
312
- if (params.ticker) search.set("ticker", normalizeIssuerResearchTicker(params.ticker));
348
+ if (params.ticker) {
349
+ const abroad = listingAbroad(params.ticker, params.exchange, params.name);
350
+ search.set("ticker", abroad?.symbol ?? normalizeIssuerResearchTicker(params.ticker));
351
+ setListingAbroad(search, abroad);
352
+ }
313
353
  if (params.limit != null) search.set("limit", String(params.limit));
314
354
  if (params.offset != null) search.set("offset", String(params.offset));
315
355
  if (params.includePending) search.set("includePending", "true");
@@ -320,33 +360,60 @@ export function cloudEarningsTranscriptPath(id: string): string {
320
360
  return `/cloud/transcripts/${encodeURIComponent(id)}`;
321
361
  }
322
362
 
363
+ /**
364
+ * An issuer read's path: a US listing or a bare symbol keeps its US ticker
365
+ * and sends nothing else; a listing abroad sends its bare symbol with its
366
+ * venue and company (listingAbroad).
367
+ */
368
+ function issuerPath(base: string, ticker: string, listing: IssuerListingParams = {}, suffix = ""): string {
369
+ const abroad = listingAbroad(ticker, listing.exchange, listing.name);
370
+ const search = new URLSearchParams();
371
+ setListingAbroad(search, abroad);
372
+ return appendQuery(`${base}/${encodeURIComponent(abroad?.symbol ?? normalizeIssuerResearchTicker(ticker))}${suffix}`, search);
373
+ }
374
+
323
375
  /**
324
376
  * RISK, EXEC and EK are Pro: these reads need a verified Pro account. The same
325
377
  * risk factors and pay are open under /public for the gloom.sh pages.
326
378
  */
327
- export function cloudProxyStatementsPath(ticker: string): string {
328
- return `/cloud/proxies/${encodeURIComponent(normalizeIssuerResearchTicker(ticker))}`;
379
+ export function cloudProxyStatementsPath(ticker: string, listing?: IssuerListingParams): string {
380
+ return issuerPath("/cloud/proxies", ticker, listing);
329
381
  }
330
382
 
331
- export function cloudFilingEventsPath(ticker: string, limit?: number): string {
383
+ export function cloudFilingEventsPath(ticker: string, limit?: number, listing: IssuerListingParams = {}): string {
384
+ const abroad = listingAbroad(ticker, listing.exchange, listing.name);
332
385
  const search = new URLSearchParams();
386
+ setListingAbroad(search, abroad);
333
387
  if (limit != null) search.set("limit", String(limit));
334
- return appendQuery(
335
- `/cloud/events/${encodeURIComponent(normalizeIssuerResearchTicker(ticker))}`,
336
- search,
337
- );
388
+ return appendQuery(`/cloud/events/${encodeURIComponent(abroad?.symbol ?? normalizeIssuerResearchTicker(ticker))}`, search);
338
389
  }
339
390
 
340
- export function cloudRiskReportsPath(ticker: string): string {
341
- return `/cloud/risks/${encodeURIComponent(normalizeIssuerResearchTicker(ticker))}`;
391
+ export function cloudRiskReportsPath(ticker: string, listing?: IssuerListingParams): string {
392
+ return issuerPath("/cloud/risks", ticker, listing);
342
393
  }
343
394
 
344
- export function cloudRiskReportPath(ticker: string, year: number): string {
345
- return `/cloud/risks/${encodeURIComponent(normalizeIssuerResearchTicker(ticker))}/${year}`;
395
+ export function cloudRiskReportPath(ticker: string, year: number, listing?: IssuerListingParams): string {
396
+ return issuerPath("/cloud/risks", ticker, listing, `/${year}`);
346
397
  }
347
398
 
348
- export function cloudProxyStatementPath(ticker: string, year: number): string {
349
- return `/cloud/proxies/${encodeURIComponent(normalizeIssuerResearchTicker(ticker))}/${year}`;
399
+ export function cloudProxyStatementPath(ticker: string, year: number, listing?: IssuerListingParams): string {
400
+ return issuerPath("/cloud/proxies", ticker, listing, `/${year}`);
401
+ }
402
+
403
+ /** The principal maturity schedule; a US symbol goes as given, as it always has. */
404
+ export function cloudDebtMaturitiesPath(symbol: string, listing: IssuerListingParams = {}): string {
405
+ const abroad = listingAbroad(symbol, listing.exchange, listing.name);
406
+ const search = new URLSearchParams({ symbol: abroad?.symbol ?? symbol });
407
+ setListingAbroad(search, abroad);
408
+ return appendQuery("/cloud/debt-maturities", search);
409
+ }
410
+
411
+ export function cloudRevenueBreakdownPath(symbol: string, view?: RevenueBreakdownView, listing: IssuerListingParams = {}): string {
412
+ const abroad = listingAbroad(symbol, listing.exchange, listing.name);
413
+ const search = new URLSearchParams({ symbol: abroad?.symbol ?? symbol });
414
+ setListingAbroad(search, abroad);
415
+ if (view) search.set("view", view);
416
+ return appendQuery("/cloud/revenue-breakdown", search);
350
417
  }
351
418
 
352
419
  /**
@@ -355,23 +422,21 @@ export function cloudProxyStatementPath(ticker: string, year: number): string {
355
422
  * its symbol can be another company's US ticker.
356
423
  */
357
424
  export function cloudSecFilingsPath(params: CloudSecFilingsParams): string {
358
- const venue = nonUsSecListingVenue(params.ticker, params.exchange);
425
+ const abroad = listingAbroad(params.ticker, params.exchange, params.name);
359
426
  const search = new URLSearchParams({
360
- ticker: venue ? parsePublicTickerKey(params.ticker).symbol : normalizeIssuerResearchTicker(params.ticker),
427
+ ticker: abroad?.symbol ?? normalizeIssuerResearchTicker(params.ticker),
361
428
  });
362
429
  if (params.limit != null) search.set("limit", String(params.limit));
363
430
  if (params.offset != null) search.set("offset", String(params.offset));
364
- if (venue) {
365
- search.set("exchange", venue);
366
- const name = params.name?.trim();
367
- if (name) search.set("name", name);
368
- }
431
+ setListingAbroad(search, abroad);
369
432
  return appendQuery("/cloud/sec/filings", search);
370
433
  }
371
434
 
372
435
  /** Schedule 13D and 13G reports about the issuer behind `ticker`. */
373
436
  export function cloudSecBeneficialOwnersPath(params: CloudBeneficialOwnersParams): string {
374
- const search = new URLSearchParams({ ticker: normalizeIssuerResearchTicker(params.ticker) });
437
+ const abroad = listingAbroad(params.ticker, params.exchange, params.name);
438
+ const search = new URLSearchParams({ ticker: abroad?.symbol ?? normalizeIssuerResearchTicker(params.ticker) });
439
+ setListingAbroad(search, abroad);
375
440
  if (params.form) search.set("form", params.form);
376
441
  if (params.history) search.set("history", "1");
377
442
  if (params.limit != null) search.set("limit", String(params.limit));
@@ -511,6 +576,13 @@ export function cloudNewsPath(params: CloudNewsParams = {}): string {
511
576
  return appendQuery("/news", search);
512
577
  }
513
578
 
579
+ /** Stories whose headline, summary or publisher matches the text, best match first; the service takes at most 100. */
580
+ export function cloudNewsSearchPath(query: string, limit?: number): string {
581
+ const search = new URLSearchParams({ query });
582
+ if (limit != null) search.set("limit", String(limit));
583
+ return appendQuery("/news/search", search);
584
+ }
585
+
514
586
  export function cloudTickerTweetsPath(params: CloudTickerTweetsParams): string {
515
587
  const search = new URLSearchParams({ ticker: params.ticker });
516
588
  if (params.limit != null) search.set("limit", String(params.limit));
@@ -16,7 +16,8 @@ import {
16
16
  } from "../core/connection-health";
17
17
  import { SESSION_COOKIE_NAMES } from "./session-cookie";
18
18
 
19
- const DEFAULT_API_URL = "https://api.gloom.sh";
19
+ /** The public Gloom Cloud API, which the web app's same-origin `/api` path forwards to. */
20
+ export const DEFAULT_API_URL = "https://api.gloom.sh";
20
21
  const DEFAULT_MARKET_REQUEST_TIMEOUT_MS = 10_000;
21
22
  const DEFAULT_RESEARCH_REQUEST_TIMEOUT_MS = 45_000;
22
23
  // Research may fill missing sections after a primary read; quote/history reads remain latency bounded.
@@ -3,8 +3,12 @@ import { getCurrentPluginTarget } from "../plugins/current-target";
3
3
  import type { DesktopDeepLinkBridge } from "../types/desktop-deeplink";
4
4
  import { exposeExperiment, storedExperimentAssignments } from "./web-experiments";
5
5
  import { createWallExperimentSession, type WallExperiment, type WallExperimentContext, type WallTeaserVariant } from "./wall-experiments";
6
+ import { createUpgradeExperimentSession, UPGRADE_PERSONALIZED, type UpgradeExperimentContext, type UpgradePersonalizedVariant } from "./upgrade-experiment";
6
7
  import { hasProAccess } from "./plan-rules";
7
8
  import { withDeadline } from "../utils/async-deadline";
9
+ import { browserDoNotTrack } from "../telemetry/crash-reports-dom";
10
+ import { currentTelemetryConfig } from "../telemetry/live-config";
11
+ import { usageTelemetryAllowed } from "../telemetry/usage-counts";
8
12
 
9
13
  export type ResearchActivity =
10
14
  | "workspace_opened"
@@ -38,6 +42,7 @@ let anonymousId: string | undefined;
38
42
  let attribution: Record<string, string> = {};
39
43
  const wallExperiment = createWallExperimentSession();
40
44
  const signinWallExperiment = createWallExperimentSession("wall_teaser_signin");
45
+ const upgradeExperiment = createUpgradeExperimentSession();
41
46
  const WALL_VIEWS_SESSION_KEY = "gloomberb.wall-teaser.views";
42
47
 
43
48
  const ATTRIBUTION_STORAGE_KEY = "gloomberb.web.attribution";
@@ -232,12 +237,7 @@ function stripHandoffParams(url: URL): void {
232
237
  /** Hosted web analytics only. Native local use never creates an identifier. */
233
238
  export function initializeBrowserResearchActivity(): void {
234
239
  try {
235
- if (
236
- navigator.doNotTrack === "1" ||
237
- (navigator as Navigator & { globalPrivacyControl?: boolean })
238
- .globalPrivacyControl
239
- )
240
- return;
240
+ if (!researchTelemetryAllowed()) return;
241
241
  const url = new URL(location.href);
242
242
  const incoming = readHandoffId(url);
243
243
  const stored = localStorage.getItem(ANONYMOUS_ID_STORAGE_KEY);
@@ -267,6 +267,7 @@ export function initializeBrowserResearchActivity(): void {
267
267
  */
268
268
  export function initializeDesktopResearchActivity(storage: StorageLike = localStorage): void {
269
269
  try {
270
+ if (!researchTelemetryAllowed()) return;
270
271
  const stored = storage.getItem(ANONYMOUS_ID_STORAGE_KEY);
271
272
  anonymousId = stored && ANONYMOUS_ID.test(stored) ? stored : undefined;
272
273
  attribution = readStoredAttribution(storage.getItem(ATTRIBUTION_STORAGE_KEY));
@@ -276,6 +277,7 @@ export function initializeDesktopResearchActivity(storage: StorageLike = localSt
276
277
  }
277
278
 
278
279
  export function adoptDesktopHandoff(href: string, storage: StorageLike = localStorage, now = Date.now()): boolean {
280
+ if (!researchTelemetryAllowed()) return false;
279
281
  if (!carriesHandoff(href)) return false;
280
282
  try {
281
283
  const url = new URL(href);
@@ -367,6 +369,7 @@ export function recordResearchActivity(
367
369
  tab?: string,
368
370
  { desks, placement: rawPlacement, teaser_kind, cta }: ResearchActivityDetails = {},
369
371
  ): void {
372
+ if (!researchTelemetryAllowed()) return;
370
373
  const target = getCurrentPluginTarget();
371
374
  const user = apiClient.getCurrentUser();
372
375
  const wallEvent = event === "wall_viewed" || event === "wall_cta_clicked";
@@ -449,6 +452,7 @@ function webExperimentAttribution(): { experiments?: string } {
449
452
  * Privacy Control) and not driven by automation are asked. See web-experiments.ts.
450
453
  */
451
454
  export function exposeWebExperiment(experiment: string): Promise<string | null> {
455
+ if (!researchTelemetryAllowed()) return Promise.resolve(null);
452
456
  if (getCurrentPluginTarget() !== "web") return Promise.resolve(null);
453
457
  try {
454
458
  return exposeExperiment(experiment, {
@@ -471,11 +475,13 @@ export function exposeWebExperiment(experiment: string): Promise<string | null>
471
475
  }
472
476
  }
473
477
 
478
+ /** Research milestones, attribution and exposures share the Usage off switch. */
479
+ function researchTelemetryAllowed(): boolean {
480
+ return usageTelemetryAllowed(currentTelemetryConfig(undefined)) && !browserDoNotTrack();
481
+ }
482
+
474
483
  function wallPrivacyBlocked(): boolean {
475
- if (typeof navigator === "undefined") return false;
476
- return navigator.doNotTrack === "1"
477
- || (navigator as Navigator & { globalPrivacyControl?: boolean }).globalPrivacyControl === true
478
- || navigator.webdriver === true;
484
+ return !researchTelemetryAllowed() || (typeof navigator !== "undefined" && navigator.webdriver === true);
479
485
  }
480
486
 
481
487
  function wallExperimentContext(): WallExperimentContext {
@@ -524,6 +530,35 @@ export function exposeWallTeaser(experiment: WallExperiment = "wall_teaser"): Pr
524
530
  });
525
531
  }
526
532
 
533
+ function upgradeExperimentContext(): UpgradeExperimentContext {
534
+ const { accountId, pro, optedOut, automated, session } = wallExperimentContext();
535
+ return { accountId, pro, optedOut, automated, session };
536
+ }
537
+
538
+ /** The `upgrade_personalized` arm this session already has, without asking; see upgrade-experiment.ts. */
539
+ export function knownUpgradePersonalized(): UpgradePersonalizedVariant | null | undefined {
540
+ return upgradeExperiment.known(upgradeExperimentContext());
541
+ }
542
+
543
+ /**
544
+ * Asks for the `upgrade_personalized` arm when an upgrade surface is shown to
545
+ * a free account that has tickers to name, once per account and session. The
546
+ * request says where it showed and nothing about the holdings.
547
+ */
548
+ export function exposeUpgradePersonalized(placement: string): Promise<UpgradePersonalizedVariant | null> {
549
+ const context = upgradeExperimentContext();
550
+ const surface = getCurrentPluginTarget();
551
+ return upgradeExperiment.expose(context, () => {
552
+ const controller = new AbortController();
553
+ return withDeadline(apiClient.recordExperimentExposure({
554
+ eventId: crypto.randomUUID(),
555
+ surface,
556
+ experiment: UPGRADE_PERSONALIZED,
557
+ ...(ACTIVITY_ID.test(placement) ? { placement } : {}),
558
+ }, controller.signal), 3_000, "Upgrade experiment request timed out", (error) => controller.abort(error));
559
+ });
560
+ }
561
+
527
562
  /** Records the visible wall once per placement, including visitors outside the experiment. */
528
563
  export function recordWallViewed(placement: string, teaserKind?: "summary" | "sample" | "none"): void {
529
564
  recordResearchActivity("wall_viewed", undefined, undefined, { placement, teaser_kind: teaserKind });
@@ -537,6 +572,7 @@ export function recordWallCtaClicked(placement: string, cta: "login" | "signup")
537
572
  export function researchUpgradeUrl(returnTo?: string): string {
538
573
  const url = new URL("https://gloom.sh/cloud?upgrade=pro");
539
574
  if (returnTo) url.searchParams.set("returnTo", returnTo);
575
+ if (!researchTelemetryAllowed()) return url.href;
540
576
  if (anonymousId) url.searchParams.set(HANDOFF_ID_KEY, anonymousId);
541
577
  for (const [key, value] of Object.entries(attribution)) {
542
578
  if (/^(utm_(source|medium|campaign|content|term)|twclid)$/.test(key))
@@ -33,7 +33,9 @@ const QUOTE_SUBSCRIPTION_FLUSH_MS = 25;
33
33
  const MARKET_BATCH_FEATURE = "market.batch";
34
34
  /** Chat frames carry `attachments`; without it the server writes images into the text. */
35
35
  export const CHAT_ATTACHMENTS_FEATURE = "chat.attachments";
36
- const CLIENT_SOCKET_FEATURES = [MARKET_BATCH_FEATURE, CHAT_ATTACHMENTS_FEATURE] as const;
36
+ /** The app can run terminal tools relayed from a remote assistant; it still announces itself first. */
37
+ export const TERMINAL_RELAY_FEATURE = "terminal.relay";
38
+ const CLIENT_SOCKET_FEATURES = [MARKET_BATCH_FEATURE, CHAT_ATTACHMENTS_FEATURE, TERMINAL_RELAY_FEATURE] as const;
37
39
  const cloudApiLog = debugLog.createLogger("cloud-api");
38
40
 
39
41
  type ChannelListener = (message: ChatMessage) => void;
@@ -131,6 +133,7 @@ export class CloudApiSocket {
131
133
  /** What the last "ready" frame offered; kept across reconnects so a blip does not hide features. */
132
134
  private offeredFeatures: ReadonlySet<string> = new Set();
133
135
  private readonly offeredFeatureListeners = new Set<() => void>();
136
+ private readonly connectionListeners = new Set<(event: "ready" | "closed") => void>();
134
137
  private readonly tapeListeners = new Map<string, { symbol: string; exchange: string; listeners: Set<(event: TapeFeedEvent) => void> }>();
135
138
  private readonly scannerListeners = new Map<
136
139
  ScannerKind,
@@ -164,6 +167,7 @@ export class CloudApiSocket {
164
167
  const ws = this.ws;
165
168
  this.ws = null;
166
169
  if (ws) {
170
+ this.emitConnection("closed");
167
171
  cloudApiLog.info("teardown websocket");
168
172
  this.health.reportSocketState(
169
173
  GLOOM_CLOUD_SOCKET_CONNECTION_ID,
@@ -260,6 +264,29 @@ export class CloudApiSocket {
260
264
  };
261
265
  }
262
266
 
267
+ /** "ready" after each server hello (features negotiated), "closed" when that connection ends. */
268
+ subscribeConnection(listener: (event: "ready" | "closed") => void): () => void {
269
+ this.connectionListeners.add(listener);
270
+ return () => {
271
+ this.connectionListeners.delete(listener);
272
+ };
273
+ }
274
+
275
+ /** Sends one frame on the open connection; false when there is none. */
276
+ sendFrame(payload: Record<string, unknown>): boolean {
277
+ if (this.ws?.readyState !== WebSocket.OPEN) return false;
278
+ try {
279
+ this.ws.send(JSON.stringify(payload));
280
+ return true;
281
+ } catch {
282
+ return false;
283
+ }
284
+ }
285
+
286
+ private emitConnection(event: "ready" | "closed"): void {
287
+ for (const listener of this.connectionListeners) listener(event);
288
+ }
289
+
263
290
  subscribeTeamNotifications(listener: TeamNotificationListener): () => void {
264
291
  this.teamNotificationListeners.add(listener);
265
292
  this.syncAuthState();
@@ -470,6 +497,7 @@ export class CloudApiSocket {
470
497
  });
471
498
  this.channelListeners.clear();
472
499
  this.offeredFeatureListeners.clear();
500
+ this.connectionListeners.clear();
473
501
  this.chatNotificationListeners.clear();
474
502
  this.chatPresenceListeners.clear();
475
503
  this.teamNotificationListeners.clear();
@@ -500,13 +528,15 @@ export class CloudApiSocket {
500
528
  if (parsed?.type === "ready") {
501
529
  recordServerClockSample(parsed.serverTime);
502
530
  this.negotiateSocketFeatures(parsed.features);
503
- if (!parsed.user) return;
504
- cloudApiLog.info("websocket ready", {
505
- emailVerified: parsed.user.emailVerified === true,
506
- });
507
- this.delegate.updateCurrentUserFromSocket(
508
- parsed.user as Partial<AuthUser>,
509
- );
531
+ if (parsed.user) {
532
+ cloudApiLog.info("websocket ready", {
533
+ emailVerified: parsed.user.emailVerified === true,
534
+ });
535
+ this.delegate.updateCurrentUserFromSocket(
536
+ parsed.user as Partial<AuthUser>,
537
+ );
538
+ }
539
+ this.emitConnection("ready");
510
540
  return;
511
541
  }
512
542
 
@@ -769,6 +799,7 @@ export class CloudApiSocket {
769
799
  tokenSource: usingWebSocketToken ? "websocket" : "session",
770
800
  });
771
801
  if (!activeSocket) return;
802
+ this.emitConnection("closed");
772
803
  this.health.reportSocketState(
773
804
  GLOOM_CLOUD_SOCKET_CONNECTION_ID,
774
805
  "closed",