gloomberb 0.15.7 → 0.16.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (524) hide show
  1. package/README.md +11 -2
  2. package/package.json +1 -1
  3. package/src/api-client/app-attention.ts +147 -0
  4. package/src/api-client/attention.ts +26 -0
  5. package/src/api-client/awards.ts +215 -0
  6. package/src/api-client/catalysts.ts +160 -0
  7. package/src/api-client/chat.ts +137 -14
  8. package/src/api-client/company-kpis.ts +153 -0
  9. package/src/api-client/cpi.ts +52 -0
  10. package/src/api-client/credit-documents.ts +107 -0
  11. package/src/api-client/data.ts +192 -3
  12. package/src/api-client/distress.ts +164 -0
  13. package/src/api-client/doe.ts +75 -0
  14. package/src/api-client/equity-screener.ts +11 -0
  15. package/src/api-client/exposure.ts +202 -0
  16. package/src/api-client/gpu.ts +93 -0
  17. package/src/api-client/hiring.ts +110 -0
  18. package/src/api-client/index.ts +78 -3
  19. package/src/api-client/normalizers.ts +31 -1
  20. package/src/api-client/paths.ts +3 -0
  21. package/src/api-client/perps.ts +127 -0
  22. package/src/api-client/power.ts +148 -0
  23. package/src/api-client/request.ts +58 -1
  24. package/src/api-client/research-activity.ts +172 -13
  25. package/src/api-client/socket.ts +75 -27
  26. package/src/api-client/supply-chain-graph.ts +40 -0
  27. package/src/api-client/supply-chain.ts +98 -0
  28. package/src/api-client/telemetry.ts +29 -0
  29. package/src/api-client/themes.ts +28 -0
  30. package/src/api-client/types.ts +33 -1
  31. package/src/api-client/wall-experiments.ts +100 -0
  32. package/src/api-client/wall-summary.ts +49 -0
  33. package/src/api-client/web-experiments.ts +136 -0
  34. package/src/app/pane-runtime/plugin-bindings.ts +5 -0
  35. package/src/app/pane-runtime/ticker-open-runtime.ts +8 -2
  36. package/src/app/runtime/update.ts +13 -1
  37. package/src/cli/commands/system.ts +2 -0
  38. package/src/cli/desktop-pane-shot.ts +3 -4
  39. package/src/cli/pane-functions/data.ts +78 -0
  40. package/src/cli/pane-functions/financial-ratio-shot.ts +160 -0
  41. package/src/cli/pane-functions/function-help.ts +220 -8
  42. package/src/cli/pane-functions/headless.ts +4 -0
  43. package/src/cli/pane-functions/screenshot-evidence.ts +21 -0
  44. package/src/cli/pane-functions/screenshot.ts +49 -5
  45. package/src/components/chart/composite/composite-chart.tsx +15 -2
  46. package/src/components/chart/composite/format.ts +24 -11
  47. package/src/components/chart/composite/rasterizer.ts +67 -16
  48. package/src/components/chart/composite/scene.ts +53 -2
  49. package/src/components/chart/composite/session-shading.ts +3 -2
  50. package/src/components/chart/composite/text-renderer.ts +52 -1
  51. package/src/components/chart/composite/time-axis.ts +100 -30
  52. package/src/components/chart/composite/tools.ts +2 -1
  53. package/src/components/chart/composite/types.ts +4 -0
  54. package/src/components/chart-table/index.ts +1 -0
  55. package/src/components/chart-table/layout.ts +15 -0
  56. package/src/components/command-bar/action-runtime.ts +1 -0
  57. package/src/components/command-bar/commands/direct/index.ts +32 -0
  58. package/src/components/command-bar/commands/registry.ts +7 -0
  59. package/src/components/command-bar/pane-templates/items.ts +11 -0
  60. package/src/components/command-bar/pane-templates/workflow.ts +19 -4
  61. package/src/components/command-bar/routes/root/command-items.ts +6 -0
  62. package/src/components/command-bar/routes/root/provider-search.ts +2 -0
  63. package/src/components/command-bar/routes/root/results.ts +64 -0
  64. package/src/components/command-bar/routes/root/runtime.ts +8 -0
  65. package/src/components/command-bar/routes/ticker-search/results.ts +89 -24
  66. package/src/components/command-bar/routes/ticker-search/route.ts +2 -0
  67. package/src/components/command-bar/surface/index.tsx +15 -0
  68. package/src/components/command-bar/view-model.ts +3 -0
  69. package/src/components/command-bar/workflow/collection-actions.ts +9 -7
  70. package/src/components/command-bar/workflow/ops.ts +19 -0
  71. package/src/components/command-bar/workflow/tickers.ts +5 -0
  72. package/src/components/company-logo.tsx +15 -2
  73. package/src/components/data-table/table-pane.ts +2 -1
  74. package/src/components/index.ts +1 -0
  75. package/src/components/layout/detached-pane-shell.tsx +12 -1
  76. package/src/components/layout/missing-pane.tsx +87 -23
  77. package/src/components/layout/pane/footer/index.tsx +64 -18
  78. package/src/components/layout/pane/footer/model.ts +85 -0
  79. package/src/components/layout/pane/sidebar.tsx +19 -1
  80. package/src/components/layout/shell/index.tsx +38 -28
  81. package/src/components/layout/shell/pane/management-shortcuts.ts +13 -1
  82. package/src/components/layout/status-bar.tsx +93 -28
  83. package/src/components/layout/status-widget-space.ts +72 -0
  84. package/src/components/onboarding/first-run-workspace.ts +8 -2
  85. package/src/components/onboarding/onboarding-wizard.tsx +35 -16
  86. package/src/components/onboarding/portfolio-step/positions-panel.tsx +14 -5
  87. package/src/components/onboarding/wizard-model.ts +13 -5
  88. package/src/components/onboarding/wizard-positions.ts +56 -7
  89. package/src/components/price-performance.tsx +31 -34
  90. package/src/components/ui/data-table/index.tsx +11 -8
  91. package/src/components/ui/display.tsx +15 -6
  92. package/src/components/ui/fields.tsx +5 -0
  93. package/src/components/ui/figure.tsx +94 -0
  94. package/src/components/ui/header-case.ts +25 -3
  95. package/src/components/ui/icon.tsx +3 -1
  96. package/src/components/ui/message-composer.tsx +8 -1
  97. package/src/components/ui/query-bar.tsx +8 -1
  98. package/src/components/ui/ratio-bar.tsx +84 -0
  99. package/src/components/ui/toggle.tsx +3 -1
  100. package/src/components/use-scrollbox-layout.ts +17 -0
  101. package/src/core/state/app/layout.ts +35 -1
  102. package/src/core/state/app/state.ts +15 -0
  103. package/src/core/state/app/types.ts +1 -0
  104. package/src/data/config/store/normalize.ts +24 -0
  105. package/src/i18n/es.ts +2 -0
  106. package/src/i18n/ja.ts +2 -0
  107. package/src/i18n/ko.ts +2 -0
  108. package/src/i18n/zh-cn.ts +2 -0
  109. package/src/i18n/zh-tw.ts +2 -0
  110. package/src/layout-marketplace/pane-imagery.ts +1 -0
  111. package/src/market-data/coordinator/entries.ts +13 -0
  112. package/src/market-data/coordinator/financials.ts +33 -8
  113. package/src/market-data/market/freshness.ts +16 -5
  114. package/src/market-data/market/trading-sessions.ts +65 -1
  115. package/src/market-data/published-cn-sessions.ts +25 -0
  116. package/src/market-data/published-nse-sessions.ts +20 -0
  117. package/src/news/aggregator.ts +4 -0
  118. package/src/plugins/builtin/account-management/model.ts +6 -1
  119. package/src/plugins/builtin/account-management/pane.tsx +36 -25
  120. package/src/plugins/builtin/alerts/catalysts.ts +77 -0
  121. package/src/plugins/builtin/alerts/events-pane.tsx +3 -0
  122. package/src/plugins/builtin/alerts/events.ts +10 -4
  123. package/src/plugins/builtin/alerts/history-pane.tsx +1 -1
  124. package/src/plugins/builtin/alerts/history.ts +1 -0
  125. package/src/plugins/builtin/alerts/index.tsx +6 -0
  126. package/src/plugins/builtin/alerts/research-builder.ts +10 -3
  127. package/src/plugins/builtin/alerts/research-rules.ts +15 -1
  128. package/src/plugins/builtin/analytics/risk-client.ts +15 -3
  129. package/src/plugins/builtin/analytics/risk-headless.ts +123 -18
  130. package/src/plugins/builtin/attention/client.ts +80 -0
  131. package/src/plugins/builtin/attention/evidence.ts +30 -0
  132. package/src/plugins/builtin/attention/headless.ts +33 -0
  133. package/src/plugins/builtin/attention/index.tsx +18 -0
  134. package/src/plugins/builtin/attention/model.ts +59 -0
  135. package/src/plugins/builtin/attention/pane.tsx +211 -0
  136. package/src/plugins/builtin/attention/trending.tsx +59 -0
  137. package/src/plugins/builtin/awards/alerts.ts +32 -0
  138. package/src/plugins/builtin/awards/client.ts +82 -0
  139. package/src/plugins/builtin/awards/detail.tsx +107 -0
  140. package/src/plugins/builtin/awards/evidence.ts +36 -0
  141. package/src/plugins/builtin/awards/headless.ts +55 -0
  142. package/src/plugins/builtin/awards/index.tsx +20 -0
  143. package/src/plugins/builtin/awards/model.ts +42 -0
  144. package/src/plugins/builtin/awards/pane.tsx +263 -0
  145. package/src/plugins/builtin/catalysts/client.ts +28 -0
  146. package/src/plugins/builtin/catalysts/detail.tsx +88 -0
  147. package/src/plugins/builtin/catalysts/evidence.ts +47 -0
  148. package/src/plugins/builtin/catalysts/headless.ts +42 -0
  149. package/src/plugins/builtin/catalysts/history.ts +26 -0
  150. package/src/plugins/builtin/catalysts/index.tsx +29 -0
  151. package/src/plugins/builtin/catalysts/model.ts +135 -0
  152. package/src/plugins/builtin/catalysts/pane.tsx +159 -0
  153. package/src/plugins/builtin/chart-composer/cli-options.ts +4 -0
  154. package/src/plugins/builtin/chart-composer/headless-schema.ts +6 -0
  155. package/src/plugins/builtin/chart-composer/index.tsx +8 -1
  156. package/src/plugins/builtin/chart-composer/pane.tsx +28 -1
  157. package/src/plugins/builtin/chat/attachments/desktop.tsx +610 -0
  158. package/src/plugins/builtin/chat/attachments/files.ts +45 -0
  159. package/src/plugins/builtin/chat/attachments/model.ts +164 -0
  160. package/src/plugins/builtin/chat/attachments/terminal.tsx +72 -0
  161. package/src/plugins/builtin/chat/attachments/transfer.ts +165 -0
  162. package/src/plugins/builtin/chat/content/channel-navigation.ts +13 -12
  163. package/src/plugins/builtin/chat/content/composer-runtime.ts +25 -4
  164. package/src/plugins/builtin/chat/content/composer.tsx +46 -4
  165. package/src/plugins/builtin/chat/content/footer.tsx +46 -8
  166. package/src/plugins/builtin/chat/content/index.tsx +263 -62
  167. package/src/plugins/builtin/chat/content/layout-metrics.ts +10 -2
  168. package/src/plugins/builtin/chat/content/open-targets.ts +17 -3
  169. package/src/plugins/builtin/chat/content/scroll.ts +7 -1
  170. package/src/plugins/builtin/chat/content/shortcuts.ts +36 -11
  171. package/src/plugins/builtin/chat/content/snapshot.ts +3 -0
  172. package/src/plugins/builtin/chat/content/transcript.tsx +17 -1
  173. package/src/plugins/builtin/chat/content/types.ts +7 -0
  174. package/src/plugins/builtin/chat/controller/attachments.ts +213 -0
  175. package/src/plugins/builtin/chat/controller/connections.ts +3 -1
  176. package/src/plugins/builtin/chat/controller/index.ts +114 -2
  177. package/src/plugins/builtin/chat/controller/lifecycle.ts +9 -0
  178. package/src/plugins/builtin/chat/controller/messages.ts +35 -2
  179. package/src/plugins/builtin/chat/controller/send.ts +128 -25
  180. package/src/plugins/builtin/chat/controller/state.ts +12 -1
  181. package/src/plugins/builtin/chat/controller/utils.ts +7 -5
  182. package/src/plugins/builtin/chat/controller/view.ts +2 -0
  183. package/src/plugins/builtin/chat/index.tsx +21 -0
  184. package/src/plugins/builtin/chat/layout.ts +9 -4
  185. package/src/plugins/builtin/chat/message/desktop.tsx +55 -20
  186. package/src/plugins/builtin/chat/message/header.tsx +30 -5
  187. package/src/plugins/builtin/chat/message/inline-tokens.tsx +9 -0
  188. package/src/plugins/builtin/chat/message/pending-send.ts +35 -0
  189. package/src/plugins/builtin/chat/message/profile-popover.tsx +5 -1
  190. package/src/plugins/builtin/chat/message/render-state.ts +12 -2
  191. package/src/plugins/builtin/chat/message/terminal.tsx +51 -4
  192. package/src/plugins/builtin/chat/message/types.ts +6 -1
  193. package/src/plugins/builtin/chat/pane-state.ts +59 -1
  194. package/src/plugins/builtin/chat/profile-popover.ts +50 -1
  195. package/src/plugins/builtin/chat/sidebar.tsx +8 -3
  196. package/src/plugins/builtin/chat/status-widget.tsx +29 -12
  197. package/src/plugins/builtin/chat/unread-inbox-pane.tsx +143 -0
  198. package/src/plugins/builtin/chat/unread-inbox.ts +91 -0
  199. package/src/plugins/builtin/clinical-trials/client.ts +237 -0
  200. package/src/plugins/builtin/clinical-trials/index.tsx +74 -0
  201. package/src/plugins/builtin/clinical-trials/pane.tsx +225 -0
  202. package/src/plugins/builtin/clinical-trials/types.ts +2 -0
  203. package/src/plugins/builtin/cloud/askg/controller.ts +37 -6
  204. package/src/plugins/builtin/cloud/askg/executor.ts +59 -44
  205. package/src/plugins/builtin/cloud/askg/host.ts +8 -1
  206. package/src/plugins/builtin/cloud/askg/manifest.ts +29 -2
  207. package/src/plugins/builtin/cloud/askg/model.ts +47 -13
  208. package/src/plugins/builtin/cloud/askg/notes.ts +100 -0
  209. package/src/plugins/builtin/cloud/askg/pane.tsx +50 -14
  210. package/src/plugins/builtin/cloud/askg/protocol.ts +39 -1
  211. package/src/plugins/builtin/cloud/askg/result-budget.ts +156 -0
  212. package/src/plugins/builtin/cloud/askg/user-data.ts +89 -0
  213. package/src/plugins/builtin/cloud/auth-actions.tsx +55 -31
  214. package/src/plugins/builtin/cloud/plugin.tsx +4 -1
  215. package/src/plugins/builtin/cloud/team/pane-sections.tsx +10 -1
  216. package/src/plugins/builtin/cloud/team/pane.tsx +3 -2
  217. package/src/plugins/builtin/cloud/thesis/board-pane.tsx +2 -2
  218. package/src/plugins/builtin/cloud/thesis/detail.tsx +1 -1
  219. package/src/plugins/builtin/cloud/thesis/ticker-tab.tsx +2 -2
  220. package/src/plugins/builtin/cloud/trial-offer-status-widget.tsx +202 -0
  221. package/src/plugins/builtin/cloud/upgrade-command.ts +1 -1
  222. package/src/plugins/builtin/cloud/upgrade-dialog.tsx +29 -3
  223. package/src/plugins/builtin/cloud/upgrade-status-widget.tsx +1 -1
  224. package/src/plugins/builtin/cloud-tweets/table.tsx +1 -1
  225. package/src/plugins/builtin/comment-letters/client.ts +342 -0
  226. package/src/plugins/builtin/comment-letters/index.tsx +74 -0
  227. package/src/plugins/builtin/comment-letters/pane.tsx +295 -0
  228. package/src/plugins/builtin/comment-letters/types.ts +43 -0
  229. package/src/plugins/builtin/company-attention/app-rank.tsx +79 -0
  230. package/src/plugins/builtin/company-attention/client.ts +69 -0
  231. package/src/plugins/builtin/company-attention/evidence.ts +45 -0
  232. package/src/plugins/builtin/company-attention/headless.ts +47 -0
  233. package/src/plugins/builtin/company-attention/index.tsx +30 -0
  234. package/src/plugins/builtin/company-attention/model.ts +129 -0
  235. package/src/plugins/builtin/company-attention/pane.tsx +183 -0
  236. package/src/plugins/builtin/company-kpis/client.ts +92 -0
  237. package/src/plugins/builtin/company-kpis/headless.ts +32 -0
  238. package/src/plugins/builtin/company-kpis/index.tsx +26 -0
  239. package/src/plugins/builtin/company-kpis/model.ts +124 -0
  240. package/src/plugins/builtin/company-kpis/pane.tsx +226 -0
  241. package/src/plugins/builtin/company-kpis/related.ts +11 -0
  242. package/src/plugins/builtin/company-kpis/screenshot-evidence.ts +44 -0
  243. package/src/plugins/builtin/composite-plugins.ts +34 -0
  244. package/src/plugins/builtin/correlation/history.ts +4 -1
  245. package/src/plugins/builtin/correlation/index.tsx +139 -80
  246. package/src/plugins/builtin/correlation/matrix/pair-chart.tsx +48 -0
  247. package/src/plugins/builtin/correlation/matrix/selection.ts +77 -0
  248. package/src/plugins/builtin/correlation/relationship/model.ts +2 -2
  249. package/src/plugins/builtin/cpi/client.ts +66 -0
  250. package/src/plugins/builtin/cpi/headless.ts +78 -0
  251. package/src/plugins/builtin/cpi/index.tsx +31 -0
  252. package/src/plugins/builtin/cpi/model.ts +198 -0
  253. package/src/plugins/builtin/cpi/pane.tsx +157 -0
  254. package/src/plugins/builtin/credit-documents/client.ts +99 -0
  255. package/src/plugins/builtin/credit-documents/detail.tsx +109 -0
  256. package/src/plugins/builtin/credit-documents/evidence.ts +64 -0
  257. package/src/plugins/builtin/credit-documents/gauge.tsx +55 -0
  258. package/src/plugins/builtin/credit-documents/headless.ts +40 -0
  259. package/src/plugins/builtin/credit-documents/index.tsx +19 -0
  260. package/src/plugins/builtin/credit-documents/model.ts +336 -0
  261. package/src/plugins/builtin/credit-documents/pane.tsx +185 -0
  262. package/src/plugins/builtin/custom-view/view-spec.ts +14 -2
  263. package/src/plugins/builtin/debt-maturities/pane.tsx +1 -0
  264. package/src/plugins/builtin/dividend-yield/pane.tsx +1 -1
  265. package/src/plugins/builtin/doe/client.ts +73 -0
  266. package/src/plugins/builtin/doe/headless.ts +93 -0
  267. package/src/plugins/builtin/doe/index.tsx +41 -0
  268. package/src/plugins/builtin/doe/model.ts +215 -0
  269. package/src/plugins/builtin/doe/pane.tsx +148 -0
  270. package/src/plugins/builtin/doe/range-bar.tsx +45 -0
  271. package/src/plugins/builtin/earnings/board.tsx +3 -0
  272. package/src/plugins/builtin/earnings/index.tsx +2 -0
  273. package/src/plugins/builtin/earnings-calls/pane.tsx +7 -1
  274. package/src/plugins/builtin/earnings-calls/transcript-view.tsx +7 -7
  275. package/src/plugins/builtin/earnings-ripple/client.ts +60 -0
  276. package/src/plugins/builtin/earnings-ripple/headless.ts +35 -0
  277. package/src/plugins/builtin/earnings-ripple/index.tsx +35 -0
  278. package/src/plugins/builtin/earnings-ripple/model.ts +98 -0
  279. package/src/plugins/builtin/earnings-ripple/pane.tsx +103 -0
  280. package/src/plugins/builtin/equity-screener/client.ts +1 -1
  281. package/src/plugins/builtin/equity-screener/criterion-editor.tsx +1 -1
  282. package/src/plugins/builtin/equity-screener/model.ts +74 -9
  283. package/src/plugins/builtin/equity-screener/pane.tsx +2 -0
  284. package/src/plugins/builtin/estimate-revisions/pane.tsx +3 -0
  285. package/src/plugins/builtin/executives/pane.tsx +7 -5
  286. package/src/plugins/builtin/exposure/charts.tsx +66 -0
  287. package/src/plugins/builtin/exposure/client.ts +53 -0
  288. package/src/plugins/builtin/exposure/drivers.ts +29 -0
  289. package/src/plugins/builtin/exposure/editor.tsx +61 -0
  290. package/src/plugins/builtin/exposure/evidence.ts +39 -0
  291. package/src/plugins/builtin/exposure/headless.ts +51 -0
  292. package/src/plugins/builtin/exposure/holdings.ts +56 -0
  293. package/src/plugins/builtin/exposure/index.tsx +13 -0
  294. package/src/plugins/builtin/exposure/model.ts +104 -0
  295. package/src/plugins/builtin/exposure/pane.tsx +247 -0
  296. package/src/plugins/builtin/fear-greed/charts.tsx +1 -1
  297. package/src/plugins/builtin/fear-greed/pane.tsx +2 -9
  298. package/src/plugins/builtin/filing-events/pane.tsx +2 -1
  299. package/src/plugins/builtin/gpu/board.tsx +163 -0
  300. package/src/plugins/builtin/gpu/changes.tsx +94 -0
  301. package/src/plugins/builtin/gpu/client.ts +130 -0
  302. package/src/plugins/builtin/gpu/equities.tsx +112 -0
  303. package/src/plugins/builtin/gpu/headless.ts +67 -0
  304. package/src/plugins/builtin/gpu/history.tsx +140 -0
  305. package/src/plugins/builtin/gpu/index.tsx +18 -0
  306. package/src/plugins/builtin/gpu/ladder.tsx +127 -0
  307. package/src/plugins/builtin/gpu/model.ts +317 -0
  308. package/src/plugins/builtin/gpu/pane.tsx +63 -0
  309. package/src/plugins/builtin/help/index.tsx +19 -2
  310. package/src/plugins/builtin/holders/pane.tsx +5 -9
  311. package/src/plugins/builtin/insider/detail.tsx +119 -0
  312. package/src/plugins/builtin/insider/display.ts +221 -0
  313. package/src/plugins/builtin/insider/headless.ts +24 -3
  314. package/src/plugins/builtin/insider/index.tsx +206 -108
  315. package/src/plugins/builtin/insider/insider-data.ts +31 -3
  316. package/src/plugins/builtin/insider/model.ts +53 -4
  317. package/src/plugins/builtin/insider/table-model.ts +226 -0
  318. package/src/plugins/builtin/insider/table.tsx +79 -0
  319. package/src/plugins/builtin/iv-history/screen-pane.tsx +1 -1
  320. package/src/plugins/builtin/jobs/pane.tsx +14 -7
  321. package/src/plugins/builtin/kelly-sizer/pane.tsx +1 -1
  322. package/src/plugins/builtin/macro-day/client.ts +50 -0
  323. package/src/plugins/builtin/macro-day/headless.ts +51 -0
  324. package/src/plugins/builtin/macro-day/index.tsx +21 -0
  325. package/src/plugins/builtin/macro-day/model.ts +137 -0
  326. package/src/plugins/builtin/macro-day/pane.tsx +118 -0
  327. package/src/plugins/builtin/macro-day/releases.ts +58 -0
  328. package/src/plugins/builtin/market-halts/model.ts +30 -17
  329. package/src/plugins/builtin/market-halts/pane.tsx +15 -21
  330. package/src/plugins/builtin/market-heatmap/data.ts +1 -1
  331. package/src/plugins/builtin/market-heatmap/index.tsx +198 -50
  332. package/src/plugins/builtin/market-heatmap/portfolio.ts +220 -0
  333. package/src/plugins/builtin/market-movers/index.tsx +1 -0
  334. package/src/plugins/builtin/market-movers/session-body.tsx +5 -2
  335. package/src/plugins/builtin/mna/distress/client.ts +326 -0
  336. package/src/plugins/builtin/mna/distress/detail.tsx +247 -0
  337. package/src/plugins/builtin/mna/distress/headless.ts +257 -0
  338. package/src/plugins/builtin/mna/distress/model.ts +427 -0
  339. package/src/plugins/builtin/mna/distress/pane.tsx +606 -0
  340. package/src/plugins/builtin/mna/index.tsx +15 -0
  341. package/src/plugins/builtin/mna/pane.tsx +42 -1
  342. package/src/plugins/builtin/news/index.tsx +62 -16
  343. package/src/plugins/builtin/news/wire/filter-articles.ts +54 -0
  344. package/src/plugins/builtin/news/wire/index.tsx +37 -3
  345. package/src/plugins/builtin/news/wire/industry-pane.tsx +29 -13
  346. package/src/plugins/builtin/news/wire/mutes.ts +253 -0
  347. package/src/plugins/builtin/news/wire/news/command-bar-search.ts +117 -0
  348. package/src/plugins/builtin/news/wire/news/footer.ts +4 -0
  349. package/src/plugins/builtin/news/wire/news/list-search.ts +34 -0
  350. package/src/plugins/builtin/news/wire/news/pop-out.tsx +158 -0
  351. package/src/plugins/builtin/news/wire/news/preset-pane.tsx +64 -19
  352. package/src/plugins/builtin/openfda/client.ts +300 -0
  353. package/src/plugins/builtin/openfda/index.tsx +71 -0
  354. package/src/plugins/builtin/openfda/pane.tsx +382 -0
  355. package/src/plugins/builtin/openfda/types.ts +76 -0
  356. package/src/plugins/builtin/options/footer.ts +1 -0
  357. package/src/plugins/builtin/options/view.tsx +1 -1
  358. package/src/plugins/builtin/options-calculator/pane.tsx +0 -1
  359. package/src/plugins/builtin/options-positioning/index.tsx +4 -2
  360. package/src/plugins/builtin/options-positioning/pane.tsx +1 -1
  361. package/src/plugins/builtin/pe-band/client.ts +61 -0
  362. package/src/plugins/builtin/pe-band/headless.ts +51 -0
  363. package/src/plugins/builtin/pe-band/index.tsx +20 -0
  364. package/src/plugins/builtin/pe-band/model.ts +267 -0
  365. package/src/plugins/builtin/pe-band/pane.tsx +159 -0
  366. package/src/plugins/builtin/perps/client.ts +66 -0
  367. package/src/plugins/builtin/perps/equity-row.tsx +28 -0
  368. package/src/plugins/builtin/perps/headless.ts +34 -0
  369. package/src/plugins/builtin/perps/index.tsx +14 -0
  370. package/src/plugins/builtin/perps/model.ts +58 -0
  371. package/src/plugins/builtin/perps/pane.tsx +185 -0
  372. package/src/plugins/builtin/plugin-marketplace/pane.tsx +0 -1
  373. package/src/plugins/builtin/portfolio-list/cli/render.ts +177 -87
  374. package/src/plugins/builtin/portfolio-list/cli/watchlist-command.ts +6 -20
  375. package/src/plugins/builtin/portfolio-list/command-bar.ts +6 -2
  376. package/src/plugins/builtin/portfolio-list/headless.ts +237 -0
  377. package/src/plugins/builtin/portfolio-list/index.tsx +2 -0
  378. package/src/plugins/builtin/portfolio-list/mutations.ts +70 -1
  379. package/src/plugins/builtin/portfolio-list/pane/data.ts +17 -0
  380. package/src/plugins/builtin/portfolio-list/pane/index.tsx +88 -5
  381. package/src/plugins/builtin/portfolio-list/pane/remove-ticker.ts +85 -0
  382. package/src/plugins/builtin/portfolio-list/pane/streaming.ts +18 -12
  383. package/src/plugins/builtin/portfolio-list/quick-add/index.tsx +6 -0
  384. package/src/plugins/builtin/power/client.ts +100 -0
  385. package/src/plugins/builtin/power/detail.tsx +82 -0
  386. package/src/plugins/builtin/power/evidence.ts +56 -0
  387. package/src/plugins/builtin/power/generation.tsx +37 -0
  388. package/src/plugins/builtin/power/headless.ts +43 -0
  389. package/src/plugins/builtin/power/index.tsx +16 -0
  390. package/src/plugins/builtin/power/model.ts +89 -0
  391. package/src/plugins/builtin/power/pane.tsx +209 -0
  392. package/src/plugins/builtin/power/query.ts +25 -0
  393. package/src/plugins/builtin/relative-rotation/pane.tsx +3 -3
  394. package/src/plugins/builtin/research/analyst-pane.tsx +1 -1
  395. package/src/plugins/builtin/research/corporate-actions-pane.tsx +13 -4
  396. package/src/plugins/builtin/research/equity-diagnostic-pane.tsx +11 -9
  397. package/src/plugins/builtin/research-search/pane.tsx +21 -7
  398. package/src/plugins/builtin/revenue-breakdown/pane.tsx +1 -1
  399. package/src/plugins/builtin/reverse-dcf/client.ts +35 -0
  400. package/src/plugins/builtin/reverse-dcf/headless.ts +44 -0
  401. package/src/plugins/builtin/reverse-dcf/index.tsx +20 -0
  402. package/src/plugins/builtin/reverse-dcf/model.ts +87 -0
  403. package/src/plugins/builtin/reverse-dcf/pane.tsx +107 -0
  404. package/src/plugins/builtin/risk-factors/pane.tsx +6 -5
  405. package/src/plugins/builtin/scanner/denied.tsx +4 -2
  406. package/src/plugins/builtin/scanner/feed.ts +1 -0
  407. package/src/plugins/builtin/scanner/flow-pane.tsx +3 -2
  408. package/src/plugins/builtin/scanner/hilo-pane.tsx +1 -1
  409. package/src/plugins/builtin/seasonality/client.ts +4 -1
  410. package/src/plugins/builtin/sec/command-bar-search.ts +217 -0
  411. package/src/plugins/builtin/sec/forms.ts +54 -0
  412. package/src/plugins/builtin/sec/headless.ts +31 -5
  413. package/src/plugins/builtin/sec/index.tsx +67 -11
  414. package/src/plugins/builtin/sec/model.ts +35 -5
  415. package/src/plugins/builtin/sectors/headless.ts +1 -0
  416. package/src/plugins/builtin/sectors/index.tsx +72 -26
  417. package/src/plugins/builtin/shared/cloud-upgrade.ts +143 -39
  418. package/src/plugins/builtin/shared/pro-feature-wall.tsx +8 -4
  419. package/src/plugins/builtin/shared/research-cells.tsx +107 -0
  420. package/src/plugins/builtin/shared/series-list-detail.tsx +5 -1
  421. package/src/plugins/builtin/shared/ticker-request.ts +1 -1
  422. package/src/plugins/builtin/shared/wall-teaser-catalog.ts +80 -0
  423. package/src/plugins/builtin/shared/wall-teaser.tsx +192 -0
  424. package/src/plugins/builtin/shared/wall-view-lifecycle.ts +43 -0
  425. package/src/plugins/builtin/short-interest/index.tsx +31 -0
  426. package/src/plugins/builtin/short-interest/watch-client.ts +70 -0
  427. package/src/plugins/builtin/short-interest/watch-headless.ts +49 -0
  428. package/src/plugins/builtin/short-interest/watch-model.ts +185 -0
  429. package/src/plugins/builtin/short-interest/watch-pane.tsx +169 -0
  430. package/src/plugins/builtin/short-volume/pane.tsx +1 -1
  431. package/src/plugins/builtin/social-mentions/pane.tsx +1 -1
  432. package/src/plugins/builtin/supply-chain/client.ts +104 -0
  433. package/src/plugins/builtin/supply-chain/disclosure-quote.tsx +17 -0
  434. package/src/plugins/builtin/supply-chain/evidence.ts +88 -0
  435. package/src/plugins/builtin/supply-chain/flow-layout.ts +133 -0
  436. package/src/plugins/builtin/supply-chain/flow.tsx +323 -0
  437. package/src/plugins/builtin/supply-chain/graph-client.ts +83 -0
  438. package/src/plugins/builtin/supply-chain/graph-evidence.ts +25 -0
  439. package/src/plugins/builtin/supply-chain/graph-model.ts +45 -0
  440. package/src/plugins/builtin/supply-chain/graph-pane.tsx +218 -0
  441. package/src/plugins/builtin/supply-chain/graph.tsx +163 -0
  442. package/src/plugins/builtin/supply-chain/headless.ts +105 -0
  443. package/src/plugins/builtin/supply-chain/index.tsx +17 -0
  444. package/src/plugins/builtin/supply-chain/model.ts +145 -0
  445. package/src/plugins/builtin/supply-chain/pane.tsx +276 -0
  446. package/src/plugins/builtin/supply-chain/row-evidence.tsx +96 -0
  447. package/src/plugins/builtin/supply-chain/trust.ts +34 -0
  448. package/src/plugins/builtin/themes/client.ts +39 -0
  449. package/src/plugins/builtin/themes/headless.ts +38 -0
  450. package/src/plugins/builtin/themes/model.ts +92 -0
  451. package/src/plugins/builtin/themes/pane.tsx +125 -0
  452. package/src/plugins/builtin/thirteenf/pane.tsx +6 -15
  453. package/src/plugins/builtin/ticker-detail/data-panes/historical-prices.tsx +5 -6
  454. package/src/plugins/builtin/ticker-detail/data-panes/returns-model.ts +201 -0
  455. package/src/plugins/builtin/ticker-detail/data-panes/returns-pane.tsx +327 -0
  456. package/src/plugins/builtin/ticker-detail/financials/period-end-history.ts +5 -2
  457. package/src/plugins/builtin/ticker-detail/financials/ratios.ts +60 -12
  458. package/src/plugins/builtin/ticker-detail/financials/tab.tsx +2 -1
  459. package/src/plugins/builtin/ticker-detail/headless.ts +7 -2
  460. package/src/plugins/builtin/ticker-detail/index.tsx +22 -0
  461. package/src/plugins/builtin/ticker-detail/overview/components.tsx +53 -30
  462. package/src/plugins/builtin/ticker-detail/overview/pane.tsx +2 -0
  463. package/src/plugins/builtin/ticker-detail/overview-tab.tsx +112 -47
  464. package/src/plugins/builtin/ticker-detail/pane.tsx +50 -6
  465. package/src/plugins/builtin/ticker-detail/quote-monitor/card.tsx +21 -42
  466. package/src/plugins/builtin/ticker-detail/quote-monitor/index.tsx +3 -0
  467. package/src/plugins/builtin/time-sales/pane.tsx +1 -1
  468. package/src/plugins/builtin/world-indices/indices.ts +1 -0
  469. package/src/plugins/catalog-browser.ts +40 -0
  470. package/src/plugins/catalog-manifest.ts +3 -0
  471. package/src/plugins/catalog-ui.ts +6 -0
  472. package/src/plugins/current-target.ts +0 -9
  473. package/src/public/__snapshots__/public-api.test.ts.snap +1 -0
  474. package/src/renderers/browser/cloud-transport.ts +66 -1
  475. package/src/renderers/browser/main.tsx +2 -0
  476. package/src/renderers/dom/data-table/row.tsx +2 -0
  477. package/src/renderers/dom/desktop/controls.tsx +38 -25
  478. package/src/renderers/dom/desktop/icons.tsx +8 -0
  479. package/src/renderers/dom/host/chart-surface.tsx +36 -2
  480. package/src/renderers/dom/host/focus-scope.ts +11 -1
  481. package/src/renderers/dom/styles.css +28 -0
  482. package/src/renderers/electrobun/view/backend-rpc.ts +3 -2
  483. package/src/renderers/electrobun/view/cli-pane-shot-entry.tsx +1 -1
  484. package/src/renderers/electrobun/view/http-fetch.ts +2 -0
  485. package/src/renderers/electrobun/view/main.tsx +3 -1
  486. package/src/renderers/electrobun/view/rpc-timeout.ts +59 -0
  487. package/src/renderers/opentui/start.tsx +3 -0
  488. package/src/shares/api.ts +3 -1
  489. package/src/sources/gloomberb-cloud/index.ts +47 -13
  490. package/src/sources/history-result.ts +1 -0
  491. package/src/sources/history-retention.ts +16 -0
  492. package/src/sources/provider-router/history.ts +4 -2
  493. package/src/sources/sec-edgar/identity.ts +36 -0
  494. package/src/sources/sec-edgar.ts +1 -34
  495. package/src/state/app/context/index.tsx +8 -0
  496. package/src/sync/core-contributors.ts +20 -2
  497. package/src/telemetry/attention-counts.ts +164 -0
  498. package/src/telemetry/live-config.ts +7 -0
  499. package/src/test-support/rpc-loopback.ts +7 -3
  500. package/src/test-support/shell-pane-keys.tsx +34 -0
  501. package/src/tickers/instrument-kind.ts +12 -6
  502. package/src/tickers/open-target.ts +1 -1
  503. package/src/tickers/search/asset-classes.ts +91 -0
  504. package/src/tickers/search/index.ts +62 -15
  505. package/src/tickers/search/ranking.ts +22 -3
  506. package/src/tickers/search/upsert.ts +4 -1
  507. package/src/time-series/live-bars.ts +8 -3
  508. package/src/time-series/resolve.ts +224 -17
  509. package/src/time-series/spec.ts +1 -0
  510. package/src/time-series/types.ts +9 -1
  511. package/src/types/config.ts +23 -1
  512. package/src/types/data-provider.ts +2 -0
  513. package/src/types/headless.ts +17 -0
  514. package/src/types/price-history.ts +2 -0
  515. package/src/ui/host.tsx +6 -0
  516. package/src/utils/double-escape-close.ts +20 -0
  517. package/src/utils/exchanges.ts +1 -0
  518. package/src/utils/html-entities.ts +15 -0
  519. package/src/utils/http-proxy-response.ts +44 -7
  520. package/src/utils/plugin-proxy-hosts.json +3 -0
  521. package/src/utils/price-history.ts +35 -1
  522. package/src/utils/sec.ts +21 -2
  523. package/src/utils/text-wrap.ts +13 -8
  524. package/src/utils/zoned-date-time.ts +67 -0
