gloomberb 0.16.3 → 0.16.4

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (451) hide show
  1. package/package.json +4 -1
  2. package/src/api-client/askg.ts +43 -0
  3. package/src/api-client/auth.ts +15 -0
  4. package/src/api-client/beneficial-owners.ts +4 -0
  5. package/src/api-client/chat.ts +19 -0
  6. package/src/api-client/company-kpis.ts +14 -2
  7. package/src/api-client/data.ts +34 -16
  8. package/src/api-client/index.ts +12 -0
  9. package/src/api-client/normalizers.ts +27 -0
  10. package/src/api-client/paths.ts +88 -23
  11. package/src/api-client/request.ts +2 -1
  12. package/src/api-client/research-activity.ts +31 -0
  13. package/src/api-client/socket.ts +39 -8
  14. package/src/api-client/types.ts +57 -1
  15. package/src/api-client/upgrade-experiment.ts +90 -0
  16. package/src/app/global-shortcuts.ts +11 -1
  17. package/src/app/keybindings/actions.ts +10 -0
  18. package/src/app/pane-runtime/index.tsx +8 -0
  19. package/src/app/pane-runtime/pane-template-runtime.ts +5 -0
  20. package/src/app/pane-runtime/plugin-bindings.ts +65 -25
  21. package/src/app/pane-runtime/ticker-inspector-runtime.ts +12 -0
  22. package/src/app/pane-runtime/ticker-open-runtime.ts +18 -1
  23. package/src/app/runtime/desktop-deeplink.ts +5 -0
  24. package/src/app/star-prompt/model.ts +98 -0
  25. package/src/app/star-prompt/runtime.ts +41 -0
  26. package/src/app/star-prompt/status-line.tsx +190 -0
  27. package/src/app.tsx +13 -7
  28. package/src/architecture/core-builtin-allowlist.json +70 -0
  29. package/src/brokers/signed-in/adapter.ts +33 -2
  30. package/src/brokers/signed-in/client.ts +10 -0
  31. package/src/brokers/signed-in/sign-in-dialog.tsx +23 -9
  32. package/src/brokers/signed-in/sign-in.ts +62 -5
  33. package/src/capabilities/registry.ts +8 -1
  34. package/src/capabilities/types.ts +2 -0
  35. package/src/cli/commands/crypto-hints.ts +12 -4
  36. package/src/cli/commands/market.ts +359 -99
  37. package/src/cli/commands/options-chain.ts +172 -0
  38. package/src/cli/commands/options-leaps.ts +422 -0
  39. package/src/cli/commands/overview.ts +164 -26
  40. package/src/cli/commands/search.ts +29 -8
  41. package/src/cli/commands/system.ts +99 -19
  42. package/src/cli/commands/themes.ts +64 -0
  43. package/src/cli/commands/ticker.ts +62 -30
  44. package/src/cli/desktop-pane-shot.ts +97 -16
  45. package/src/cli/errors.ts +25 -2
  46. package/src/cli/freshness.ts +7 -4
  47. package/src/cli/fx-pair.ts +57 -0
  48. package/src/cli/help.ts +14 -1
  49. package/src/cli/index-roots.ts +51 -0
  50. package/src/cli/index.ts +9 -6
  51. package/src/cli/listing-arg.ts +211 -3
  52. package/src/cli/not-a-ticker.ts +37 -0
  53. package/src/cli/options.ts +50 -6
  54. package/src/cli/pane-functions/capabilities.ts +8 -2
  55. package/src/cli/pane-functions/catalog.ts +13 -2
  56. package/src/cli/pane-functions/data.ts +36 -5
  57. package/src/cli/pane-functions/dom.ts +21 -13
  58. package/src/cli/pane-functions/freshness.ts +205 -26
  59. package/src/cli/pane-functions/function-help.ts +67 -22
  60. package/src/cli/pane-functions/headless.ts +5 -4
  61. package/src/cli/pane-functions/index.ts +3 -0
  62. package/src/cli/pane-functions/market-session.ts +133 -0
  63. package/src/cli/pane-functions/options.ts +15 -4
  64. package/src/cli/pane-functions/report-notices.ts +63 -0
  65. package/src/cli/pane-functions/report.ts +4 -0
  66. package/src/cli/pane-functions/resolver.ts +4 -6
  67. package/src/cli/pane-functions/screenshot-evidence.ts +2 -0
  68. package/src/cli/pane-functions/screenshot.ts +105 -23
  69. package/src/cli/registry.ts +2 -1
  70. package/src/cli/result.ts +50 -13
  71. package/src/cli/row-window.ts +76 -0
  72. package/src/cli/scroll-truncation.ts +34 -0
  73. package/src/components/chart/composite/composite-chart.tsx +43 -4
  74. package/src/components/chart/composite/legend.tsx +39 -6
  75. package/src/components/chart/composite/rasterizer.ts +64 -4
  76. package/src/components/chart/composite/series-cues.ts +71 -0
  77. package/src/components/chart/composite/text-renderer.ts +16 -8
  78. package/src/components/chart/composite/types.ts +3 -0
  79. package/src/components/command-bar/commands/direct/index.ts +9 -1
  80. package/src/components/command-bar/commands/plugin/items.ts +3 -1
  81. package/src/components/command-bar/commands/registry.ts +7 -0
  82. package/src/components/command-bar/layout-items/focused-pane.ts +38 -0
  83. package/src/components/command-bar/pane-templates/workflow.ts +5 -0
  84. package/src/components/command-bar/routes/root/command-items.ts +2 -0
  85. package/src/components/command-bar/routes/root/plugin-turn-on.ts +92 -0
  86. package/src/components/command-bar/routes/root/results.ts +40 -10
  87. package/src/components/command-bar/routes/root/runtime.ts +8 -0
  88. package/src/components/command-bar/routes/root/search-providers.ts +97 -14
  89. package/src/components/command-bar/surface/index.tsx +18 -4
  90. package/src/components/command-bar/theme-picker.tsx +48 -13
  91. package/src/components/command-bar/workflow/ops.ts +5 -3
  92. package/src/components/data-table/view.tsx +28 -9
  93. package/src/components/layout/floating-pane.tsx +6 -2
  94. package/src/components/layout/market-summary.ts +23 -9
  95. package/src/components/layout/pane/content.tsx +46 -29
  96. package/src/components/layout/pane/cycle-order.ts +2 -11
  97. package/src/components/layout/pane/header.tsx +2 -1
  98. package/src/components/layout/pane/title.ts +1 -1
  99. package/src/components/layout/presentation.ts +22 -0
  100. package/src/components/layout/shell/active-drag.ts +1 -1
  101. package/src/components/layout/shell/drag/index.ts +4 -0
  102. package/src/components/layout/shell/drag/live.ts +76 -5
  103. package/src/components/layout/shell/drag/runtime.ts +8 -8
  104. package/src/components/layout/shell/index.tsx +47 -6
  105. package/src/components/layout/shell/layout-state.ts +5 -11
  106. package/src/components/layout/shell/menu.ts +28 -1
  107. package/src/components/layout/shell/pane/actions.ts +2 -1
  108. package/src/components/layout/shell/pane/layers.tsx +51 -10
  109. package/src/components/layout/shell/pane/management-shortcuts.ts +5 -0
  110. package/src/components/layout/shell/pane/new-layout.ts +116 -0
  111. package/src/components/layout/shell/shortcuts.ts +5 -2
  112. package/src/components/layout/shell/visible-layout.ts +44 -1
  113. package/src/components/layout/status-bar.tsx +4 -1
  114. package/src/components/markdown-text.tsx +9 -5
  115. package/src/components/metric-treemap/heat-surface.tsx +27 -8
  116. package/src/components/metric-treemap/heat-tiles.ts +48 -17
  117. package/src/components/onboarding/onboarding-frame.tsx +33 -10
  118. package/src/components/onboarding/onboarding-wizard.tsx +49 -40
  119. package/src/components/onboarding/portfolio-step/positions-panel.tsx +5 -2
  120. package/src/components/onboarding/pro-step-layout.ts +86 -0
  121. package/src/components/onboarding/use-onboarding-upgrade.ts +6 -2
  122. package/src/components/ui/button.tsx +10 -0
  123. package/src/components/ui/data-table/index.tsx +38 -0
  124. package/src/components/ui/data-table/types.ts +8 -1
  125. package/src/components/ui/data-table/visible-range.ts +2 -0
  126. package/src/components/ui/icon.tsx +11 -2
  127. package/src/components/ui/index.ts +1 -1
  128. package/src/core/connection-health.ts +1 -1
  129. package/src/core/state/app/layout-reducer.ts +89 -3
  130. package/src/core/state/app/state.ts +8 -5
  131. package/src/core/state/app/types.ts +13 -2
  132. package/src/data/config/layout.ts +55 -21
  133. package/src/data/config/store/fold-panes.ts +149 -0
  134. package/src/data/config/store/migrations.ts +7 -0
  135. package/src/data/config/store/node.ts +27 -6
  136. package/src/data/config/store/normalize.ts +37 -3
  137. package/src/i18n/es.ts +14 -1
  138. package/src/i18n/ja.ts +14 -1
  139. package/src/i18n/ko.ts +14 -1
  140. package/src/i18n/zh-cn.ts +14 -1
  141. package/src/i18n/zh-tw.ts +14 -1
  142. package/src/layout/desks.ts +1 -2
  143. package/src/layout/pane-layout-move.ts +264 -0
  144. package/src/layout/pane-manager/hidden-panes.ts +160 -0
  145. package/src/layout/pane-manager/index.ts +1 -0
  146. package/src/market-data/coordinator/entries.ts +7 -1
  147. package/src/market-data/coordinator/quotes.ts +2 -2
  148. package/src/market-data/market/freshness.ts +118 -18
  149. package/src/market-data/market/status.ts +40 -0
  150. package/src/market-data/options-alternatives.ts +69 -0
  151. package/src/market-data/quotes/contributions.ts +19 -2
  152. package/src/market-data/quotes/metadata.ts +16 -0
  153. package/src/market-data/quotes/screener-live-quotes.ts +56 -5
  154. package/src/plugins/builtin/account-management/keyboard.ts +3 -0
  155. package/src/plugins/builtin/account-management/model.ts +1 -0
  156. package/src/plugins/builtin/account-management/navigation.ts +1 -1
  157. package/src/plugins/builtin/account-management/pane.tsx +31 -4
  158. package/src/plugins/builtin/alerts/quotes.ts +3 -0
  159. package/src/plugins/builtin/analytics/risk-headless.ts +3 -1
  160. package/src/plugins/builtin/analytics/risk-model.ts +37 -8
  161. package/src/plugins/builtin/analytics/risk-pane.tsx +8 -4
  162. package/src/plugins/builtin/backtest/pane.tsx +1 -1
  163. package/src/plugins/builtin/broker-manager/detail.tsx +4 -0
  164. package/src/plugins/builtin/broker-manager/index.tsx +7 -3
  165. package/src/plugins/builtin/broker-manager/model.ts +8 -0
  166. package/src/plugins/builtin/broker-manager/pane-actions.tsx +8 -2
  167. package/src/plugins/builtin/broker-manager/sign-in-end.ts +82 -0
  168. package/src/plugins/builtin/broker-manager/table.ts +5 -0
  169. package/src/plugins/builtin/builtin-plugin-meta.ts +121 -11
  170. package/src/plugins/builtin/chart-composer/pane.tsx +1 -1
  171. package/src/plugins/builtin/chat/channels.ts +34 -36
  172. package/src/plugins/builtin/chat/command-bar.ts +138 -0
  173. package/src/plugins/builtin/chat/composer-commands.ts +21 -1
  174. package/src/plugins/builtin/chat/content/composer-runtime.ts +11 -1
  175. package/src/plugins/builtin/chat/content/footer.tsx +5 -3
  176. package/src/plugins/builtin/chat/content/index.tsx +21 -1
  177. package/src/plugins/builtin/chat/content/mentions.ts +2 -1
  178. package/src/plugins/builtin/chat/content/user-map.ts +3 -1
  179. package/src/plugins/builtin/chat/controller/index.ts +48 -0
  180. package/src/plugins/builtin/chat/conversations.ts +256 -0
  181. package/src/plugins/builtin/chat/discord-command.ts +91 -0
  182. package/src/plugins/builtin/chat/edit-window.ts +12 -6
  183. package/src/plugins/builtin/chat/ghost-user.ts +14 -0
  184. package/src/plugins/builtin/chat/index.tsx +40 -2
  185. package/src/plugins/builtin/chat/layout.ts +2 -0
  186. package/src/plugins/builtin/chat/message/desktop.tsx +2 -1
  187. package/src/plugins/builtin/chat/message/header.tsx +24 -15
  188. package/src/plugins/builtin/chat/message/profile-popover.tsx +2 -1
  189. package/src/plugins/builtin/chat/message/render-state.ts +3 -0
  190. package/src/plugins/builtin/chat/pane-requests.ts +60 -0
  191. package/src/plugins/builtin/chat/pane-state.ts +32 -2
  192. package/src/plugins/builtin/chat/pane.tsx +8 -0
  193. package/src/plugins/builtin/cloud/askg/controller.ts +112 -4
  194. package/src/plugins/builtin/cloud/askg/conversation-store.ts +21 -0
  195. package/src/plugins/builtin/cloud/askg/manifest.ts +1 -0
  196. package/src/plugins/builtin/cloud/askg/model.ts +129 -70
  197. package/src/plugins/builtin/cloud/askg/pane.tsx +772 -377
  198. package/src/plugins/builtin/cloud/askg/protocol.ts +40 -2
  199. package/src/plugins/builtin/cloud/askg/tool-display.ts +437 -0
  200. package/src/plugins/builtin/cloud/askg/tool-timeline.tsx +403 -0
  201. package/src/plugins/builtin/cloud/company-picker.tsx +1 -9
  202. package/src/plugins/builtin/cloud/mcp-connect/command.ts +24 -0
  203. package/src/plugins/builtin/cloud/mcp-connect/dialog.tsx +360 -0
  204. package/src/plugins/builtin/cloud/mcp-connect/model.ts +135 -0
  205. package/src/plugins/builtin/cloud/mcp-connect/sections.ts +62 -0
  206. package/src/plugins/builtin/cloud/plugin.tsx +36 -1
  207. package/src/plugins/builtin/cloud/starter-symbols.ts +8 -0
  208. package/src/plugins/builtin/cloud/terminal-relay/acm-tab.tsx +89 -0
  209. package/src/plugins/builtin/cloud/terminal-relay/client.ts +97 -0
  210. package/src/plugins/builtin/cloud/terminal-relay/connect-section.tsx +57 -0
  211. package/src/plugins/builtin/cloud/terminal-relay/engine.ts +666 -0
  212. package/src/plugins/builtin/cloud/terminal-relay/grants.ts +137 -0
  213. package/src/plugins/builtin/cloud/terminal-relay/host.tsx +81 -0
  214. package/src/plugins/builtin/cloud/terminal-relay/indicator.tsx +82 -0
  215. package/src/plugins/builtin/cloud/terminal-relay/manifest.ts +234 -0
  216. package/src/plugins/builtin/cloud/terminal-relay/policy.ts +153 -0
  217. package/src/plugins/builtin/cloud/terminal-relay/prompts.tsx +168 -0
  218. package/src/plugins/builtin/cloud/terminal-relay/redact.ts +73 -0
  219. package/src/plugins/builtin/cloud/terminal-relay/summary.ts +62 -0
  220. package/src/plugins/builtin/cloud/upgrade-dialog.tsx +26 -2
  221. package/src/plugins/builtin/cloud/upgrade-personalization.ts +57 -0
  222. package/src/plugins/builtin/cloud/upgrade-tickers.ts +124 -0
  223. package/src/plugins/builtin/comment-letters/client.ts +1 -3
  224. package/src/plugins/builtin/company-kpis/client.ts +23 -8
  225. package/src/plugins/builtin/company-kpis/headless.ts +3 -1
  226. package/src/plugins/builtin/company-kpis/pane.tsx +15 -7
  227. package/src/plugins/builtin/company-kpis/screenshot-evidence.ts +10 -3
  228. package/src/plugins/builtin/composite-plugins.ts +107 -64
  229. package/src/plugins/builtin/credit-boards/cdx-pane.tsx +4 -4
  230. package/src/plugins/builtin/credit-boards/index.tsx +21 -21
  231. package/src/plugins/builtin/credit-boards/model.ts +0 -1
  232. package/src/plugins/builtin/credit-boards/pane.tsx +30 -0
  233. package/src/plugins/builtin/credit-boards/sovr-pane.tsx +4 -4
  234. package/src/plugins/builtin/debt-maturities/client.ts +37 -9
  235. package/src/plugins/builtin/debt-maturities/headless.ts +3 -1
  236. package/src/plugins/builtin/debt-maturities/pane.tsx +5 -4
  237. package/src/plugins/builtin/dividend-yield/index.tsx +1 -1
  238. package/src/plugins/builtin/dividend-yield/pane.tsx +1 -1
  239. package/src/plugins/builtin/earnings-calls/data.ts +28 -7
  240. package/src/plugins/builtin/earnings-calls/headless.ts +3 -2
  241. package/src/plugins/builtin/earnings-calls/pane.tsx +10 -5
  242. package/src/plugins/builtin/econ/calendar-model.ts +42 -17
  243. package/src/plugins/builtin/econ/detail-view.tsx +2 -2
  244. package/src/plugins/builtin/econ/index.tsx +68 -22
  245. package/src/plugins/builtin/econ-statistics/headless.ts +12 -2
  246. package/src/plugins/builtin/econ-statistics/pane.tsx +1 -1
  247. package/src/plugins/builtin/econ-statistics/view.ts +17 -0
  248. package/src/plugins/builtin/executives/data.ts +17 -6
  249. package/src/plugins/builtin/executives/pane.tsx +16 -7
  250. package/src/plugins/builtin/filing-events/pane.tsx +22 -5
  251. package/src/plugins/builtin/fx-matrix/freshness.ts +65 -0
  252. package/src/plugins/builtin/fx-matrix/index.tsx +22 -1
  253. package/src/plugins/builtin/fx-matrix/pairs.ts +1 -1
  254. package/src/plugins/builtin/fx-matrix/settings.ts +42 -2
  255. package/src/plugins/builtin/gpu/headless.ts +9 -3
  256. package/src/plugins/builtin/gpu/model.ts +14 -5
  257. package/src/plugins/builtin/help/index.tsx +1 -0
  258. package/src/plugins/builtin/holders/beneficial-client.ts +29 -7
  259. package/src/plugins/builtin/holders/beneficial-view.tsx +7 -3
  260. package/src/plugins/builtin/holders/headless.ts +6 -1
  261. package/src/plugins/builtin/holders/pane.tsx +3 -0
  262. package/src/plugins/builtin/insider/index.tsx +4 -4
  263. package/src/plugins/builtin/iv-history/charts.tsx +21 -7
  264. package/src/plugins/builtin/iv-history/client.ts +12 -2
  265. package/src/plugins/builtin/iv-history/format.ts +33 -2
  266. package/src/plugins/builtin/iv-history/headless.ts +22 -10
  267. package/src/plugins/builtin/iv-history/index.tsx +3 -3
  268. package/src/plugins/builtin/iv-history/model.ts +61 -13
  269. package/src/plugins/builtin/iv-history/pane.tsx +11 -3
  270. package/src/plugins/builtin/iv-history/screen-pane.tsx +42 -18
  271. package/src/plugins/builtin/jobs/pane.tsx +1 -1
  272. package/src/plugins/builtin/kelly-sizer/headless.ts +149 -0
  273. package/src/plugins/builtin/kelly-sizer/history.ts +80 -0
  274. package/src/plugins/builtin/kelly-sizer/index.tsx +2 -0
  275. package/src/plugins/builtin/kelly-sizer/pane.tsx +109 -39
  276. package/src/plugins/builtin/kelly-sizer/sections.tsx +14 -0
  277. package/src/plugins/builtin/kelly-sizer/types.ts +9 -1
  278. package/src/plugins/builtin/layout-manager/index.tsx +9 -1
  279. package/src/plugins/builtin/macro-day/client.ts +24 -0
  280. package/src/plugins/builtin/macro-day/headless.ts +11 -8
  281. package/src/plugins/builtin/macro-day/index.tsx +3 -0
  282. package/src/plugins/builtin/macro-day/model.ts +11 -6
  283. package/src/plugins/builtin/macro-day/pane.tsx +12 -8
  284. package/src/plugins/builtin/macro-day/release-table.ts +40 -0
  285. package/src/plugins/builtin/macro-day/releases.ts +62 -44
  286. package/src/plugins/builtin/market-heatmap/data.ts +25 -5
  287. package/src/plugins/builtin/market-heatmap/evidence.ts +90 -0
  288. package/src/plugins/builtin/market-heatmap/index.tsx +144 -63
  289. package/src/plugins/builtin/market-heatmap/model.ts +94 -3
  290. package/src/plugins/builtin/market-heatmap/portfolio.ts +12 -2
  291. package/src/plugins/builtin/market-movers/headless.ts +31 -4
  292. package/src/plugins/builtin/market-movers/index.tsx +8 -1
  293. package/src/plugins/builtin/market-movers/model.ts +71 -17
  294. package/src/plugins/builtin/market-movers/table.ts +50 -23
  295. package/src/plugins/builtin/news/headless.ts +9 -2
  296. package/src/plugins/builtin/news/wire/news/footer.ts +10 -0
  297. package/src/plugins/builtin/openfda/client.ts +1 -1
  298. package/src/plugins/builtin/options/carry.ts +95 -0
  299. package/src/plugins/builtin/options/index.tsx +58 -5
  300. package/src/plugins/builtin/options/strike-window.ts +183 -0
  301. package/src/plugins/builtin/options/table.ts +55 -3
  302. package/src/plugins/builtin/options/types.ts +8 -1
  303. package/src/plugins/builtin/options/view.tsx +161 -12
  304. package/src/plugins/builtin/options-positioning/headless.ts +4 -2
  305. package/src/plugins/builtin/options-scenario/charts.tsx +2 -2
  306. package/src/plugins/builtin/options-scenario/client.ts +73 -17
  307. package/src/plugins/builtin/options-scenario/headless.ts +71 -24
  308. package/src/plugins/builtin/options-scenario/hedge.ts +284 -0
  309. package/src/plugins/builtin/options-scenario/index.tsx +9 -2
  310. package/src/plugins/builtin/options-scenario/model.ts +33 -0
  311. package/src/plugins/builtin/options-scenario/pane.tsx +40 -16
  312. package/src/plugins/builtin/pe-band/model.ts +2 -2
  313. package/src/plugins/builtin/pe-band/report-dates.ts +11 -7
  314. package/src/plugins/builtin/perps/equity-row.tsx +8 -5
  315. package/src/plugins/builtin/perps/model.ts +16 -5
  316. package/src/plugins/builtin/plugin-marketplace/model.ts +64 -21
  317. package/src/plugins/builtin/plugin-marketplace/packs.ts +118 -0
  318. package/src/plugins/builtin/plugin-marketplace/pane.tsx +344 -32
  319. package/src/plugins/builtin/plugin-marketplace/store.ts +7 -1
  320. package/src/plugins/builtin/plugin-module.ts +87 -4
  321. package/src/plugins/builtin/portfolio-list/cli/portfolio-command.ts +71 -36
  322. package/src/plugins/builtin/portfolio-list/cli/render.ts +87 -18
  323. package/src/plugins/builtin/portfolio-list/cli/shared.ts +2 -16
  324. package/src/plugins/builtin/portfolio-list/headless.ts +38 -7
  325. package/src/plugins/builtin/realized-vol/headless.ts +3 -0
  326. package/src/plugins/builtin/realized-vol/pane.tsx +1 -1
  327. package/src/plugins/builtin/research/corporate-actions-pane.tsx +2 -2
  328. package/src/plugins/builtin/research/equity-diagnostic-pane.tsx +1 -1
  329. package/src/plugins/builtin/revenue-breakdown/client.ts +13 -6
  330. package/src/plugins/builtin/revenue-breakdown/headless.ts +4 -1
  331. package/src/plugins/builtin/revenue-breakdown/pane.tsx +7 -4
  332. package/src/plugins/builtin/reverse-dcf/headless.ts +5 -1
  333. package/src/plugins/builtin/reverse-dcf/pane.tsx +1 -1
  334. package/src/plugins/builtin/risk-factors/data.ts +23 -9
  335. package/src/plugins/builtin/risk-factors/headless.ts +5 -2
  336. package/src/plugins/builtin/risk-factors/pane.tsx +6 -5
  337. package/src/plugins/builtin/seasonality/pane.tsx +1 -1
  338. package/src/plugins/builtin/sec/index.tsx +5 -5
  339. package/src/plugins/builtin/sectors/client.ts +10 -2
  340. package/src/plugins/builtin/sectors/headless.ts +35 -6
  341. package/src/plugins/builtin/sectors/index.tsx +18 -1
  342. package/src/plugins/builtin/sectors/sector-model.ts +150 -41
  343. package/src/plugins/builtin/shared/command-tab.ts +51 -0
  344. package/src/plugins/builtin/shared/headless-market-data.ts +33 -1
  345. package/src/plugins/builtin/shared/members-menu.tsx +4 -4
  346. package/src/plugins/builtin/shared/report-freshness.ts +50 -2
  347. package/src/plugins/builtin/shared/ticker-request.ts +25 -1
  348. package/src/plugins/builtin/shared/use-quote-board.ts +25 -5
  349. package/src/plugins/builtin/shared/volatility/options.ts +1 -46
  350. package/src/plugins/builtin/short-interest/index.tsx +19 -4
  351. package/src/plugins/builtin/short-interest/surface.tsx +4 -4
  352. package/src/plugins/builtin/short-volume/index.tsx +1 -10
  353. package/src/plugins/builtin/supply-chain/model.ts +1 -1
  354. package/src/plugins/builtin/ticker-detail/headless.ts +43 -21
  355. package/src/plugins/builtin/ticker-detail/pane.tsx +4 -5
  356. package/src/plugins/builtin/ticker-detail/quote-monitor/card.tsx +94 -6
  357. package/src/plugins/builtin/treasury-auctions/cache.ts +5 -2
  358. package/src/plugins/builtin/treasury-auctions/client.ts +22 -8
  359. package/src/plugins/builtin/treasury-auctions/headless.ts +40 -4
  360. package/src/plugins/builtin/treasury-auctions/index.tsx +11 -9
  361. package/src/plugins/builtin/treasury-auctions/model.ts +197 -30
  362. package/src/plugins/builtin/treasury-auctions/pane.tsx +35 -11
  363. package/src/plugins/builtin/treasury-auctions/types.ts +11 -1
  364. package/src/plugins/builtin/vol-surface/charts.tsx +1 -3
  365. package/src/plugins/builtin/vol-surface/client.ts +6 -2
  366. package/src/plugins/builtin/vol-surface/evidence.ts +11 -6
  367. package/src/plugins/builtin/vol-surface/headless.ts +124 -20
  368. package/src/plugins/builtin/vol-surface/model.ts +23 -11
  369. package/src/plugins/builtin/vol-surface/pane.tsx +38 -27
  370. package/src/plugins/builtin/vol-surface/tables.ts +124 -0
  371. package/src/plugins/builtin/world-indices/client.ts +22 -4
  372. package/src/plugins/builtin/world-indices/headless.ts +54 -27
  373. package/src/plugins/builtin/world-indices/model.ts +4 -2
  374. package/src/plugins/builtin/world-indices/table.tsx +13 -2
  375. package/src/plugins/builtin/world-venue-map/geo-series.ts +1 -1
  376. package/src/plugins/builtin/world-venue-map/index.ts +1 -1
  377. package/src/plugins/builtin/yield-curve/index.tsx +1 -1
  378. package/src/plugins/builtin-editorial.ts +126 -0
  379. package/src/plugins/catalog-backend.ts +16 -9
  380. package/src/plugins/catalog-browser.ts +127 -63
  381. package/src/plugins/catalog-manifest.ts +73 -40
  382. package/src/plugins/catalog-ui.ts +26 -6
  383. package/src/plugins/extracted-plugins.ts +7 -1
  384. package/src/plugins/ownership.ts +150 -7
  385. package/src/plugins/plugin-functions.ts +54 -0
  386. package/src/plugins/plugin-off.ts +36 -0
  387. package/src/plugins/registry/host-actions.ts +16 -0
  388. package/src/plugins/registry/index.ts +84 -24
  389. package/src/plugins/registry/plugin-state.ts +25 -1
  390. package/src/plugins/runtime/context.tsx +29 -0
  391. package/src/react/input.ts +48 -1
  392. package/src/remote/app-host.tsx +5 -0
  393. package/src/remote/controller.ts +3 -53
  394. package/src/remote/matching.ts +69 -0
  395. package/src/remote/schema.ts +1 -1
  396. package/src/remote/semantic-tree.tsx +14 -0
  397. package/src/remote/types.ts +2 -0
  398. package/src/renderers/dom/desktop/icons.tsx +14 -0
  399. package/src/renderers/dom/desktop/query-bar.tsx +59 -32
  400. package/src/renderers/dom/host/box.tsx +1 -1
  401. package/src/renderers/dom/host/drag-shield.ts +17 -6
  402. package/src/renderers/dom/host/live-frame.ts +10 -2
  403. package/src/renderers/dom/input-host.tsx +6 -1
  404. package/src/renderers/dom/styles.css +13 -0
  405. package/src/renderers/electrobun/bun/desktop/backend.ts +5 -1
  406. package/src/renderers/electrobun/bun/desktop/detached-windows.ts +12 -1
  407. package/src/renderers/electrobun/bun/desktop/initialization.ts +2 -1
  408. package/src/renderers/electrobun/shared/protocol.ts +2 -0
  409. package/src/renderers/electrobun/view/cli-pane-shot-entry.tsx +1 -1
  410. package/src/renderers/electrobun/view/cli-pane-shot-frame.tsx +101 -5
  411. package/src/renderers/electrobun/view/main.tsx +4 -1
  412. package/src/renderers/opentui/input-host.tsx +6 -1
  413. package/src/renderers/opentui/start.tsx +9 -0
  414. package/src/shares/portable-layout.ts +16 -6
  415. package/src/sources/gloomberb-cloud/index.ts +19 -10
  416. package/src/sources/gloomberb-cloud/normalizers.ts +4 -1
  417. package/src/sources/listing-symbols.ts +11 -5
  418. package/src/sources/provider-errors.ts +88 -3
  419. package/src/sources/provider-router/cached-routes.ts +8 -4
  420. package/src/sources/provider-router/financial-routes.ts +11 -5
  421. package/src/sources/provider-router/financials.ts +42 -15
  422. package/src/sources/provider-router/history.ts +27 -11
  423. package/src/sources/provider-router/index.ts +1 -1
  424. package/src/sources/provider-router/primary.ts +23 -5
  425. package/src/sources/sec-edgar.ts +68 -8
  426. package/src/sync/core-contributors.ts +4 -3
  427. package/src/test-support/cli-context.ts +2 -1
  428. package/src/test-support/data-provider.ts +34 -0
  429. package/src/test-support/shell-pane-keys.tsx +1 -0
  430. package/src/theme/series-colors.ts +46 -0
  431. package/src/theme/themes.ts +149 -0
  432. package/src/tickers/search/index.ts +22 -2
  433. package/src/tickers/search/ranking.ts +45 -1
  434. package/src/tickers/search/types.ts +3 -1
  435. package/src/time-series/resolve.ts +1 -14
  436. package/src/types/config.ts +61 -1
  437. package/src/types/headless.ts +11 -0
  438. package/src/types/instrument.ts +8 -0
  439. package/src/types/plugin.ts +49 -3
  440. package/src/ui/host.tsx +8 -4
  441. package/src/ui/index.tsx +2 -0
  442. package/src/utils/cli-output.ts +14 -1
  443. package/src/utils/exchanges.ts +13 -0
  444. package/src/utils/format.ts +2 -1
  445. package/src/utils/fx-market-hours.ts +34 -0
  446. package/src/utils/option-expiry.ts +126 -0
  447. package/src/utils/price-history.ts +39 -6
  448. package/src/utils/rpc-timeout-error.ts +6 -2
  449. package/src/utils/sec-eps-basis.ts +159 -30
  450. package/src/utils/sec.ts +38 -34
  451. package/src/utils/throttled-fetch.ts +51 -22
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "gloomberb",
3
- "version": "0.16.3",
3
+ "version": "0.16.4",
4
4
  "packageManager": "bun@1.3.11",
