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
@@ -5,9 +5,9 @@ import type {
5
5
  HeadlessPaneLoadArgs,
6
6
  } from "../../../types/plugin";
7
7
  import { formatNumber, formatPercentRaw } from "../../../utils/format";
8
- import { marketStateLabel } from "../../../market-data/market/status";
8
+ import { EXTENDED_SESSION_LABELS, getQuoteSessionFields, marketStateLabel, type ExtendedSession } from "../../../market-data/market/status";
9
9
  import type { MarketState } from "../../../types/financials";
10
- import { loadWorldIndexQuotes, type WorldIndexQuoteResult } from "./client";
10
+ import { loadWorldIndexQuotes, NOT_IN_FEED, type WorldIndexQuoteResult } from "./client";
11
11
  import {
12
12
  getIndicesByRegion,
13
13
  REGION_LABELS,
@@ -17,14 +17,17 @@ import {
17
17
  } from "./indices";
18
18
  import { quoteFreshnessFields } from "../shared/report-freshness";
19
19
 
20
+ /** A row for an index the feed does not carry has no figures to print; its last column says why. */
21
+ const isGap = (row: Record<string, unknown>) => row.unavailable === true;
22
+
20
23
  const COLUMNS = [
21
- { key: "shortName", header: "Index" },
24
+ { key: "shortName", header: "Index", shrink: false },
22
25
  { key: "name", header: "Name" },
23
26
  {
24
27
  key: "price",
25
28
  header: "Last",
26
29
  align: "right" as const,
27
- format: (value: unknown) => value == null
30
+ format: (value: unknown, row: Record<string, unknown>) => isGap(row) ? "" : value == null
28
31
  ? "-"
29
32
  : formatNumber(Number(value), 2),
30
33
  },
@@ -32,58 +35,82 @@ const COLUMNS = [
32
35
  key: "change",
33
36
  header: "Change",
34
37
  align: "right" as const,
35
- format: (value: unknown) => value == null ? "-" : `${Number(value) >= 0 ? "+" : ""}${formatNumber(Number(value), 2)}`,
38
+ format: (value: unknown, row: Record<string, unknown>) => isGap(row) ? "" : value == null ? "-" : `${Number(value) >= 0 ? "+" : ""}${formatNumber(Number(value), 2)}`,
36
39
  },
37
40
  {
38
41
  key: "changePercent",
39
42
  header: "Change %",
40
43
  align: "right" as const,
41
- format: (value: unknown) => value == null ? "-" : formatPercentRaw(Number(value)),
44
+ format: (value: unknown, row: Record<string, unknown>) => isGap(row) ? "" : value == null ? "-" : formatPercentRaw(Number(value)),
42
45
  },
43
46
  {
44
47
  key: "marketState",
45
48
  header: "Session",
46
- format: (value: unknown) => typeof value === "string" && value ? marketStateLabel(value as MarketState) ?? value : "-",
49
+ shrink: false,
50
+ format: (value: unknown, row: Record<string, unknown>) => isGap(row) ? "" : typeof value === "string" && value ? marketStateLabel(value as MarketState) ?? value : "-",
47
51
  },
48
52
  {
49
53
  key: "lastUpdated",
50
54
  header: "Updated",
51
- format: (value: unknown) => {
55
+ shrink: false,
56
+ format: (value: unknown, row: Record<string, unknown>) => {
52
57
  const time = value == null ? Number.NaN : Number(value);
53
- return Number.isFinite(time) ? `${new Date(time).toISOString().slice(0, 16).replace("T", " ")} UTC` : "-";
58
+ return Number.isFinite(time) ? `${new Date(time).toISOString().slice(0, 16).replace("T", " ")} UTC` : isGap(row) ? NOT_IN_FEED : "-";
54
59
  },
55
60
  },
56
61
  ];
57
62
 
63
+ /** A pre-market or after-hours print and its move from the regular close, for a row that has one. */
64
+ function extendedColumn(session: ExtendedSession) {
65
+ return {
66
+ key: "extendedPrice",
67
+ header: EXTENDED_SESSION_LABELS[session],
68
+ align: "right" as const,
69
+ format: (value: unknown, row: Record<string, unknown>) => row.extendedSession === session && typeof value === "number"
70
+ ? `${formatNumber(value, 2)} ${formatPercentRaw(typeof row.extendedChangePercent === "number" ? row.extendedChangePercent : undefined)}`
71
+ : isGap(row) ? "" : "-",
72
+ };
73
+ }
74
+
75
+ /** The table's columns, with an extended column after Change % only where a row has such a print. */
76
+ function sectionColumns(rows: readonly Record<string, unknown>[]) {
77
+ const sessions = (["PRE", "POST"] as const).filter((session) => rows.some((row) => row.extendedSession === session));
78
+ return sessions.length === 0 ? COLUMNS : [...COLUMNS.slice(0, 5), ...sessions.map(extendedColumn), ...COLUMNS.slice(5)];
79
+ }
80
+
58
81
  function projectWorldIndicesHeadless(
59
82
  entries: readonly IndexEntry[],
60
83
  loaded: WorldIndexQuoteResult,
61
84
  ): HeadlessBundleResult {
62
85
  const grouped = getIndicesByRegion(entries);
86
+ const isGapEntry = (entry: IndexEntry) => loaded.gaps.has(entry.symbol) && !loaded.quotes.get(entry.symbol);
63
87
  return {
64
88
  sections: REGION_ORDER.flatMap((region) => {
65
89
  const regionEntries = grouped.get(region) ?? [];
66
90
  if (regionEntries.length === 0) return [];
67
- return [{
68
- title: REGION_LABELS[region],
69
- columns: COLUMNS,
70
- rows: regionEntries.map((entry) => {
71
- const quote = loaded.quotes.get(entry.symbol);
72
- return {
73
- ...quoteFreshnessFields(quote),
74
- ...entry,
75
- price: quote?.price ?? null,
76
- unit: "index points",
77
- currency: quote?.currency ?? null,
78
- change: quote?.change ?? null,
79
- changePercent: quote?.changePercent ?? null,
80
- marketState: quote?.marketState ?? null,
81
- lastUpdated: quote?.lastUpdated ?? null,
82
- };
83
- }),
84
- }];
91
+ const rows = regionEntries.map((entry) => {
92
+ const quote = loaded.quotes.get(entry.symbol);
93
+ // Last and Change are the regular session, as `ticker` reads them.
94
+ const { price, change, changePercent, ...extended } = getQuoteSessionFields(quote);
95
+ return {
96
+ ...quoteFreshnessFields(quote),
97
+ ...entry,
98
+ price,
99
+ unit: "index points",
100
+ currency: quote?.currency ?? null,
101
+ change,
102
+ changePercent,
103
+ ...extended,
104
+ marketState: quote?.marketState ?? null,
105
+ lastUpdated: quote?.lastUpdated ?? null,
106
+ ...(isGapEntry(entry) ? { unavailable: true } : {}),
107
+ };
108
+ });
109
+ return [{ title: REGION_LABELS[region], columns: sectionColumns(rows), rows }];
85
110
  }),
86
111
  errors: loaded.errors,
112
+ // A symbol the feed lacks is a gap in the data, not a failure: its row says so, and the report is not whole.
113
+ ...(entries.some(isGapEntry) ? { unavailableSymbols: entries.filter(isGapEntry).map((entry) => entry.symbol) } : {}),
87
114
  metadata: {
88
115
  requested: entries.length,
89
116
  available: [...loaded.quotes.values()].filter(Boolean).length,
@@ -1,6 +1,6 @@
1
1
  import type { MarketState } from "../../../types/financials";
2
2
  import { compareSortValues, type SortDirection } from "../../../utils/sort-values";
3
- import type { BoardQuoteMap } from "../shared/use-quote-board";
3
+ import { boardHeadlineQuote, type BoardQuoteMap } from "../shared/use-quote-board";
4
4
  import { REGION_ORDER, type IndexEntry } from "./indices";
5
5
 
6
6
  export type WorldIndexTableRow =
@@ -40,7 +40,9 @@ function getSortValue(
40
40
  entry: IndexEntry,
41
41
  quotes: BoardQuoteMap,
42
42
  ): string | number | null {
43
- const quote = quotes.get(entry.symbol)?.quote;
43
+ const sent = quotes.get(entry.symbol)?.quote;
44
+ // Sorted by the figures the rows show.
45
+ const quote = sent ? boardHeadlineQuote(sent) : sent;
44
46
 
45
47
  switch (columnId) {
46
48
  case "status":
@@ -3,7 +3,8 @@ import { colors } from "../../../theme/colors";
3
3
  import type { Quote } from "../../../types/financials";
4
4
  import { TextAttributes } from "../../../ui";
5
5
  import { formatNumber } from "../../../utils/format";
6
- import { renderQuoteBoardCell, type BoardQuoteMap } from "../shared/use-quote-board";
6
+ import { renderQuoteBoardCell, type BoardQuoteMap, type BoardQuoteState } from "../shared/use-quote-board";
7
+ import { isFeedGap, NOT_IN_FEED } from "./client";
7
8
  import type {
8
9
  WorldIndexColumnId,
9
10
  WorldIndexTableRow,
@@ -66,6 +67,11 @@ const formatIndexPrice = (quote: Quote) => formatNumber(quote.price, 2);
66
67
  const formatIndexChange = (quote: Quote) =>
67
68
  `${quote.change >= 0 ? "+" : "-"}${formatNumber(Math.abs(quote.change), 2)}`;
68
69
 
70
+ /** An index the feed has no quote for: not loading, and no figures to show. */
71
+ function isUnavailableInFeed(state: BoardQuoteState | undefined): boolean {
72
+ return !!state && !state.quote && !state.loading && isFeedGap(state.error);
73
+ }
74
+
69
75
  export function renderWorldIndexCell(
70
76
  row: WorldIndexTableRow,
71
77
  column: WorldIndexColumn,
@@ -75,6 +81,8 @@ export function renderWorldIndexCell(
75
81
  if (row.type === "header") return { text: "" };
76
82
 
77
83
  const { entry } = row;
84
+ // The figures are blank and the name cell says why, ahead of the name so a narrow pane clips the name, not the reason.
85
+ const unavailable = isUnavailableInFeed(quotes.get(entry.symbol));
78
86
  switch (column.id) {
79
87
  case "symbol":
80
88
  return {
@@ -83,8 +91,11 @@ export function renderWorldIndexCell(
83
91
  attributes: TextAttributes.BOLD,
84
92
  };
85
93
  case "name":
86
- return { text: entry.name };
94
+ return unavailable
95
+ ? { text: `${NOT_IN_FEED} · ${entry.name}`, color: colors.textDim }
96
+ : { text: entry.name };
87
97
  default:
98
+ if (unavailable) return { text: "" };
88
99
  return renderQuoteBoardCell(column.id, quotes.get(entry.symbol), {
89
100
  sessionText: options?.sessionText,
90
101
  formatPrice: formatIndexPrice,
@@ -13,7 +13,7 @@ import {
13
13
  } from "../../../api-client/geo";
14
14
  import { chartSeriesProvider, type ChartSeriesCapability, type ChartSeriesCatalogItem } from "../../../capabilities";
15
15
  import { subtractTimeRange } from "../../../time-series/date-window";
16
- import { SERIES_COLORS } from "../../../time-series/resolve";
16
+ import { SERIES_COLORS } from "../../../theme/series-colors";
17
17
  import type { ChartViewportSpec, ResolvedSeries, TimeSeriesPoint } from "../../../time-series/types";
18
18
  import { GEO_SERIES_CAPABILITY_ID } from "../chart-composer/series-expression";
19
19
  import { cloudGeoRequest } from "./client";
@@ -1,5 +1,5 @@
1
1
  import { peekGeoCatalog } from "../../../api-client/geo";
2
- import { SERIES_COLORS } from "../../../time-series/resolve";
2
+ import { SERIES_COLORS } from "../../../theme/series-colors";
3
3
  import { CHART_COMPOSER_PANE_ID } from "../../../types/config";
4
4
  import type { PaneTemplateDef } from "../../../types/plugin";
5
5
  import { chartHeadless } from "../chart-composer/headless";
@@ -18,7 +18,7 @@ import type { PluginModule } from "../plugin-module";
18
18
  import { useAutoRefresh } from "../../../react/auto-refresh";
19
19
  import { usePaneStatusFooter } from "../../../components/layout/pane/status-footer";
20
20
  import { formatPercentileRank } from "../../../utils/format";
21
- import { SERIES_COLORS } from "../../../time-series/resolve";
21
+ import { SERIES_COLORS } from "../../../theme/series-colors";
22
22
  import type { CurveSeries } from "../../../components/chart/curve";
23
23
  import { yieldCurveHeadless } from "./headless";
24
24
  import {
@@ -0,0 +1,126 @@
1
+ // Editorial copy for the built-in plugins: what the Plugins pane and the
2
+ // plugin directory at gloom.sh say about each one beyond its catalog entry.
3
+ // Import-free, so the pane can read it without pulling in the catalog.
4
+
5
+ export interface BuiltinEditorial {
6
+ /** Curated, since the catalog has no notion of categories. */
7
+ categories: string[];
8
+ featured?: true;
9
+ /** Path to artwork in this repo, resolved by the directory against HEAD. */
10
+ icon?: string;
11
+ /** Ten words and 45 characters at most, for a row or a card; the description says the rest. */
12
+ tagline?: string;
13
+ /** The codes a row or card shows, at most three; the first three otherwise. */
14
+ highlights?: readonly string[];
15
+ /**
16
+ * Codes whose capture the directory shows, at most three, best first. Each
17
+ * names a reviewed image at gloom.sh/screenshots/fn/<CODE>.png.
18
+ */
19
+ screenshots?: readonly string[];
20
+ }
21
+
22
+ /**
23
+ * Anything missing here is reported by `generate-plugin-manifest.ts` rather
24
+ * than silently defaulted, so a new built-in cannot slip into the directory
25
+ * uncategorised.
26
+ */
27
+ export const BUILTIN_EDITORIAL: Readonly<Record<string, BuiltinEditorial>> = {
28
+ "gloomberb-cloud": {
29
+ categories: ["data", "cloud"],
30
+ featured: true,
31
+ tagline: "Account, chat, Ask Gloom and Cloud data.",
32
+ icon: "plugin-icons/gloomberb-cloud.webp",
33
+ },
34
+ alerts: { categories: ["alerts"], tagline: "Price, market and filing alerts." },
35
+ "alt-data": {
36
+ categories: ["research", "data"],
37
+ tagline: "Supply chains, hiring, apps, GPUs and power.",
38
+ highlights: ["SPLC", "GPU", "JOBS"],
39
+ screenshots: ["SPLC", "GPU", "JOBS"],
40
+ },
41
+ application: { categories: ["core"] },
42
+ broker: { categories: ["broker"], tagline: "Broker accounts, sync and connections." },
43
+ "clinical-trials": { categories: ["research"], tagline: "Clinical trials by drug, condition, sponsor." },
44
+ "comment-letters": { categories: ["research"], tagline: "SEC comment letters and company replies." },
45
+ credit: {
46
+ categories: ["macro", "markets"],
47
+ tagline: "CDS, credit spreads, auctions and bonds.",
48
+ highlights: ["CDS", "CRD", "YAS"],
49
+ screenshots: ["CDX", "SOVR", "YAS"],
50
+ },
51
+ crypto: {
52
+ categories: ["markets", "crypto"],
53
+ tagline: "Crypto prices, funding and open interest.",
54
+ screenshots: ["CRYP"],
55
+ },
56
+ "custom-view": { categories: ["data", "productivity"] },
57
+ debug: { categories: ["developer"], tagline: "Debug logs to read and export." },
58
+ earnings: {
59
+ categories: ["research", "markets"],
60
+ tagline: "Earnings calendar, calls and the ripple.",
61
+ screenshots: ["ERN"],
62
+ },
63
+ "fear-greed": { categories: ["markets", "sentiment"], icon: "plugin-icons/fear-greed.webp", tagline: "The Fear & Greed index and its inputs." },
64
+ filings: {
65
+ categories: ["research"],
66
+ tagline: "SEC filings, 8-Ks, risk factors, litigation.",
67
+ highlights: ["SEC", "EK", "RISK"],
68
+ screenshots: ["EK", "RISK"],
69
+ },
70
+ "futures-commodities": {
71
+ categories: ["markets", "macro"],
72
+ tagline: "Futures, curves, positioning, energy data.",
73
+ screenshots: ["CTM", "COT", "FUT"],
74
+ },
75
+ "global-markets": {
76
+ categories: ["markets"],
77
+ tagline: "World indices, map, sectors, FX, rotation.",
78
+ highlights: ["WEI", "MAP", "RRG"],
79
+ screenshots: ["MAP", "RRG", "WEI"],
80
+ },
81
+ "ipo-calendar": { categories: ["macro", "markets"], icon: "plugin-icons/ipo-calendar.webp", tagline: "Upcoming and recent IPOs worldwide." },
82
+ "market-halts": { categories: ["markets"], icon: "plugin-icons/market-halts.webp", tagline: "US trading halts, current and recent." },
83
+ "market-heatmap": { categories: ["markets"], icon: "plugin-icons/market-heatmap.webp", tagline: "The largest US stocks and ETFs as a heatmap." },
84
+ members: { categories: ["markets", "research"], tagline: "ETF holdings and index changes." },
85
+ news: { categories: ["news"], tagline: "Market news wire and company news." },
86
+ notes: { categories: ["productivity"], tagline: "Notes on tickers, personal or shared." },
87
+ openfda: { categories: ["research"], tagline: "FDA adverse events and drug recalls." },
88
+ "options-volatility": {
89
+ categories: ["research", "markets"],
90
+ tagline: "Option chains, positioning and volatility.",
91
+ highlights: ["OMON", "OPX", "OVDV"],
92
+ screenshots: ["OPX", "HIVG", "HVG"],
93
+ },
94
+ ownership: {
95
+ categories: ["research"],
96
+ tagline: "Holders, 13F funds, insiders, short interest.",
97
+ highlights: ["HDS", "INS", "SI"],
98
+ screenshots: ["INS", "SI"],
99
+ },
100
+ portfolio: { categories: ["portfolio"], tagline: "Portfolios, watchlists and position sizing." },
101
+ quant: {
102
+ categories: ["markets", "research"],
103
+ tagline: "Correlations, backtests and seasonality.",
104
+ highlights: ["CORR", "BT", "SEAS"],
105
+ screenshots: ["BT", "CORR", "SEAS"],
106
+ },
107
+ "rates-macro": {
108
+ categories: ["macro"],
109
+ tagline: "Economic data, yield curves, the rate path.",
110
+ highlights: ["ECO", "GC", "WIRP"],
111
+ screenshots: ["WIRP", "CPI", "GC"],
112
+ },
113
+ "research-search": { categories: ["research", "news"], tagline: "Search calls, wires and filings." },
114
+ screeners: {
115
+ categories: ["markets"],
116
+ tagline: "Screener, movers, highs and lows, flow.",
117
+ highlights: ["EQS", "MOST", "FLOW"],
118
+ screenshots: ["EQS", "MOST"],
119
+ },
120
+ "ticker-core": {
121
+ categories: ["research"],
122
+ tagline: "Quotes, charts, financials and estimates.",
123
+ highlights: ["DES", "G", "FA"],
124
+ screenshots: ["DES", "G", "FA"],
125
+ },
126
+ };
@@ -1,18 +1,17 @@
1
1
  import type { GloomPlugin } from "../types/plugin";
2
- import { tickerResearchPluginMeta } from "./builtin/builtin-plugin-meta";
3
- import { composeBuiltinPlugin } from "./builtin/plugin-module";
2
+ import { withoutRendererOnlyModules } from "./builtin/plugin-module";
4
3
  import { getLoadablePlugins } from "./catalog";
5
4
  import { loadExternalPlugins, type LoadedExternalPlugin } from "./loader";
6
5
 
7
- const tickerResearchBackendPlugin = composeBuiltinPlugin({ ...tickerResearchPluginMeta, modules: [] });
8
-
6
+ /**
7
+ * Every loadable plugin, in the same order and under the same ids as the
8
+ * renderer's, so toggles and state line up; built-ins leave out the modules
9
+ * they mark renderer-only.
10
+ */
9
11
  export function getDesktopBackendPlugins(
10
12
  externalPlugins: LoadedExternalPlugin[] = [],
11
13
  ): GloomPlugin[] {
12
- return getLoadablePlugins(externalPlugins).map((plugin) => {
13
- if (plugin.id === "ticker-research") return tickerResearchBackendPlugin;
14
- return plugin;
15
- });
14
+ return getLoadablePlugins(externalPlugins).map(withoutRendererOnlyModules);
16
15
  }
17
16
 
18
17
  export interface DesktopBackendPlugins {
@@ -22,9 +21,17 @@ export interface DesktopBackendPlugins {
22
21
  * that fails to register is marked failed rather than failing the launch.
23
22
  */
24
23
  externalPlugins: LoadedExternalPlugin[];
24
+ /**
25
+ * Each pane type's plugin, renderer-only modules included, so the windows
26
+ * of a switched-off plugin's popped-out panes can be hidden with it.
27
+ */
28
+ paneOwners: ReadonlyMap<string, string>;
25
29
  }
26
30
 
27
31
  export async function loadDesktopBackendPlugins(): Promise<DesktopBackendPlugins> {
28
32
  const externalPlugins = await loadExternalPlugins("desktop");
29
- return { plugins: getDesktopBackendPlugins(externalPlugins), externalPlugins };
33
+ const paneOwners = new Map(getLoadablePlugins(externalPlugins).flatMap((plugin) => (
34
+ (plugin.panes ?? []).map((pane) => [pane.id, plugin.id] as const)
35
+ )));
36
+ return { plugins: getDesktopBackendPlugins(externalPlugins), externalPlugins, paneOwners };
30
37
  }
@@ -12,6 +12,7 @@ import { debtMaturitiesModule } from "./builtin/debt-maturities";
12
12
  import { revenueBreakdownModule } from "./builtin/revenue-breakdown";
13
13
  import { mnaModule } from "./builtin/mna";
14
14
  import { cryptoBoardModule } from "./builtin/crypto-board";
15
+ import { shortInterestModule } from "./builtin/short-interest";
15
16
  import { shortVolumeModule } from "./builtin/short-volume";
16
17
  import { socialMentionsModule } from "./builtin/social-mentions";
17
18
  import { timeSalesModule } from "./builtin/time-sales";
@@ -93,11 +94,21 @@ import { moneyMarketsModule } from "./builtin/money-markets";
93
94
  import { ratePathModule } from "./builtin/rate-path";
94
95
  import {
95
96
  applicationPluginMeta,
96
- macroPluginMeta,
97
- marketOverviewPluginMeta,
97
+ creditPluginMeta,
98
+ earningsPluginMeta,
99
+ filingsPluginMeta,
100
+ optionsVolatilityPluginMeta,
101
+ ownershipPluginMeta,
102
+ ratesMacroPluginMeta,
103
+ tickerCorePluginMeta,
104
+ altDataPluginMeta,
105
+ cryptoPluginMeta,
106
+ futuresCommoditiesPluginMeta,
107
+ globalMarketsPluginMeta,
108
+ quantPluginMeta,
109
+ screenersPluginMeta,
98
110
  newsPluginMeta,
99
111
  portfolioPluginMeta,
100
- tickerResearchPluginMeta,
101
112
  } from "./builtin/builtin-plugin-meta";
102
113
 
103
114
  const browserApplicationPlugin = composeBuiltinPlugin({
@@ -110,84 +121,107 @@ const browserPortfolioPlugin = composeBuiltinPlugin({
110
121
  modules: [portfolioListModule, portfolioAnalyticsModule, positionSizerModule],
111
122
  });
112
123
 
113
- const browserTickerResearchPlugin = composeBuiltinPlugin({
114
- ...tickerResearchPluginMeta,
124
+ // Ticker Research's successors with the modules it had on the web. Holders,
125
+ // 13F funds and the Congress tab are terminal-only, so Ownership & Insiders
126
+ // is smaller here.
127
+ const browserTickerCorePlugin = composeBuiltinPlugin({
128
+ ...tickerCorePluginMeta,
115
129
  modules: [
116
130
  tickerDetailModule,
117
131
  chartComposerModule,
132
+ researchModule,
133
+ estimateRevisionsModule,
134
+ companyKpisModule,
135
+ revenueBreakdownModule,
136
+ browserDividendYieldModule,
137
+ reverseDcfModule,
138
+ peBandModule,
139
+ executivesModule,
140
+ timeSalesModule,
141
+ ],
142
+ });
143
+
144
+ const browserOptionsVolatilityPlugin = composeBuiltinPlugin({
145
+ ...optionsVolatilityPluginMeta,
146
+ modules: [
118
147
  optionsModule,
119
148
  optionsPositioningModule,
120
149
  optionsCalculatorModule,
121
150
  optionsScenarioModule,
122
151
  volSurfaceModule,
123
152
  realizedVolModule,
124
- seasonalityModule,
125
- earningsRippleModule,
126
- reverseDcfModule,
127
- peBandModule,
128
- macroDayModule,
129
153
  ivHistoryModule,
130
- backtestModule,
131
- timeSalesModule,
132
- estimateRevisionsModule,
133
- researchModule,
134
- shortVolumeModule,
135
- socialMentionsModule,
136
- debtMaturitiesModule,
137
- revenueBreakdownModule,
138
- supplyChainModule,
139
- creditDocumentsModule,
140
- companyAttentionModule,
141
- catalystsModule,
142
- companyKpisModule,
143
- awardsModule,
144
- exposureModule,
145
- mnaModule,
146
- browserDividendYieldModule,
147
- earningsCallsModule,
148
- executivesModule,
149
- riskFactorsModule,
150
- filingEventsModule,
151
- // Filings and Form 4s come through Gloom Cloud, behind a sign-in wall.
152
- secModule,
154
+ ],
155
+ });
156
+
157
+ const browserOwnershipPlugin = composeBuiltinPlugin({
158
+ ...ownershipPluginMeta,
159
+ description: "Insider trades, and short interest and volume.",
160
+ modules: [
161
+ // Form 4s come through Gloom Cloud, behind a sign-in wall.
153
162
  insiderModule,
154
- // Hiring data is a Gloom Cloud Pro dataset.
155
- jobsModule,
163
+ // Daily volume shares open this pane.
164
+ shortInterestModule,
165
+ shortVolumeModule,
156
166
  ],
157
167
  });
158
168
 
169
+ const browserFilingsPlugin = composeBuiltinPlugin({
170
+ ...filingsPluginMeta,
171
+ // Filings come through Gloom Cloud, behind a sign-in wall.
172
+ modules: [secModule, riskFactorsModule, filingEventsModule, catalystsModule, mnaModule],
173
+ });
174
+
159
175
  const browserNewsPlugin = composeBuiltinPlugin({
160
176
  ...newsPluginMeta,
161
177
  modules: [tickerNewsModule, browserNewsWireModule],
162
178
  });
163
179
 
164
- const browserMarketOverviewPlugin = composeBuiltinPlugin({
165
- ...marketOverviewPluginMeta,
166
- description: "Global indices, scanners, sectors, FX, futures, and correlations.",
180
+ // Market Overview's successors with the modules it had on the web: all of
181
+ // them but top movers.
182
+ const browserGlobalMarketsPlugin = composeBuiltinPlugin({
183
+ ...globalMarketsPluginMeta,
184
+ modules: [worldIndicesModule, worldVenueMapModule, sectorsModule, fxMatrixModule, relativeRotationModule],
185
+ });
186
+
187
+ const browserScreenersPlugin = composeBuiltinPlugin({
188
+ ...screenersPluginMeta,
189
+ description: "Equity screener, session highs and lows, and unusual options flow.",
190
+ modules: [equityScreenerModule, scannerModule],
191
+ });
192
+
193
+ const browserFuturesCommoditiesPlugin = composeBuiltinPlugin({
194
+ ...futuresCommoditiesPluginMeta,
195
+ modules: [futuresModule, futuresCurveModule, cotModule, doeModule],
196
+ });
197
+
198
+ const browserCryptoPlugin = composeBuiltinPlugin({
199
+ ...cryptoPluginMeta,
200
+ modules: [cryptoBoardModule, perpsModule],
201
+ });
202
+
203
+ const browserAltDataPlugin = composeBuiltinPlugin({
204
+ ...altDataPluginMeta,
167
205
  modules: [
168
- correlationModule,
169
- relativeRotationModule,
170
- equityScreenerModule,
171
- worldIndicesModule,
172
- worldVenueMapModule,
173
- scannerModule,
174
- sectorsModule,
175
- fxMatrixModule,
176
- futuresModule,
177
- futuresCurveModule,
178
- cotModule,
179
- doeModule,
180
- gpuModule,
181
- attentionModule,
182
- powerModule,
183
- cryptoBoardModule,
184
- perpsModule,
206
+ ...[attentionModule, gpuModule, powerModule].map((module) => ({ module, stateId: "market-overview" })),
207
+ supplyChainModule,
208
+ exposureModule,
209
+ awardsModule,
210
+ companyAttentionModule,
211
+ // Hiring data is a Gloom Cloud Pro dataset.
212
+ jobsModule,
213
+ socialMentionsModule,
185
214
  ],
186
215
  });
187
216
 
188
- const browserMacroPlugin = composeBuiltinPlugin({
189
- ...macroPluginMeta,
190
- description: "Economic calendar, rates, volatility, credit spreads, single-name, index and sovereign CDS, and Treasury auctions.",
217
+ const browserQuantPlugin = composeBuiltinPlugin({
218
+ ...quantPluginMeta,
219
+ modules: [{ module: correlationModule, stateId: "market-overview" }, backtestModule, seasonalityModule, macroDayModule],
220
+ });
221
+
222
+ // The same panes as on the terminal.
223
+ const browserRatesMacroPlugin = composeBuiltinPlugin({
224
+ ...ratesMacroPluginMeta,
191
225
  modules: [
192
226
  macroSharedResourcesModule,
193
227
  economicCalendarModule,
@@ -196,14 +230,34 @@ const browserMacroPlugin = composeBuiltinPlugin({
196
230
  yieldCurveModule,
197
231
  ratePathModule,
198
232
  moneyMarketsModule,
199
- bondCalculatorModule,
200
233
  centralBankRatesModule,
201
234
  volatilityModule,
202
- creditConditionsModule,
203
235
  marketValuationModule,
236
+ ],
237
+ });
238
+
239
+ const browserCreditPlugin = composeBuiltinPlugin({
240
+ ...creditPluginMeta,
241
+ modules: [
204
242
  cdsModule,
205
243
  creditBoardsModule,
244
+ creditConditionsModule,
206
245
  treasuryAuctionsModule,
246
+ bondCalculatorModule,
247
+ { module: creditDocumentsModule, stateId: "ticker-research" },
248
+ { module: debtMaturitiesModule, stateId: "ticker-research" },
249
+ ],
250
+ });
251
+
252
+ // The web app has never carried the earnings calendar. The call transcripts
253
+ // and the ripple ran with Ticker Research here, so their pane state is under
254
+ // its namespace, not Macro's as on the terminal.
255
+ const browserEarningsPlugin = composeBuiltinPlugin({
256
+ ...earningsPluginMeta,
257
+ description: "Earnings call transcripts, and the earnings ripple through customers and suppliers.",
258
+ modules: [
259
+ { module: earningsCallsModule, stateId: "ticker-research" },
260
+ { module: earningsRippleModule, stateId: "ticker-research" },
207
261
  ],
208
262
  });
209
263
 
@@ -215,10 +269,18 @@ const browserMacroPlugin = composeBuiltinPlugin({
215
269
  export const browserBuiltinPlugins: readonly GloomPlugin[] = [
216
270
  browserGloomberbCloudPlugin,
217
271
  browserPortfolioPlugin,
218
- browserTickerResearchPlugin,
272
+ browserTickerCorePlugin,
273
+ browserOptionsVolatilityPlugin,
274
+ browserOwnershipPlugin,
275
+ browserFilingsPlugin,
219
276
  browserApplicationPlugin,
220
277
  browserNewsPlugin,
221
- browserMarketOverviewPlugin,
278
+ browserGlobalMarketsPlugin,
279
+ browserScreenersPlugin,
280
+ browserFuturesCommoditiesPlugin,
281
+ browserCryptoPlugin,
282
+ browserAltDataPlugin,
283
+ browserQuantPlugin,
222
284
  marketHeatmapPlugin,
223
285
  marketHaltsPlugin,
224
286
  fearGreedPlugin,
@@ -227,7 +289,9 @@ export const browserBuiltinPlugins: readonly GloomPlugin[] = [
227
289
  clinicalTrialsPlugin,
228
290
  commentLettersPlugin,
229
291
  openFdaPlugin,
230
- browserMacroPlugin,
292
+ browserRatesMacroPlugin,
293
+ browserCreditPlugin,
294
+ browserEarningsPlugin,
231
295
  alertsPlugin,
232
296
  researchSearchPlugin,
233
297
  ];