@@ -1,3 +1,4 @@
1
+ import type { ReactNode } from "react";
1
2
  import { useMemo } from "react";
2
3
  import { Box, Text, TextAttributes, useUiCapabilities } from "../../../../ui";
3
4
  import type { PricePoint, Quote, TickerFinancials } from "../../../../types/financials";
@@ -5,6 +6,7 @@ import type { TickerRecord } from "../../../../types/ticker";
5
6
  import type { QueryEntry } from "../../../../market-data/result-types";
6
7
  import { resolveEntryData } from "../../../../market-data/selectors";
7
8
  import { useDoubleClickActivation } from "../../../../components/use-double-click-activation";
9
+ import { FigureText } from "../../../../components/ui/figure";
8
10
  import { colors, priceColor } from "../../../../theme/colors";
9
11
  import { formatPercentRaw } from "../../../../utils/format";
10
12
  import { formatMarketPriceWithCurrency, formatSignedMarketPrice, liveQuoteFormatOptions } from "../../../../market-data/market/format";
@@ -61,7 +63,9 @@ export function QuoteMonitorCard({
61
63
  selected = false,
62
64
  onSelect,
63
65
  onOpen,
66
+ perpetuals,
64
67
  }: {
68
+ perpetuals?: ReactNode;
65
69
  symbol: string;
66
70
  ticker: TickerRecord | null;
67
71
  cachedFinancials: TickerFinancials | null;
@@ -97,9 +101,8 @@ export function QuoteMonitorCard({
97
101
  const quoteStatus = resolveQuoteStatus(quoteEntry, symbol, quote);
98
102
  const quoteFailed = quoteStatus.failed && !!display;
99
103
  const changeColor = quoteFailed ? colors.textDim : priceColor(display?.change ?? 0);
100
- const priceAttributes = flashDirection ? TextAttributes.DIM : TextAttributes.BOLD;
101
- const changeAttributes = flashDirection ? TextAttributes.DIM : TextAttributes.NONE;
102
- const currency = quote?.currency ?? ticker?.metadata.currency ?? "USD";
104
+ const flashing = !!flashDirection;
105
+ const currency = quote?.currency || ticker?.metadata.currency || "USD";
103
106
  const stacked = width < 31;
104
107
  const compactQuoteFailure = quoteFailed && stacked && height <= 3;
105
108
  // One decimal count per instrument, so streamed ticks never narrow or widen the price column.
@@ -119,22 +122,8 @@ export function QuoteMonitorCard({
119
122
  const trend = quoteTrend(display?.change);
120
123
  const terminalSparklineHeight = !nativePaneChrome && !stacked && height >= 4 ? 2 : 1;
121
124
  const showTerminalSparkline = !quoteFailed || height >= (stacked ? 3 : 2) + 1 + terminalSparklineHeight;
122
- const desktopPriceStyle = nativePaneChrome
123
- ? {
124
- fontSize: "22px",
125
- lineHeight: "1.05",
126
- fontWeight: 720,
127
- textShadow: `0 1px 2px ${colors.bg}`,
128
- }
129
- : undefined;
130
- const desktopChangeStyle = nativePaneChrome
131
- ? {
132
- fontSize: "12px",
133
- lineHeight: "1.1",
134
- fontWeight: 540,
135
- textShadow: `0 1px 2px ${colors.bg}`,
136
- }
137
- : undefined;
125
+ // Figures sit over the sparkline, so the desktop rings them in the card colour.
126
+ const figureHalo = { textShadow: `0 1px 2px ${colors.bg}` };
138
127
  const desktopSymbolStyle = nativePaneChrome
139
128
  ? {
140
129
  fontSize: "15px",
@@ -198,7 +187,7 @@ export function QuoteMonitorCard({
198
187
  display: "grid",
199
188
  // The name gives way first; the price keeps its natural width.
200
189
  gridTemplateColumns: "minmax(0, 1fr) auto",
201
- gridTemplateRows: "auto 1fr auto",
190
+ gridTemplateRows: "auto 1fr auto auto",
202
191
  columnGap: 12,
203
192
  width: "100%",
204
193
  height: "100%",
@@ -253,19 +242,14 @@ export function QuoteMonitorCard({
253
242
  paddingBottom: 1,
254
243
  }}
255
244
  >
256
- <Text
257
- attributes={priceAttributes}
258
- fg={changeColor}
259
- style={desktopPriceStyle}
260
- >
261
- {priceText}
262
- </Text>
245
+ <FigureText fg={changeColor} dim={flashing} style={figureHalo}>{priceText}</FigureText>
263
246
  <Box flexDirection="row" gap={1} justifyContent="flex-end">
264
- <Text fg={changeColor} attributes={changeAttributes} style={desktopChangeStyle}>{changePercentText}</Text>
265
- <Text fg={changeColor} attributes={changeAttributes} style={desktopChangeStyle}>{changeValueText}</Text>
247
+ <FigureText part="sub" fg={changeColor} dim={flashing} style={figureHalo}>{changePercentText}</FigureText>
248
+ <FigureText part="sub" fg={changeColor} dim={flashing} style={figureHalo}>{changeValueText}</FigureText>
266
249
  </Box>
267
250
  </Box>
268
251
 
252
+ {perpetuals && <Box style={{ gridColumn: "1 / -1", gridRow: "4", alignSelf: "end" }}>{perpetuals}</Box>}
269
253
  {rangeLabel && (
270
254
  <Text
271
255
  fg={colors.textDim}
@@ -294,12 +278,12 @@ export function QuoteMonitorCard({
294
278
  {symbol}
295
279
  </Text>
296
280
  <Box flexDirection="column">
297
- <Text attributes={priceAttributes} fg={changeColor} style={desktopPriceStyle}>
281
+ <FigureText fg={changeColor} dim={flashing} style={figureHalo}>
298
282
  {compactQuoteFailure ? `${priceText} · ${quoteStatus.stale ? "STALE" : "ERROR"}` : priceText}
299
- </Text>
283
+ </FigureText>
300
284
  <Box flexDirection="row" gap={1}>
301
- <Text fg={changeColor} attributes={changeAttributes} style={desktopChangeStyle}>{changePercentText}</Text>
302
- <Text fg={changeColor} attributes={changeAttributes} style={desktopChangeStyle}>{changeValueText}</Text>
285
+ <FigureText part="sub" fg={changeColor} dim={flashing} style={figureHalo}>{changePercentText}</FigureText>
286
+ <FigureText part="sub" fg={changeColor} dim={flashing} style={figureHalo}>{changeValueText}</FigureText>
303
287
  </Box>
304
288
  </Box>
305
289
  </Box>
@@ -331,16 +315,10 @@ export function QuoteMonitorCard({
331
315
  )}
332
316
  </Box>
333
317
  <Box flexDirection="column" alignItems="flex-end">
334
- <Text
335
- attributes={priceAttributes}
336
- fg={changeColor}
337
- style={desktopPriceStyle}
338
- >
339
- {priceText}
340
- </Text>
318
+ <FigureText fg={changeColor} dim={flashing} style={figureHalo}>{priceText}</FigureText>
341
319
  <Box flexDirection="row" gap={1} justifyContent="flex-end">
342
- <Text fg={changeColor} attributes={changeAttributes} style={desktopChangeStyle}>{changePercentText}</Text>
343
- <Text fg={changeColor} attributes={changeAttributes} style={desktopChangeStyle}>{changeValueText}</Text>
320
+ <FigureText part="sub" fg={changeColor} dim={flashing} style={figureHalo}>{changePercentText}</FigureText>
321
+ <FigureText part="sub" fg={changeColor} dim={flashing} style={figureHalo}>{changeValueText}</FigureText>
344
322
  </Box>
345
323
  </Box>
346
324
  </Box>
@@ -349,6 +327,7 @@ export function QuoteMonitorCard({
349
327
  {quoteFailed && !compactQuoteFailure && (
350
328
  <Box height={1} overflow="hidden"><Text fg={colors.negative}>{quoteStatus.text}</Text></Box>
351
329
  )}
330
+ {perpetuals}
352
331
  {showTerminalSparkline && <Box height={terminalSparklineHeight} flexDirection="row" alignItems="center" gap={1}>
353
332
  <PriceSparkline
354
333
  priceHistory={priceHistory}
@@ -1,3 +1,4 @@
1
+ import { PerpEquityRow } from "../../perps/equity-row";
1
2
  import { useCallback, useEffect, useMemo, useRef, useState } from "react";
2
3
  import { Box, useUiCapabilities } from "../../../../ui";
3
4
  import type { PaneProps } from "../../../../types/plugin";
@@ -263,6 +264,7 @@ export function QuoteMonitorPane({ paneId, focused, width, height }: PaneProps)
263
264
  selected={showCursor && index === cursorIndex}
264
265
  onSelect={setCursorSymbol}
265
266
  onOpen={openTicker}
267
+ perpetuals={cardHeight >= 8 ? <PerpEquityRow maxRows={1} symbol={entry.symbol} instrumentType={entry.ticker?.metadata.assetCategory} /> : undefined}
266
268
  />
267
269
  ))}
268
270
  </Box>
@@ -297,6 +299,7 @@ export function QuoteMonitorPane({ paneId, focused, width, height }: PaneProps)
297
299
  selected={showCursor && rowIndex * columns + columnIndex === cursorIndex}
298
300
  onSelect={setCursorSymbol}
299
301
  onOpen={openTicker}
302
+ perpetuals={cardHeight >= 8 ? <PerpEquityRow maxRows={1} symbol={entry.symbol} instrumentType={entry.ticker?.metadata.assetCategory} /> : undefined}
300
303
  />
301
304
  ))}
302
305
  </Box>
@@ -90,7 +90,7 @@ function TimeSalesView({ width, height, focused, symbol, exchange }: PaneProps &
90
90
  ...(!data.connected || resource.snapshotOnly ? [{ id: "snapshot", parts: [{ text: "snapshot", tone: "warning" as const }] }] : [])] : [] });
91
91
  const selectTab = (value: string) => { setTab(value); setDetail(null); setSelected(null); };
92
92
  const { strip: tabStrip, rows: tabRows } = usePaneTabs({ tabs: TABS, activeValue: tab, onSelect: selectTab, focused: focused && !detail, dense: true });
93
- if (!data && isCloudSessionRequired(resource.error)) return <SignInWall action="view time and sales" needsVerification={session.needsVerification} />;
93
+ if (!data && isCloudSessionRequired(resource.error)) return <SignInWall placement="time-sales-signin" action="view time and sales" needsVerification={session.needsVerification} />;
94
94
  return <Box width={width} height={height} flexDirection="column">
95
95
  {tabStrip}
96
96
  <PaneStatusBody loading={resource.loading && !data} error={!data ? resource.error : null} empty={!!data && !rows.length} subject={tab === "quotes" ? "NBBO observations" : "trade observations"}>
@@ -28,6 +28,7 @@ export const WORLD_INDICES: IndexEntry[] = [
28
28
  { symbol: "000001.SS", name: "Shanghai Composite", shortName: "SHCOMP", region: "asia-pacific" },
29
29
  { symbol: "^KS11", name: "KOSPI", shortName: "KOSPI", region: "asia-pacific" },
30
30
  { symbol: "^AXJO", name: "ASX 200", shortName: "ASX", region: "asia-pacific" },
31
+ { symbol: "^NSEI", name: "Nifty 50", shortName: "NIFTY", region: "asia-pacific" },
31
32
  { symbol: "^BSESN", name: "BSE Sensex", shortName: "SENSEX", region: "asia-pacific" },
32
33
 
33
34
  // Other
@@ -1,3 +1,13 @@
1
+ import { creditDocumentsModule } from "./builtin/credit-documents";
2
+ import { attentionModule } from "./builtin/attention";
3
+ import { companyAttentionModule } from "./builtin/company-attention";
4
+ import { catalystsModule } from "./builtin/catalysts";
5
+ import { companyKpisModule } from "./builtin/company-kpis";
6
+ import { powerModule } from "./builtin/power";
7
+ import { perpsModule } from "./builtin/perps";
8
+ import { exposureModule } from "./builtin/exposure";
9
+ import { supplyChainModule } from "./builtin/supply-chain";
10
+ import { awardsModule } from "./builtin/awards";
1
11
  import { debtMaturitiesModule } from "./builtin/debt-maturities";
2
12
  import { revenueBreakdownModule } from "./builtin/revenue-breakdown";
3
13
  import { mnaModule } from "./builtin/mna";
@@ -20,6 +30,9 @@ import { marketHeatmapPlugin } from "./builtin/market-heatmap";
20
30
  import { marketHaltsPlugin } from "./builtin/market-halts";
21
31
  import { fearGreedPlugin } from "./builtin/fear-greed";
22
32
  import { ipoCalendarPlugin } from "./builtin/ipo-calendar";
33
+ import { clinicalTrialsPlugin } from "./builtin/clinical-trials";
34
+ import { commentLettersPlugin } from "./builtin/comment-letters";
35
+ import { openFdaPlugin } from "./builtin/openfda";
23
36
  import { browserGloomberbCloudPlugin } from "./builtin/cloud/browser";
24
37
  import { changelogModule } from "./builtin/changelog";
25
38
  import { chartComposerModule } from "./builtin/chart-composer";
@@ -33,10 +46,13 @@ import { creditConditionsModule } from "./builtin/credit-conditions";
33
46
  import { marketValuationModule } from "./builtin/market-valuation";
34
47
  import { macroSharedResourcesModule } from "./builtin/macro-resources";
35
48
  import { economicCalendarModule } from "./builtin/econ";
49
+ import { cpiModule } from "./builtin/cpi";
36
50
  import { econStatisticsModule } from "./builtin/econ-statistics";
37
51
  import { futuresModule } from "./builtin/futures";
38
52
  import { futuresCurveModule } from "./builtin/futures-curve";
39
53
  import { cotModule } from "./builtin/cot";
54
+ import { doeModule } from "./builtin/doe";
55
+ import { gpuModule } from "./builtin/gpu";
40
56
  import { fxMatrixModule } from "./builtin/fx-matrix";
41
57
  import { helpModule } from "./builtin/help";
42
58
  import { positionSizerModule } from "./builtin/kelly-sizer";
@@ -53,6 +69,10 @@ import { optionsCalculatorModule } from "./builtin/options-calculator";
53
69
  import { volSurfaceModule } from "./builtin/vol-surface";
54
70
  import { realizedVolModule } from "./builtin/realized-vol";
55
71
  import { seasonalityModule } from "./builtin/seasonality";
72
+ import { earningsRippleModule } from "./builtin/earnings-ripple";
73
+ import { reverseDcfModule } from "./builtin/reverse-dcf";
74
+ import { peBandModule } from "./builtin/pe-band";
75
+ import { macroDayModule } from "./builtin/macro-day";
56
76
  import { ivHistoryModule } from "./builtin/iv-history";
57
77
  import { backtestModule } from "./builtin/backtest";
58
78
  import { composeBuiltinPlugin } from "./builtin/plugin-module";
@@ -101,6 +121,10 @@ const browserTickerResearchPlugin = composeBuiltinPlugin({
101
121
  volSurfaceModule,
102
122
  realizedVolModule,
103
123
  seasonalityModule,
124
+ earningsRippleModule,
125
+ reverseDcfModule,
126
+ peBandModule,
127
+ macroDayModule,
104
128
  ivHistoryModule,
105
129
  backtestModule,
106
130
  timeSalesModule,
@@ -110,6 +134,13 @@ const browserTickerResearchPlugin = composeBuiltinPlugin({
110
134
  socialMentionsModule,
111
135
  debtMaturitiesModule,
112
136
  revenueBreakdownModule,
137
+ supplyChainModule,
138
+ creditDocumentsModule,
139
+ companyAttentionModule,
140
+ catalystsModule,
141
+ companyKpisModule,
142
+ awardsModule,
143
+ exposureModule,
113
144
  mnaModule,
114
145
  browserDividendYieldModule,
115
146
  earningsCallsModule,
@@ -144,7 +175,12 @@ const browserMarketOverviewPlugin = composeBuiltinPlugin({
144
175
  futuresModule,
145
176
  futuresCurveModule,
146
177
  cotModule,
178
+ doeModule,
179
+ gpuModule,
180
+ attentionModule,
181
+ powerModule,
147
182
  cryptoBoardModule,
183
+ perpsModule,
148
184
  ],
149
185
  });
150
186
 
@@ -155,6 +191,7 @@ const browserMacroPlugin = composeBuiltinPlugin({
155
191
  macroSharedResourcesModule,
156
192
  economicCalendarModule,
157
193
  econStatisticsModule,
194
+ cpiModule,
158
195
  yieldCurveModule,
159
196
  ratePathModule,
160
197
  moneyMarketsModule,
@@ -185,6 +222,9 @@ export const browserBuiltinPlugins: readonly GloomPlugin[] = [
185
222
  marketHaltsPlugin,
186
223
  fearGreedPlugin,
187
224
  ipoCalendarPlugin,
225
+ clinicalTrialsPlugin,
226
+ commentLettersPlugin,
227
+ openFdaPlugin,
188
228
  browserMacroPlugin,
189
229
  alertsPlugin,
190
230
  researchSearchPlugin,
@@ -45,6 +45,8 @@ const EDITORIAL: Record<
45
45
  alerts: { categories: ["alerts"] },
46
46
  application: { categories: ["core"] },
47
47
  broker: { categories: ["broker"] },
48
+ "clinical-trials": { categories: ["research"] },
49
+ "comment-letters": { categories: ["research"] },
48
50
  "custom-view": { categories: ["data", "productivity"] },
49
51
  debug: { categories: ["developer"] },
50
52
  "fear-greed": { categories: ["markets", "sentiment"], icon: "plugin-icons/fear-greed.webp" },
@@ -55,6 +57,7 @@ const EDITORIAL: Record<
55
57
  "market-overview": { categories: ["markets"] },
56
58
  news: { categories: ["news"] },
57
59
  notes: { categories: ["productivity"] },
60
+ openfda: { categories: ["research"] },
58
61
  portfolio: { categories: ["portfolio"] },
59
62
  "research-search": { categories: ["research", "news"] },
60
63
  "ticker-research": { categories: ["research"] },
@@ -10,6 +10,9 @@ import { marketHeatmapPlugin } from "./builtin/market-heatmap";
10
10
  import { marketHaltsPlugin } from "./builtin/market-halts";
11
11
  import { fearGreedPlugin } from "./builtin/fear-greed";
12
12
  import { ipoCalendarPlugin } from "./builtin/ipo-calendar";
13
+ import { clinicalTrialsPlugin } from "./builtin/clinical-trials";
14
+ import { commentLettersPlugin } from "./builtin/comment-letters";
15
+ import { openFdaPlugin } from "./builtin/openfda";
13
16
  import {
14
17
  applicationPlugin,
15
18
  brokerPlugin,
@@ -33,6 +36,9 @@ export const uiBuiltinPlugins: GloomPlugin[] = [
33
36
  marketHaltsPlugin,
34
37
  fearGreedPlugin,
35
38
  ipoCalendarPlugin,
39
+ clinicalTrialsPlugin,
40
+ commentLettersPlugin,
41
+ openFdaPlugin,
36
42
  macroPlugin,
37
43
  alertsPlugin,
38
44
  researchSearchPlugin,
@@ -18,15 +18,6 @@ export function getCurrentPluginTarget(): PluginTarget {
18
18
  return currentTarget;
19
19
  }
20
20
 
21
- /**
22
- * Whether this renderer can install plugins itself. Installing means cloning a
23
- * repository and running `bun install`, so only the Bun-hosted renderers can;
24
- * elsewhere the marketplace shows the command to run instead.
25
- */
26
- export function canInstallPlugins(): boolean {
27
- return currentTarget === "cli" || currentTarget === "tui";
28
- }
29
-
30
21
  /**
31
22
  * Whether this renderer loads plugins that are not part of its build.
32
23
  *
@@ -91,6 +91,7 @@ exports[`the runtime exports of every public subpath are the reviewed ones 1`] =
91
91
  "PaneLinkMenu",
92
92
  "PaneSidebar",
93
93
  "PaneSidebarAction",
94
+ "PaneSidebarList",
94
95
  "PaneSidebarRow",
95
96
  "PaneStatusBody",
96
97
  "Popover",
@@ -1,4 +1,5 @@
1
- import { apiClient, setCloudApiFetchTransport } from "../../api-client";
1
+ import { apiClient, setCloudApiFetchTransport, setCloudApiUploadTransport } from "../../api-client";
2
+ import type { CloudApiUploadRequest } from "../../api-client/request";
2
3
  import { settleWithin } from "../../utils/async-deadline";
3
4
  import { setHttpFetchTransport } from "../../utils/http-transport";
4
5
  import { createBrowserHttpProxyTransport } from "./http-proxy-transport";
@@ -30,10 +31,74 @@ export function browserCredentialedFetch(url: string, init: RequestInit = {}): P
30
31
  return fetch(url, { ...init, headers, credentials: "include" });
31
32
  }
32
33
 
34
+ function parseResponseHeaders(raw: string): Headers {
35
+ const headers = new Headers();
36
+ for (const line of raw.trim().split(/[\r\n]+/)) {
37
+ const separator = line.indexOf(":");
38
+ if (separator <= 0) continue;
39
+ try {
40
+ headers.append(line.slice(0, separator).trim(), line.slice(separator + 1).trim());
41
+ } catch {
42
+ // A header the Headers class refuses is not one the client reads.
43
+ }
44
+ }
45
+ return headers;
46
+ }
47
+
48
+ /**
49
+ * Uploads through XMLHttpRequest, the one browser API that reports how much of
50
+ * a request body has gone out, so an image upload can show its progress.
51
+ */
52
+ function browserXhrUpload(request: CloudApiUploadRequest): Promise<Response> {
53
+ const cookieHeader = request.headers.get("Cookie");
54
+ if (cookieHeader) plantBrowserSessionCookies(cookieHeader);
55
+ return new Promise((resolve, reject) => {
56
+ if (request.signal?.aborted) {
57
+ reject(new DOMException("The operation was aborted.", "AbortError"));
58
+ return;
59
+ }
60
+ const xhr = new XMLHttpRequest();
61
+ xhr.open("POST", request.url);
62
+ xhr.withCredentials = true;
63
+ request.headers.forEach((value, name) => {
64
+ const lower = name.toLowerCase();
65
+ if (lower === "cookie" || lower === "origin") return;
66
+ xhr.setRequestHeader(name, value);
67
+ });
68
+ const abort = () => xhr.abort();
69
+ request.signal?.addEventListener("abort", abort, { once: true });
70
+ const settle = () => request.signal?.removeEventListener("abort", abort);
71
+ xhr.upload.onprogress = (event) => {
72
+ if (event.lengthComputable && event.total > 0) request.onProgress?.(event.loaded / event.total);
73
+ };
74
+ xhr.onload = () => {
75
+ settle();
76
+ const text = xhr.responseText;
77
+ resolve({
78
+ ok: xhr.status >= 200 && xhr.status < 300,
79
+ status: xhr.status,
80
+ statusText: xhr.statusText,
81
+ headers: parseResponseHeaders(xhr.getAllResponseHeaders()),
82
+ text: async () => text,
83
+ } as Response);
84
+ };
85
+ xhr.onerror = () => {
86
+ settle();
87
+ reject(new TypeError("The upload could not reach the server."));
88
+ };
89
+ xhr.onabort = () => {
90
+ settle();
91
+ reject(new DOMException("The operation was aborted.", "AbortError"));
92
+ };
93
+ xhr.send(request.body as XMLHttpRequestBodyInit);
94
+ });
95
+ }
96
+
33
97
  export function installBrowserFetchTransports(): void {
34
98
  apiClient.setCookieSessionMode(true);
35
99
  // Native fetch, so a response body can be read while it arrives.
36
100
  setCloudApiFetchTransport(browserCredentialedFetch, { streaming: true });
101
+ setCloudApiUploadTransport(browserXhrUpload);
37
102
  // Plugin requests to a host on the proxy allowlist go through the worker,
38
103
  // which can reach APIs that send no CORS headers. Those come back buffered,
39
104
  // but nothing on the allowlist streams; every other host is a direct fetch
@@ -29,6 +29,7 @@ import {
29
29
  readOrCreateBrowserInstallId,
30
30
  } from "../../telemetry/crash-reports-dom";
31
31
  import { currentTelemetryConfig } from "../../telemetry/live-config";
32
+ import { attentionCountsEnabled, installAttentionCounter } from "../../telemetry/attention-counts";
32
33
  import { installUsageCounter, recordRestoredFunctions, usageCountsEnabled } from "../../telemetry/usage-counts";
33
34
  import { installWindowUsageFlush } from "../../telemetry/usage-counts-dom";
34
35
  import type { AppConfig } from "../../types/config";
@@ -62,6 +63,7 @@ async function boot(): Promise<void> {
62
63
  getInstallId: () => readOrCreateBrowserInstallId(),
63
64
  officialPluginIds: loadOfficialPluginIds,
64
65
  });
66
+ installAttentionCounter(() => !browserDoNotTrack() && attentionCountsEnabled(currentTelemetryConfig(loadedConfig)));
65
67
  // A document reload does not unmount React. Flush both config and session
66
68
  // timers while localStorage is still available, including background tabs.
67
69
  window.addEventListener("pagehide", () => { void flushPendingPersistence(); });
@@ -254,6 +254,7 @@ function WebDataTableRowInner<
254
254
  <div
255
255
  key={itemKey}
256
256
  data-gloom-role="data-table-section-header"
257
+ data-gloom-row-key={itemKey}
257
258
  data-selected={selected ? "true" : undefined}
258
259
  style={{
259
260
  ...baseRowStyle,
@@ -302,6 +303,7 @@ function WebDataTableRowInner<
302
303
  key={itemKey}
303
304
  ref={ref}
304
305
  data-gloom-role="data-table-row"
306
+ data-gloom-row-key={itemKey}
305
307
  data-gloom-context-menu-surface={rowContextMenuSurface ? "true" : undefined}
306
308
  data-selected={selected ? "true" : undefined}
307
309
  style={{
@@ -387,6 +387,7 @@ export function WebMessageComposer({
387
387
  onSubmit,
388
388
  keyBindings,
389
389
  wrapText = false,
390
+ accessory,
390
391
  }: MessageComposerProps) {
391
392
  const colors = useThemeColors();
392
393
  const borderColor = focused
@@ -414,31 +415,43 @@ export function WebMessageComposer({
414
415
  overflow: "hidden",
415
416
  }}
416
417
  >
417
- <Textarea
418
- ref={inputRef}
419
- initialValue={initialValue}
420
- width="100%"
421
- height={height}
422
- focused={focused}
423
- placeholder={placeholder}
424
- placeholderColor={colors.textMuted}
425
- textColor={colors.text}
426
- backgroundColor="transparent"
427
- focusedBackgroundColor="transparent"
428
- cursorColor={colors.textBright}
429
- style={{
430
- padding: "6px 12px",
431
- lineHeight: "20px",
432
- fontSize: "13px",
433
- }}
434
- onMouseDown={requestFocus}
435
- onFocus={requestFocus}
436
- onInput={handleInput}
437
- onCursorChange={onCursorChange}
438
- keyBindings={keyBindings}
439
- onSubmit={onSubmit}
440
- wrapText={wrapText}
441
- />
418
+ {/* The field takes what the accessory leaves. */}
419
+ <Box flexGrow={1} height={height} style={{ minWidth: 0 }}>
420
+ <Textarea
421
+ ref={inputRef}
422
+ initialValue={initialValue}
423
+ width="100%"
424
+ height={height}
425
+ focused={focused}
426
+ placeholder={placeholder}
427
+ placeholderColor={colors.textMuted}
428
+ textColor={colors.text}
429
+ backgroundColor="transparent"
430
+ focusedBackgroundColor="transparent"
431
+ cursorColor={colors.textBright}
432
+ style={{
433
+ padding: "6px 12px",
434
+ lineHeight: "20px",
435
+ fontSize: "13px",
436
+ }}
437
+ onMouseDown={requestFocus}
438
+ onFocus={requestFocus}
439
+ onInput={handleInput}
440
+ onCursorChange={onCursorChange}
441
+ keyBindings={keyBindings}
442
+ onSubmit={onSubmit}
443
+ wrapText={wrapText}
444
+ />
445
+ </Box>
446
+ {accessory != null && (
447
+ <Box
448
+ flexDirection="row"
449
+ data-gloom-role="desktop-message-composer-accessory"
450
+ style={{ flex: "none", alignItems: "flex-start", padding: "4px 6px 0 0" }}
451
+ >
452
+ {accessory}
453
+ </Box>
454
+ )}
442
455
  </Box>
443
456
  );
444
457
  }
@@ -79,6 +79,14 @@ const ICONS: Record<IconName, ReactNode> = {
79
79
  <circle cx="7.6" cy="9" r="0.9" fill="currentColor" />
80
80
  </>
81
81
  ),
82
+ // A framed picture: a sun over hills.
83
+ image: (
84
+ <>
85
+ <rect x="1.5" y="2.25" width="9" height="7.5" rx="1.2" stroke="currentColor" strokeWidth="1.1" />
86
+ <circle cx="4.4" cy="4.9" r="0.85" fill="currentColor" />
87
+ <path d="M2 9.1 4.7 6.6l1.6 1.5 1.8-2 2.4 2.5" stroke="currentColor" strokeWidth="1.1" strokeLinecap="round" strokeLinejoin="round" />
88
+ </>
89
+ ),
82
90
  restore: (
83
91
  <>
84
92
  <rect x="2" y="4" width="6" height="6" rx="0.8" stroke="currentColor" strokeWidth="1.1" />
@@ -3,6 +3,7 @@ import {
3
3
  forwardRef,
4
4
  memo,
5
5
  useEffect,
6
+ useId,
6
7
  useRef,
7
8
  type CSSProperties,
8
9
  type ReactNode,
@@ -59,8 +60,23 @@ const BoxLayer = memo(function BoxLayer({ bitmap, index }: { bitmap: BitmapSurfa
59
60
  );
60
61
  });
61
62
 
63
+ /** A left-to-right gradient in the overlay's 0..1 user space, so a flat line keeps its colours too. */
64
+ function VectorGradient({ id, shape }: { id: string; shape: ChartVectorShape }) {
65
+ const stops = shape.gradient ?? [];
66
+ const xs = shape.points.map((point) => point.x);
67
+ return (
68
+ <linearGradient id={id} gradientUnits="userSpaceOnUse" x1={Math.min(...xs)} x2={Math.max(...xs)} y1={0} y2={0}>
69
+ {stops.map((color, index) => (
70
+ <stop key={index} offset={stops.length > 1 ? index / (stops.length - 1) : 0} stopColor={color} />
71
+ ))}
72
+ </linearGradient>
73
+ );
74
+ }
75
+
62
76
  const ChartVectors = memo(function ChartVectors({ vectors }: { vectors: readonly ChartVectorShape[] }) {
77
+ const gradientPrefix = useId().replace(/:/g, "");
63
78
  if (vectors.length === 0) return null;
79
+ const paint = (shape: ChartVectorShape, index: number) => (shape.gradient?.length ? `url(#${gradientPrefix}-${index})` : shape.color);
64
80
  return (
65
81
  <>
66
82
  <svg
@@ -77,9 +93,26 @@ const ChartVectors = memo(function ChartVectors({ vectors }: { vectors: readonly
77
93
  zIndex: 9,
78
94
  }}
79
95
  >
80
- {vectors.map((shape) => {
96
+ <defs>
97
+ {vectors.map((shape, index) => (shape.gradient?.length && shape.points.length
98
+ ? <VectorGradient key={shape.id} id={`${gradientPrefix}-${index}`} shape={shape} />
99
+ : null))}
100
+ </defs>
101
+ {vectors.map((shape, index) => {
81
102
  const strokeWidth = shape.strokeWidth ?? 1.4;
82
103
  const [first, second] = shape.points;
104
+ if (shape.fill) {
105
+ return (
106
+ <polygon
107
+ key={shape.id}
108
+ points={shape.points.map((point) => `${point.x},${point.y}`).join(" ")}
109
+ fill={paint(shape, index)}
110
+ fillOpacity={shape.fillOpacity ?? 1}
111
+ stroke="none"
112
+ opacity={shape.opacity}
113
+ />
114
+ );
115
+ }
83
116
  if (shape.box && first && second) {
84
117
  return (
85
118
  <rect
@@ -101,7 +134,8 @@ const ChartVectors = memo(function ChartVectors({ vectors }: { vectors: readonly
101
134
  key={shape.id}
102
135
  points={shape.points.map((point) => `${point.x},${point.y}`).join(" ")}
103
136
  fill="none"
104
- stroke={shape.color}
137
+ stroke={paint(shape, index)}
138
+ opacity={shape.opacity}
105
139
  strokeWidth={strokeWidth}
106
140
  strokeLinecap="round"
107
141
  strokeLinejoin="round"
@@ -60,7 +60,7 @@ export function installFocusScopeRelease(): () => void {
60
60
  const active = doc.activeElement;
61
61
  if (!active || active === doc.body || isEditableTarget(active)) return;
62
62
  const control = asFocusable(event.target)?.closest?.(POINTER_CONTROL_SELECTOR);
63
- if (control !== active) return;
63
+ if (control !== active || holdsTextSelection(doc, control)) return;
64
64
  const detail = event.detail;
65
65
  queueMicrotask(() => {
66
66
  if (doc.activeElement === active) releasePointerFocus(active, detail);
@@ -74,6 +74,16 @@ export function installFocusScopeRelease(): () => void {
74
74
  };
75
75
  }
76
76
 
77
+ /**
78
+ * Dragging across text ends in a click too, on whatever holds the focus behind
79
+ * it: usually the app root, which matches `[tabindex]`. That was no press of a
80
+ * control, and WebKit drops the selection with the blur, so it is left alone.
81
+ */
82
+ function holdsTextSelection(doc: Document, control: Pick<FocusableLike, "contains"> | null): boolean {
83
+ const selection = doc.getSelection?.();
84
+ return !!selection && !selection.isCollapsed && !!control?.contains?.(selection.anchorNode);
85
+ }
86
+
77
87
  /**
78
88
  * Keyboard focus lives in the app, not the DOM: Tab moves between panes, and a
79
89
  * pane's rows and hints act on keys that reach the window. A button a pointer