5
5
  "description": "Market research and portfolio tracker for the terminal",
6
6
  "module": "src/public/index.ts",
@@ -67,6 +67,7 @@
67
67
  "plugins:registry:check": "bun run scripts/check-registry-plugins.ts",
68
68
  "web:proxy-hosts": "bun run scripts/generate-web-proxy-hosts.ts",
69
69
  "map:data": "bun run scripts/generate-world-map-data.ts",
70
+ "macro-releases:update": "bun run scripts/update-macro-releases.ts",
70
71
  "web:proxy-hosts:check": "bun run scripts/generate-web-proxy-hosts.ts --check",
71
72
  "typecheck": "bun run typecheck:opentui && bun run typecheck:dom && bun run typecheck:cloudflare && bun run typecheck:scripts && bun run typecheck:plugin-tests",
72
73
  "typecheck:opentui": "tsc --project tsconfig.opentui.json",
@@ -79,6 +80,8 @@
79
80
  "benchmark:tui:navigation": "bun run scripts/benchmark-tui-navigation.ts",
80
81
  "benchmark:tui:compare": "bun run scripts/benchmark-tui-compare.ts",
81
82
  "benchmark:tui:memory": "bun run scripts/benchmark-tui-memory.ts",
83
+ "check:pane-chrome": "bun run scripts/pane-chrome/checks.ts",
84
+ "benchmark:pane-drag:compare": "bun run scripts/pane-chrome/frame-budget.ts",
82
85
  "test:global-upgrade": "bun run scripts/smoke-global-upgrade.ts",
83
86
  "release": "./scripts/release.sh"
84
87
  },
@@ -1,7 +1,10 @@
1
1
  import {
2
2
  ASKG_PROTOCOL_VERSION,
3
+ type ASKGCapabilities,
3
4
  type ASKGDoneReason,
4
5
  type ASKGErrorCode,
6
+ type ASKGFeedback,
7
+ type ASKGFeedbackRequest,
5
8
  type ASKGSessionStartRequest,
6
9
  type ASKGSessionStartResponse,
7
10
  type ASKGSseEvent,
@@ -90,10 +93,14 @@ interface ASKGConversationMessage {
90
93
  tools: ASKGConversationTool[];
91
94
  turnId: string | null;
92
95
  createdAt: string;
96
+ /** On an answer: the person's own rating, null when unrated. */
97
+ feedback?: ASKGFeedback | null;
93
98
  }
94
99
 
95
100
  export interface ASKGConversationDetail extends ASKGConversationSummary {
96
101
  messages: ASKGConversationMessage[];
102
+ /** `feedback: 1` when this server takes ratings; absent from an older one. */
103
+ capabilities?: ASKGCapabilities;
97
104
  }
98
105
 
99
106
  export interface ASKGTransport {
@@ -134,6 +141,16 @@ export interface ASKGTransport {
134
141
  id: string,
135
142
  options?: { signal?: AbortSignal },
136
143
  ): Promise<boolean>;
144
+ /**
145
+ * Rates one answer and returns the rating as stored. Null when the server
146
+ * has no answer of this person's under that id, which is also what a
147
+ * server without the route says.
148
+ */
149
+ sendFeedback(
150
+ turnId: string,
151
+ request: ASKGFeedbackRequest,
152
+ options?: { signal?: AbortSignal },
153
+ ): Promise<ASKGFeedback | null>;
137
154
  }
138
155
 
139
156
  /** One decoded server-sent event frame. */
@@ -662,4 +679,30 @@ export class CloudASKGApi implements ASKGTransport {
662
679
  throw classifyASKGRequestError(error);
663
680
  }
664
681
  }
682
+
683
+ async sendFeedback(
684
+ turnId: string,
685
+ request: ASKGFeedbackRequest,
686
+ options: { signal?: AbortSignal } = {},
687
+ ): Promise<ASKGFeedback | null> {
688
+ try {
689
+ const stored = await this.options.request<Partial<ASKGFeedback> | null>(
690
+ `/askg/turns/${encodeURIComponent(turnId)}/feedback`,
691
+ {
692
+ method: "PUT",
693
+ body: JSON.stringify(request),
694
+ signal: options.signal,
695
+ },
696
+ );
697
+ // What the server stored, read defensively: the control shows it.
698
+ return {
699
+ rating: stored?.rating === "down" ? "down" : stored?.rating === "up" ? "up" : request.rating,
700
+ reason: stored?.reason ?? null,
701
+ shared: stored?.shared === true,
702
+ };
703
+ } catch (error) {
704
+ if (error instanceof ApiRequestError && error.status === 404) return null;
705
+ throw classifyASKGRequestError(error);
706
+ }
707
+ }
665
708
  }
@@ -11,8 +11,10 @@ import type {
11
11
  CloudBrowserHandoffResponse,
12
12
  CloudPricing,
13
13
  CloudVerificationResponse,
14
+ CreatedMcpKey,
14
15
  DeviceAuthStartResponse,
15
16
  DeviceAuthTokenResponse,
17
+ McpKeyScope,
16
18
  PersistedAuthUser,
17
19
  } from "./types";
18
20
 
@@ -269,6 +271,19 @@ export class CloudAuthApi {
269
271
  return result.feed;
270
272
  }
271
273
 
274
+ /**
275
+ * Creates an MCP key for an agent, the same call as Cloud settings, Agents.
276
+ * Needs Pro (402 otherwise) and fails with 409 at the per-account limit. The
277
+ * token in the answer is never returned again, so callers show it once and
278
+ * keep it out of logs and storage.
279
+ */
280
+ async createMcpKey(input: { name: string; scope: McpKeyScope }): Promise<CreatedMcpKey> {
281
+ return this.options.request<CreatedMcpKey>("/account/mcp/keys", {
282
+ method: "POST",
283
+ body: JSON.stringify({ name: input.name, scope: input.scope }),
284
+ });
285
+ }
286
+
272
287
  /** A new calendar feed link; the old one stops working. */
273
288
  async rotateCalendarFeed(): Promise<CalendarFeed> {
274
289
  const result = await this.options.request<{ feed: CalendarFeed }>(
@@ -85,6 +85,10 @@ export interface BeneficialOwnersPayload {
85
85
 
86
86
  export interface CloudBeneficialOwnersParams {
87
87
  ticker: string;
88
+ /** The listing's venue. Sent only for a venue outside the US, with `name`. */
89
+ exchange?: string;
90
+ /** The listing's company name, from its ticker or its own quote. */
91
+ name?: string;
88
92
  form?: BeneficialOwnersForm;
89
93
  history?: boolean;
90
94
  limit?: number;
@@ -1,6 +1,7 @@
1
1
  import {
2
2
  normalizeChatAttachments,
3
3
  normalizeChatChannel,
4
+ normalizeChatDiscordLink,
4
5
  normalizeChatMessage,
5
6
  normalizeChatMessages,
6
7
  normalizeChatState,
@@ -10,6 +11,7 @@ import type {
10
11
  ChatAttachment,
11
12
  ChatChannel,
12
13
  ChatChannelState,
14
+ ChatDiscordLink,
13
15
  ChatMessage,
14
16
  ChatNotification,
15
17
  ChatStateResponse,
@@ -256,6 +258,23 @@ export class CloudChatApi {
256
258
  return normalizeChatMessage(message);
257
259
  }
258
260
 
261
+ /** Whether this account is tied to a Discord person. Throws a 404 or 501 `ApiRequestError` on a server without Discord sync. */
262
+ async getDiscordLink(): Promise<ChatDiscordLink> {
263
+ return normalizeChatDiscordLink(await this.options.request<unknown>("/chat/discord/link"));
264
+ }
265
+
266
+ async unlinkDiscord(): Promise<void> {
267
+ await this.options.request<unknown>("/chat/discord/link", { method: "DELETE" });
268
+ }
269
+
270
+ /** Turns the mirroring of your own public messages to Discord on or off. */
271
+ async setDiscordMirror(enabled: boolean): Promise<void> {
272
+ await this.options.request<unknown>("/chat/discord/mirror", {
273
+ method: "PUT",
274
+ body: JSON.stringify({ enabled }),
275
+ });
276
+ }
277
+
259
278
  connectChannel(
260
279
  channelId: string,
261
280
  onMessage: (msg: ChatMessage) => void,
@@ -1,3 +1,5 @@
1
+ import { listingAbroad, type IssuerListingParams } from "./paths";
2
+
1
3
  type QuoteMatchMode = "exact" | "whitespace" | "nfkc_whitespace";
2
4
 
3
5
  type KpiBasis = "reported" | "adjusted" | "constant_currency" | "organic"
@@ -147,7 +149,17 @@ export interface KpiQueryOptions {
147
149
  /** Point-in-time publication cutoff; excludes later restatements and actuals. */
148
150
  asOf?: string
149
151
  }
150
- export function companyDisclosurePath(section: "kpis" | "guidance", symbol: string, options: KpiQueryOptions): string {
152
+ /**
153
+ * A US listing or a bare symbol asks for the symbol as before. A listing abroad
154
+ * asks for its bare symbol with its venue and company, so it never reads the
155
+ * disclosures of a US company that has the same symbol.
156
+ */
157
+ export function companyDisclosurePath(section: "kpis" | "guidance", symbol: string, options: KpiQueryOptions, listing: IssuerListingParams = {}): string {
151
158
  const query = new URLSearchParams(Object.entries(options).filter((entry): entry is [string, string] => entry[1] != null));
152
- return `/cloud/company-${section}/${encodeURIComponent(symbol)}?${query}`;
159
+ const abroad = listingAbroad(symbol, listing.exchange, listing.name);
160
+ if (abroad) {
161
+ query.set("exchange", abroad.exchange);
162
+ if (abroad.name) query.set("name", abroad.name);
163
+ }
164
+ return `/cloud/company-${section}/${encodeURIComponent(abroad?.symbol ?? symbol)}?${query}`;
153
165
  }
@@ -65,11 +65,14 @@ import {
65
65
  cloudJobsPath,
66
66
  cloudJobsPostingsPath,
67
67
  type CloudJobsPostingsParams,
68
+ type IssuerListingParams,
68
69
  cloudProxyStatementPath,
70
+ cloudDebtMaturitiesPath,
69
71
  cloudFilingEventsPath,
70
72
  cloudRiskReportPath,
71
73
  cloudRiskReportsPath,
72
74
  cloudProxyStatementsPath,
75
+ cloudRevenueBreakdownPath,
73
76
  cloudExchangeRatePath,
74
77
  cloudSec13FPath,
75
78
  cloudSecBeneficialOwnersPath,
@@ -120,8 +123,10 @@ import type {
120
123
  CloudRiskReportPayload,
121
124
  CloudCorporateActionsPayload,
122
125
  CloudEconEventPayload,
126
+ CloudMacroReleaseDaysPayload,
123
127
  CloudEquityDiagnosticMode,
124
128
  CloudEquityDiagnosticResult,
129
+ CloudFredSeriesCatalogPayload,
125
130
  CloudFredSeriesPayload,
126
131
  CloudShillerPayload,
127
132
  CloudFinancialsPayload,
@@ -414,6 +419,10 @@ export class CloudDataApi {
414
419
  return this.request<CloudEconEventPayload[]>("/cloud/econ/calendar");
415
420
  }
416
421
 
422
+ async getCloudMacroReleaseDays(): Promise<CloudMacroReleaseDaysPayload> {
423
+ return this.request<CloudMacroReleaseDaysPayload>("/cloud/econ/release-days");
424
+ }
425
+
417
426
  async getCloudFredSeries(
418
427
  seriesId: string,
419
428
  params: CloudFredSeriesParams = {},
@@ -425,6 +434,11 @@ export class CloudDataApi {
425
434
  );
426
435
  }
427
436
 
437
+ /** Every series `getCloudFredSeries` serves. A server older than the list answers 404. */
438
+ async getCloudFredSeriesCatalog(): Promise<CloudFredSeriesCatalogPayload> {
439
+ return this.request<CloudFredSeriesCatalogPayload>("/cloud/econ/series");
440
+ }
441
+
428
442
  async getCloudShiller(): Promise<CloudShillerPayload> {
429
443
  return this.request<CloudShillerPayload>(cloudShillerPath());
430
444
  }
@@ -483,12 +497,13 @@ export class CloudDataApi {
483
497
  return this.request<CatalystStatus>("/cloud/catalysts/status");
484
498
  }
485
499
 
486
- async getCloudCompanyKpis(symbol: string, options: KpiQueryOptions = {}): Promise<KpisPayload> {
487
- return this.request<KpisPayload>(companyDisclosurePath("kpis", symbol, options));
500
+ /** `listing` names a listing abroad's venue and company; a US listing needs neither. */
501
+ async getCloudCompanyKpis(symbol: string, options: KpiQueryOptions = {}, listing: IssuerListingParams = {}): Promise<KpisPayload> {
502
+ return this.request<KpisPayload>(companyDisclosurePath("kpis", symbol, options, listing));
488
503
  }
489
504
 
490
- async getCloudCompanyGuidance(symbol: string, options: KpiQueryOptions = {}): Promise<GuidancePayload> {
491
- return this.request<GuidancePayload>(companyDisclosurePath("guidance", symbol, options));
505
+ async getCloudCompanyGuidance(symbol: string, options: KpiQueryOptions = {}, listing: IssuerListingParams = {}): Promise<GuidancePayload> {
506
+ return this.request<GuidancePayload>(companyDisclosurePath("guidance", symbol, options, listing));
492
507
  }
493
508
  async getCloudPerpsBoard(query: PerpBoardQuery = {}): Promise<PerpBoardPayload> {
494
509
  return this.request(`/cloud/perps/board?${new URLSearchParams(Object.entries(query).filter(([, value]) => value !== undefined).map(([key, value]) => [key, String(value)]))}`);
@@ -619,14 +634,12 @@ export class CloudDataApi {
619
634
  return this.request<MoneyMarketsPayload>("/cloud/econ/money-markets", { signal: AbortSignal.timeout(45_000) });
620
635
  }
621
636
 
622
- async getCloudDebtMaturities(symbol: string): Promise<DebtMaturitiesPayload> {
623
- const params = new URLSearchParams({ symbol });
624
- return this.request<DebtMaturitiesPayload>(`/cloud/debt-maturities?${params}`, { signal: AbortSignal.timeout(45_000) });
637
+ async getCloudDebtMaturities(symbol: string, listing?: IssuerListingParams): Promise<DebtMaturitiesPayload> {
638
+ return this.request<DebtMaturitiesPayload>(cloudDebtMaturitiesPath(symbol, listing), { signal: AbortSignal.timeout(45_000) });
625
639
  }
626
640
 
627
- async getCloudRevenueBreakdown(symbol: string, view?: RevenueBreakdownView): Promise<RevenueBreakdownPayload> {
628
- const params = new URLSearchParams({ symbol, ...(view ? { view } : {}) });
629
- return this.request<RevenueBreakdownPayload>(`/cloud/revenue-breakdown?${params}`, { signal: AbortSignal.timeout(30_000) });
641
+ async getCloudRevenueBreakdown(symbol: string, view?: RevenueBreakdownView, listing?: IssuerListingParams): Promise<RevenueBreakdownPayload> {
642
+ return this.request<RevenueBreakdownPayload>(cloudRevenueBreakdownPath(symbol, view, listing), { signal: AbortSignal.timeout(30_000) });
630
643
  }
631
644
 
632
645
  async getCloudMnaDeals(params: MnaDealsParams = {}, options?: { signal?: AbortSignal }): Promise<MnaDealsPayload> {
@@ -756,44 +769,49 @@ export class CloudDataApi {
756
769
  );
757
770
  }
758
771
 
772
+ // A listing outside the US also sends its venue and company (listingAbroad).
759
773
  async getProxyStatements(
760
774
  ticker: string,
775
+ listing?: IssuerListingParams,
761
776
  ): Promise<CloudProxyStatementListPayload> {
762
777
  return this.request<CloudProxyStatementListPayload>(
763
- cloudProxyStatementsPath(ticker),
778
+ cloudProxyStatementsPath(ticker, listing),
764
779
  );
765
780
  }
766
781
 
767
782
  async getProxyStatement(
768
783
  ticker: string,
769
784
  year: number,
785
+ listing?: IssuerListingParams,
770
786
  ): Promise<CloudProxyStatementPayload> {
771
787
  return this.request<CloudProxyStatementPayload>(
772
- cloudProxyStatementPath(ticker, year),
788
+ cloudProxyStatementPath(ticker, year, listing),
773
789
  );
774
790
  }
775
791
 
776
792
  async getFilingEvents(
777
793
  ticker: string,
778
794
  limit?: number,
795
+ listing?: IssuerListingParams,
779
796
  ): Promise<{ ticker: string; events: CloudFilingEventPayload[] }> {
780
797
  return this.request<{ ticker: string; events: CloudFilingEventPayload[] }>(
781
- cloudFilingEventsPath(ticker, limit),
798
+ cloudFilingEventsPath(ticker, limit, listing),
782
799
  );
783
800
  }
784
801
 
785
- async getRiskReports(ticker: string): Promise<CloudRiskReportListPayload> {
802
+ async getRiskReports(ticker: string, listing?: IssuerListingParams): Promise<CloudRiskReportListPayload> {
786
803
  return this.request<CloudRiskReportListPayload>(
787
- cloudRiskReportsPath(ticker),
804
+ cloudRiskReportsPath(ticker, listing),
788
805
  );
789
806
  }
790
807
 
791
808
  async getRiskReport(
792
809
  ticker: string,
793
810
  year: number,
811
+ listing?: IssuerListingParams,
794
812
  ): Promise<CloudRiskReportPayload> {
795
813
  return this.request<CloudRiskReportPayload>(
796
- cloudRiskReportPath(ticker, year),
814
+ cloudRiskReportPath(ticker, year, listing),
797
815
  );
798
816
  }
799
817
 
@@ -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);
@@ -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);
389
+ }
390
+
391
+ export function cloudRiskReportsPath(ticker: string, listing?: IssuerListingParams): string {
392
+ return issuerPath("/cloud/risks", ticker, listing);
338
393
  }
339
394
 
340
- export function cloudRiskReportsPath(ticker: string): string {
341
- return `/cloud/risks/${encodeURIComponent(normalizeIssuerResearchTicker(ticker))}`;
395
+ export function cloudRiskReportPath(ticker: string, year: number, listing?: IssuerListingParams): string {
396
+ return issuerPath("/cloud/risks", ticker, listing, `/${year}`);
342
397
  }
343
398
 
344
- export function cloudRiskReportPath(ticker: string, year: number): string {
345
- return `/cloud/risks/${encodeURIComponent(normalizeIssuerResearchTicker(ticker))}/${year}`;
399
+ export function cloudProxyStatementPath(ticker: string, year: number, listing?: IssuerListingParams): string {
400
+ return issuerPath("/cloud/proxies", ticker, listing, `/${year}`);
346
401
  }
347
402
 
348
- export function cloudProxyStatementPath(ticker: string, year: number): string {
349
- return `/cloud/proxies/${encodeURIComponent(normalizeIssuerResearchTicker(ticker))}/${year}`;
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));
@@ -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.