gloomberb 0.16.0 → 0.16.2

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 (691) hide show
  1. package/README.md +2 -1
  2. package/package.json +2 -1
  3. package/src/api-client/beneficial-owners.ts +92 -0
  4. package/src/api-client/data.ts +44 -11
  5. package/src/api-client/errors.ts +12 -0
  6. package/src/api-client/geo.ts +363 -0
  7. package/src/api-client/index.ts +5 -0
  8. package/src/api-client/market-discovery.ts +10 -0
  9. package/src/api-client/members.ts +26 -0
  10. package/src/api-client/paths.ts +30 -1
  11. package/src/api-client/perps.ts +41 -0
  12. package/src/api-client/request.ts +5 -2
  13. package/src/api-client/types.ts +9 -1
  14. package/src/app/global-shortcuts.ts +14 -6
  15. package/src/app/keybindings/actions.ts +1 -1
  16. package/src/app/runtime/update.ts +38 -2
  17. package/src/app.tsx +10 -6
  18. package/src/brokers/account-cache.ts +24 -0
  19. package/src/cli/commands/command-utils.ts +8 -0
  20. package/src/cli/commands/crypto-hints.ts +75 -0
  21. package/src/cli/commands/market.ts +414 -106
  22. package/src/cli/commands/overview.ts +77 -32
  23. package/src/cli/commands/ticker.ts +101 -43
  24. package/src/cli/desktop-pane-shot.ts +34 -4
  25. package/src/cli/freshness.ts +61 -0
  26. package/src/cli/help.ts +1 -0
  27. package/src/cli/helpers.ts +4 -8
  28. package/src/cli/index.ts +12 -2
  29. package/src/cli/listing-arg.ts +321 -0
  30. package/src/cli/pane-functions/access-gate.ts +42 -0
  31. package/src/cli/pane-functions/catalog.ts +28 -1
  32. package/src/cli/pane-functions/data.ts +3 -1
  33. package/src/cli/pane-functions/dom.ts +20 -2
  34. package/src/cli/pane-functions/freshness.ts +400 -0
  35. package/src/cli/pane-functions/function-help.ts +36 -22
  36. package/src/cli/pane-functions/headless.ts +39 -11
  37. package/src/cli/pane-functions/index.ts +15 -4
  38. package/src/cli/pane-functions/options.ts +3 -0
  39. package/src/cli/pane-functions/report.ts +4 -0
  40. package/src/cli/pane-functions/resolver.ts +35 -7
  41. package/src/cli/pane-functions/screenshot-evidence.ts +2 -0
  42. package/src/cli/pane-functions/screenshot.ts +7 -3
  43. package/src/cli/result.ts +41 -27
  44. package/src/cli/ticker-resolution.ts +7 -5
  45. package/src/components/chart/composite/composite-chart.tsx +88 -2536
  46. package/src/components/chart/composite/drawing-store.ts +59 -0
  47. package/src/components/chart/composite/legend.tsx +319 -0
  48. package/src/components/chart/composite/panel-bitmap.ts +139 -0
  49. package/src/components/chart/composite/panel-gestures.ts +59 -0
  50. package/src/components/chart/composite/panel-labels.ts +107 -0
  51. package/src/components/chart/composite/panel-surface.tsx +876 -0
  52. package/src/components/chart/composite/tool-catalog.ts +98 -0
  53. package/src/components/chart/composite/toolbar.tsx +186 -0
  54. package/src/components/chart/composite/tools.ts +8 -0
  55. package/src/components/chart/composite/use-composite-chart-keyboard.ts +703 -0
  56. package/src/components/chart/composite/use-composite-viewport.ts +143 -0
  57. package/src/components/command-bar/commands/collection.ts +5 -1
  58. package/src/components/command-bar/list/model.ts +5 -0
  59. package/src/components/command-bar/list/view.tsx +16 -3
  60. package/src/components/command-bar/pane-templates/workflow.ts +1 -0
  61. package/src/components/command-bar/routes/root/command-items.ts +9 -2
  62. package/src/components/command-bar/routes/root/plugin-install.ts +2 -2
  63. package/src/components/command-bar/routes/root/provider-search.ts +19 -5
  64. package/src/components/command-bar/routes/root/runtime.ts +14 -5
  65. package/src/components/command-bar/routes/ticker-search/actions.ts +5 -0
  66. package/src/components/command-bar/routes/ticker-search/results.ts +31 -5
  67. package/src/components/command-bar/routes/ticker-search/route.ts +2 -2
  68. package/src/components/command-bar/routing/actions.ts +2 -0
  69. package/src/components/command-bar/selection-runtime.ts +38 -0
  70. package/src/components/command-bar/surface/index.tsx +7 -2
  71. package/src/components/command-bar/workflow/ops.ts +1 -1
  72. package/src/components/command-bar/workflow/tickers.ts +6 -0
  73. package/src/components/data-table/view.tsx +29 -10
  74. package/src/components/feedback-dialog.tsx +2 -1
  75. package/src/components/form-modal/field-row.tsx +2 -2
  76. package/src/components/index.ts +2 -2
  77. package/src/components/layout/detached-pane-shell.tsx +6 -3
  78. package/src/components/layout/floating-pane.tsx +6 -0
  79. package/src/components/layout/header.tsx +24 -7
  80. package/src/components/layout/missing-pane.tsx +2 -2
  81. package/src/components/layout/pane/content.tsx +23 -10
  82. package/src/components/layout/pane/error-boundary.tsx +103 -0
  83. package/src/components/layout/pane/footer/registration.tsx +68 -23
  84. package/src/components/layout/pane/header.tsx +61 -28
  85. package/src/components/layout/pane/index.tsx +6 -0
  86. package/src/components/layout/pane/title.ts +31 -7
  87. package/src/components/layout/shell/drag/index.ts +6 -5
  88. package/src/components/layout/shell/drag/runtime.ts +3 -0
  89. package/src/components/layout/shell/index.tsx +6 -0
  90. package/src/components/layout/shell/menu.ts +2 -1
  91. package/src/components/layout/shell/pane/actions.ts +2 -1
  92. package/src/components/layout/shell/pane/layers.tsx +29 -10
  93. package/src/components/layout/shell/terminal-pointer-runtime.ts +24 -3
  94. package/src/components/layout/shell/ticker-link-menu.ts +23 -9
  95. package/src/components/metric-treemap/heat-surface.tsx +745 -0
  96. package/src/components/metric-treemap/heat-tiles.ts +228 -0
  97. package/src/components/metric-treemap/index.tsx +2 -0
  98. package/src/components/metric-treemap/layout.ts +8 -0
  99. package/src/components/metric-treemap/scene.ts +432 -0
  100. package/src/components/onboarding/onboarding-keyboard.ts +311 -0
  101. package/src/components/onboarding/onboarding-wizard.tsx +101 -788
  102. package/src/components/onboarding/use-onboarding-broker-form.ts +263 -0
  103. package/src/components/onboarding/use-onboarding-progress.ts +298 -0
  104. package/src/components/onboarding/use-onboarding-upgrade.ts +83 -0
  105. package/src/components/pane-settings-dialog/field-dialogs.tsx +1 -0
  106. package/src/components/ticker/list-table-view.tsx +13 -1
  107. package/src/components/toggle-list.tsx +38 -12
  108. package/src/components/ui/country-flag-art.tsx +449 -0
  109. package/src/components/ui/country-flag.tsx +41 -0
  110. package/src/components/ui/data-table/types.ts +13 -0
  111. package/src/components/ui/fields.tsx +8 -0
  112. package/src/components/ui/icon.tsx +2 -0
  113. package/src/components/ui/index.ts +4 -0
  114. package/src/components/ui/multi-select/dialog.tsx +108 -22
  115. package/src/components/ui/range-track.tsx +53 -0
  116. package/src/components/ui/status.tsx +8 -2
  117. package/src/components/ui/tabs.tsx +11 -4
  118. package/src/components/ui/text-prompt-dialog.tsx +4 -2
  119. package/src/core/state/app/types.ts +10 -1
  120. package/src/data/config/store/normalize.ts +17 -1
  121. package/src/i18n/es.ts +24 -4
  122. package/src/i18n/ja.ts +24 -4
  123. package/src/i18n/ko.ts +24 -4
  124. package/src/i18n/zh-cn.ts +24 -4
  125. package/src/i18n/zh-tw.ts +24 -4
  126. package/src/layout/ticker-navigation.ts +28 -2
  127. package/src/market-data/coordinator/chart.ts +1 -1
  128. package/src/market-data/coordinator/quotes.ts +23 -4
  129. package/src/market-data/fx-closes.ts +72 -0
  130. package/src/market-data/market/freshness.ts +78 -6
  131. package/src/market-data/market/session-close-note.ts +57 -0
  132. package/src/market-data/market/status.ts +151 -0
  133. package/src/market-data/published-apac-sessions.ts +66 -0
  134. package/src/market-data/quotes/contributions.ts +8 -0
  135. package/src/market-data/quotes/freshness.ts +36 -0
  136. package/src/market-data/quotes/resolution.ts +24 -8
  137. package/src/market-data/quotes/screener-live-quotes.ts +49 -4
  138. package/src/market-data/quotes/time.ts +16 -0
  139. package/src/plugins/builtin/account-management/pane.tsx +4 -0
  140. package/src/plugins/builtin/alerts/cli.ts +10 -5
  141. package/src/plugins/builtin/alerts/index.tsx +1 -0
  142. package/src/plugins/builtin/analytics/metrics.ts +8 -3
  143. package/src/plugins/builtin/analytics/risk-client.ts +330 -79
  144. package/src/plugins/builtin/analytics/risk-fx.ts +102 -0
  145. package/src/plugins/builtin/analytics/risk-headless.ts +61 -49
  146. package/src/plugins/builtin/analytics/risk-math.ts +33 -13
  147. package/src/plugins/builtin/analytics/risk-model.ts +282 -64
  148. package/src/plugins/builtin/analytics/risk-pane.tsx +62 -30
  149. package/src/plugins/builtin/analytics/risk-test-data.ts +206 -0
  150. package/src/plugins/builtin/attention/headless.ts +6 -4
  151. package/src/plugins/builtin/attention/index.tsx +1 -1
  152. package/src/plugins/builtin/attention/pane.tsx +1 -1
  153. package/src/plugins/builtin/awards/headless.ts +1 -0
  154. package/src/plugins/builtin/awards/pane.tsx +1 -1
  155. package/src/plugins/builtin/backtest/headless.ts +1 -0
  156. package/src/plugins/builtin/bond-calculator/headless.ts +1 -0
  157. package/src/plugins/builtin/buildout/cells.tsx +15 -12
  158. package/src/plugins/builtin/buildout/detail/company.tsx +3 -3
  159. package/src/plugins/builtin/buildout/detail/index.tsx +0 -1
  160. package/src/plugins/builtin/buildout/detail/intel.tsx +6 -6
  161. package/src/plugins/builtin/buildout/detail/site.tsx +4 -7
  162. package/src/plugins/builtin/buildout/detail/ui.tsx +0 -19
  163. package/src/plugins/builtin/buildout/index.tsx +1 -0
  164. package/src/plugins/builtin/catalysts/headless.ts +3 -1
  165. package/src/plugins/builtin/catalysts/index.tsx +2 -2
  166. package/src/plugins/builtin/catalysts/pane.tsx +3 -1
  167. package/src/plugins/builtin/cds/headless.ts +2 -0
  168. package/src/plugins/builtin/cds/index.tsx +1 -0
  169. package/src/plugins/builtin/central-bank-rates/headless.ts +1 -0
  170. package/src/plugins/builtin/chart-composer/headless.ts +38 -3
  171. package/src/plugins/builtin/chart-composer/index.tsx +3 -1
  172. package/src/plugins/builtin/chart-composer/series-expression.ts +18 -2
  173. package/src/plugins/builtin/chat/channels.ts +19 -3
  174. package/src/plugins/builtin/chat/content/composer-runtime.ts +28 -13
  175. package/src/plugins/builtin/chat/content/footer.tsx +15 -6
  176. package/src/plugins/builtin/chat/content/index.tsx +120 -21
  177. package/src/plugins/builtin/chat/content/new-dm-dialog.tsx +261 -113
  178. package/src/plugins/builtin/chat/content/transcript.tsx +20 -2
  179. package/src/plugins/builtin/chat/direct-messages.ts +200 -0
  180. package/src/plugins/builtin/chat/index.tsx +1 -0
  181. package/src/plugins/builtin/chat/message/desktop.tsx +3 -0
  182. package/src/plugins/builtin/chat/message/header.tsx +16 -6
  183. package/src/plugins/builtin/chat/message/inline-tokens.tsx +72 -32
  184. package/src/plugins/builtin/chat/message/profile-popover.tsx +96 -12
  185. package/src/plugins/builtin/chat/message/terminal.tsx +3 -0
  186. package/src/plugins/builtin/chat/message/types.ts +14 -2
  187. package/src/plugins/builtin/chat/profile-popover.ts +18 -13
  188. package/src/plugins/builtin/clinical-trials/index.tsx +1 -0
  189. package/src/plugins/builtin/cloud/askg/executor.ts +2 -1
  190. package/src/plugins/builtin/cloud/plugin.tsx +1 -0
  191. package/src/plugins/builtin/cloud/team/module.tsx +1 -0
  192. package/src/plugins/builtin/cloud/thesis/module.tsx +1 -0
  193. package/src/plugins/builtin/cloud-tweets/registration.ts +1 -0
  194. package/src/plugins/builtin/comment-letters/index.tsx +1 -0
  195. package/src/plugins/builtin/company-attention/headless.ts +5 -1
  196. package/src/plugins/builtin/company-attention/pane.tsx +1 -1
  197. package/src/plugins/builtin/company-kpis/headless.ts +1 -0
  198. package/src/plugins/builtin/congress-trades/headless.ts +1 -0
  199. package/src/plugins/builtin/correlation/compute.ts +59 -16
  200. package/src/plugins/builtin/correlation/geo.ts +34 -0
  201. package/src/plugins/builtin/correlation/headless-schema.ts +4 -1
  202. package/src/plugins/builtin/correlation/headless.ts +42 -8
  203. package/src/plugins/builtin/correlation/history.ts +2 -0
  204. package/src/plugins/builtin/correlation/index.tsx +68 -14
  205. package/src/plugins/builtin/correlation/matrix/model.ts +17 -2
  206. package/src/plugins/builtin/correlation/matrix/selection.ts +5 -3
  207. package/src/plugins/builtin/correlation/relationship/model.ts +1 -1
  208. package/src/plugins/builtin/correlation/relationship/pane.tsx +4 -2
  209. package/src/plugins/builtin/correlation/relationship/view-model.ts +16 -1
  210. package/src/plugins/builtin/correlation/settings.ts +1 -1
  211. package/src/plugins/builtin/cot/headless.ts +6 -3
  212. package/src/plugins/builtin/cot/index.tsx +3 -3
  213. package/src/plugins/builtin/cot/model.ts +36 -3
  214. package/src/plugins/builtin/cpi/headless.ts +4 -0
  215. package/src/plugins/builtin/credit-boards/headless.ts +2 -0
  216. package/src/plugins/builtin/credit-conditions/headless.ts +1 -0
  217. package/src/plugins/builtin/credit-documents/gauge.tsx +5 -8
  218. package/src/plugins/builtin/credit-documents/headless.ts +2 -0
  219. package/src/plugins/builtin/crypto-board/headless.ts +3 -0
  220. package/src/plugins/builtin/custom-view/loader.ts +1 -1
  221. package/src/plugins/builtin/debt-maturities/headless.ts +4 -0
  222. package/src/plugins/builtin/debt-maturities/wall-bar.tsx +14 -41
  223. package/src/plugins/builtin/dividend-yield/client.ts +4 -2
  224. package/src/plugins/builtin/dividend-yield/headless.ts +1 -0
  225. package/src/plugins/builtin/doe/headless.ts +7 -0
  226. package/src/plugins/builtin/doe/range-bar.tsx +7 -37
  227. package/src/plugins/builtin/earnings/client.ts +2 -2
  228. package/src/plugins/builtin/earnings/headless.ts +5 -0
  229. package/src/plugins/builtin/earnings-calls/headless.ts +1 -0
  230. package/src/plugins/builtin/earnings-calls/index.tsx +1 -0
  231. package/src/plugins/builtin/earnings-ripple/client.ts +91 -18
  232. package/src/plugins/builtin/earnings-ripple/headless.ts +28 -8
  233. package/src/plugins/builtin/earnings-ripple/index.tsx +2 -2
  234. package/src/plugins/builtin/earnings-ripple/model.ts +97 -7
  235. package/src/plugins/builtin/earnings-ripple/pane.tsx +148 -23
  236. package/src/plugins/builtin/econ/index.tsx +1 -0
  237. package/src/plugins/builtin/econ-statistics/headless.ts +2 -0
  238. package/src/plugins/builtin/equity-screener/headless.ts +2 -0
  239. package/src/plugins/builtin/estimate-revisions/headless.ts +1 -0
  240. package/src/plugins/builtin/executives/index.tsx +1 -0
  241. package/src/plugins/builtin/exposure/headless.ts +3 -1
  242. package/src/plugins/builtin/fear-greed/headless.ts +2 -0
  243. package/src/plugins/builtin/filing-events/index.tsx +1 -0
  244. package/src/plugins/builtin/futures-curve/client.ts +12 -3
  245. package/src/plugins/builtin/futures-curve/headless.ts +39 -10
  246. package/src/plugins/builtin/futures-curve/index.tsx +3 -3
  247. package/src/plugins/builtin/futures-curve/model.ts +188 -4
  248. package/src/plugins/builtin/futures-curve/pane.tsx +51 -9
  249. package/src/plugins/builtin/fx-matrix/direction.ts +81 -0
  250. package/src/plugins/builtin/fx-matrix/index.tsx +71 -33
  251. package/src/plugins/builtin/fx-matrix/live-legs.ts +17 -0
  252. package/src/plugins/builtin/fx-matrix/pairs.ts +68 -14
  253. package/src/plugins/builtin/fx-matrix/settings.ts +62 -0
  254. package/src/plugins/builtin/gpu/headless.ts +7 -3
  255. package/src/plugins/builtin/gpu/ladder.tsx +26 -30
  256. package/src/plugins/builtin/gpu/model.ts +27 -1
  257. package/src/plugins/builtin/holders/beneficial-client.ts +209 -0
  258. package/src/plugins/builtin/holders/beneficial-model.ts +279 -0
  259. package/src/plugins/builtin/holders/beneficial-report.ts +126 -0
  260. package/src/plugins/builtin/holders/beneficial-view.tsx +241 -0
  261. package/src/plugins/builtin/holders/headless.ts +139 -5
  262. package/src/plugins/builtin/holders/index.tsx +10 -3
  263. package/src/plugins/builtin/holders/pane.tsx +20 -3
  264. package/src/plugins/builtin/holders/report-header.ts +95 -0
  265. package/src/plugins/builtin/holders/table-model.ts +20 -5
  266. package/src/plugins/builtin/holders/thirteenf-match.ts +29 -1
  267. package/src/plugins/builtin/holders/types.ts +2 -1
  268. package/src/plugins/builtin/insider/headless.ts +2 -0
  269. package/src/plugins/builtin/ipo-calendar/headless.ts +1 -0
  270. package/src/plugins/builtin/iv-history/headless.ts +4 -1
  271. package/src/plugins/builtin/jobs/headless.ts +1 -0
  272. package/src/plugins/builtin/jobs/index.tsx +1 -0
  273. package/src/plugins/builtin/jobs/share-bars.tsx +5 -28
  274. package/src/plugins/builtin/kelly-sizer/index.tsx +1 -0
  275. package/src/plugins/builtin/macro-day/headless.ts +2 -0
  276. package/src/plugins/builtin/market-halts/index.tsx +1 -0
  277. package/src/plugins/builtin/market-heatmap/data.ts +30 -2
  278. package/src/plugins/builtin/market-heatmap/headless.ts +135 -0
  279. package/src/plugins/builtin/market-heatmap/index.tsx +245 -81
  280. package/src/plugins/builtin/market-heatmap/live.ts +88 -0
  281. package/src/plugins/builtin/market-heatmap/model.ts +146 -0
  282. package/src/plugins/builtin/market-heatmap/portfolio.ts +50 -11
  283. package/src/plugins/builtin/market-movers/client.ts +3 -2
  284. package/src/plugins/builtin/market-movers/headless.ts +10 -1
  285. package/src/plugins/builtin/market-movers/screener.ts +18 -5
  286. package/src/plugins/builtin/market-valuation/headless.ts +2 -0
  287. package/src/plugins/builtin/members/client.ts +53 -0
  288. package/src/plugins/builtin/members/headless.ts +35 -0
  289. package/src/plugins/builtin/members/index.tsx +20 -0
  290. package/src/plugins/builtin/members/model.ts +68 -0
  291. package/src/plugins/builtin/members/pane.tsx +175 -0
  292. package/src/plugins/builtin/mna/distress/headless.ts +1 -0
  293. package/src/plugins/builtin/mna/headless.ts +1 -0
  294. package/src/plugins/builtin/mna/index.tsx +2 -1
  295. package/src/plugins/builtin/mna/pane.tsx +5 -2
  296. package/src/plugins/builtin/money-markets/headless.ts +1 -0
  297. package/src/plugins/builtin/news/headless.ts +2 -0
  298. package/src/plugins/builtin/news/wire/index.tsx +8 -1
  299. package/src/plugins/builtin/notes/cli.ts +14 -6
  300. package/src/plugins/builtin/notes/index.tsx +1 -0
  301. package/src/plugins/builtin/openfda/index.tsx +1 -0
  302. package/src/plugins/builtin/options/index.tsx +2 -1
  303. package/src/plugins/builtin/options-calculator/headless.ts +2 -0
  304. package/src/plugins/builtin/options-positioning/headless.ts +3 -0
  305. package/src/plugins/builtin/options-scenario/headless.ts +5 -0
  306. package/src/plugins/builtin/pe-band/client.ts +74 -2
  307. package/src/plugins/builtin/pe-band/headless.ts +26 -8
  308. package/src/plugins/builtin/pe-band/model.ts +102 -22
  309. package/src/plugins/builtin/pe-band/pane.tsx +34 -16
  310. package/src/plugins/builtin/pe-band/report-dates.ts +78 -0
  311. package/src/plugins/builtin/perps/client.ts +66 -5
  312. package/src/plugins/builtin/perps/equity-identity.ts +16 -0
  313. package/src/plugins/builtin/perps/equity-row.tsx +6 -4
  314. package/src/plugins/builtin/perps/headless.ts +144 -16
  315. package/src/plugins/builtin/perps/index.tsx +6 -6
  316. package/src/plugins/builtin/perps/model.ts +189 -12
  317. package/src/plugins/builtin/perps/pane.tsx +248 -47
  318. package/src/plugins/builtin/plugin-marketplace/activation.ts +19 -0
  319. package/src/plugins/builtin/plugin-marketplace/pane.tsx +2 -2
  320. package/src/plugins/builtin/plugin-marketplace/store.ts +2 -0
  321. package/src/plugins/builtin/portfolio-list/allocation.ts +245 -0
  322. package/src/plugins/builtin/portfolio-list/cached-account.ts +33 -0
  323. package/src/plugins/builtin/portfolio-list/cell-version.ts +19 -1
  324. package/src/plugins/builtin/portfolio-list/cli/portfolio-command.ts +328 -29
  325. package/src/plugins/builtin/portfolio-list/cli/render.ts +230 -39
  326. package/src/plugins/builtin/portfolio-list/cli/shared.ts +67 -2
  327. package/src/plugins/builtin/portfolio-list/cli/watchlist-command.ts +35 -31
  328. package/src/plugins/builtin/portfolio-list/column-values.ts +124 -47
  329. package/src/plugins/builtin/portfolio-list/headless.ts +98 -16
  330. package/src/plugins/builtin/portfolio-list/index.tsx +14 -3
  331. package/src/plugins/builtin/portfolio-list/live-valuation.ts +7 -5
  332. package/src/plugins/builtin/portfolio-list/mutations.ts +55 -1
  333. package/src/plugins/builtin/portfolio-list/pane/data.ts +6 -0
  334. package/src/plugins/builtin/portfolio-list/pane/index.tsx +47 -13
  335. package/src/plugins/builtin/portfolio-list/quick-add/index.tsx +43 -2
  336. package/src/plugins/builtin/portfolio-list/quick-add/resolution.ts +48 -5
  337. package/src/plugins/builtin/portfolio-list/settings.ts +33 -2
  338. package/src/plugins/builtin/portfolio-list/summary/index.tsx +24 -1
  339. package/src/plugins/builtin/portfolio-list/summary/totals.ts +26 -7
  340. package/src/plugins/builtin/power/headless.ts +3 -1
  341. package/src/plugins/builtin/rate-path/headless.ts +2 -0
  342. package/src/plugins/builtin/realized-vol/headless.ts +2 -0
  343. package/src/plugins/builtin/relative-rotation/headless.ts +2 -0
  344. package/src/plugins/builtin/research/analyst-headless.ts +3 -0
  345. package/src/plugins/builtin/research/events-headless.ts +2 -0
  346. package/src/plugins/builtin/research/headless.ts +2 -0
  347. package/src/plugins/builtin/research/index.tsx +1 -0
  348. package/src/plugins/builtin/research/relative-valuation-headless.ts +10 -5
  349. package/src/plugins/builtin/research/relative-valuation-model.ts +11 -3
  350. package/src/plugins/builtin/research/relative-valuation-pane.tsx +3 -3
  351. package/src/plugins/builtin/research-search/index.tsx +1 -0
  352. package/src/plugins/builtin/revenue-breakdown/headless.ts +2 -0
  353. package/src/plugins/builtin/reverse-dcf/headless.ts +2 -0
  354. package/src/plugins/builtin/risk-factors/headless.ts +2 -0
  355. package/src/plugins/builtin/scanner/flow-history.ts +2 -13
  356. package/src/plugins/builtin/scanner/headless.ts +14 -0
  357. package/src/plugins/builtin/scanner/hilo-bars.tsx +12 -70
  358. package/src/plugins/builtin/scanner/hilo-model.ts +0 -18
  359. package/src/plugins/builtin/seasonality/headless.ts +2 -0
  360. package/src/plugins/builtin/sec/command-bar-search.ts +14 -4
  361. package/src/plugins/builtin/sec/filing-content.ts +42 -17
  362. package/src/plugins/builtin/sec/forms.ts +12 -0
  363. package/src/plugins/builtin/sec/headless.ts +2 -0
  364. package/src/plugins/builtin/sectors/client.ts +1 -0
  365. package/src/plugins/builtin/sectors/headless.ts +9 -1
  366. package/src/plugins/builtin/sectors/move-bar.tsx +10 -32
  367. package/src/plugins/builtin/sectors/sector-model.ts +2 -0
  368. package/src/plugins/builtin/shared/crypto-pair.ts +14 -0
  369. package/src/plugins/builtin/shared/locked-rows.tsx +1 -1
  370. package/src/plugins/builtin/shared/report-freshness.ts +57 -0
  371. package/src/plugins/builtin/shared/research-cells.tsx +4 -9
  372. package/src/plugins/builtin/short-interest/headless.ts +2 -0
  373. package/src/plugins/builtin/short-interest/watch-headless.ts +1 -0
  374. package/src/plugins/builtin/short-volume/headless.ts +1 -0
  375. package/src/plugins/builtin/social-mentions/headless.ts +1 -0
  376. package/src/plugins/builtin/social-mentions/index.tsx +1 -1
  377. package/src/plugins/builtin/supply-chain/headless.ts +7 -1
  378. package/src/plugins/builtin/supply-chain/index.tsx +10 -1
  379. package/src/plugins/builtin/supply-chain/model.ts +27 -2
  380. package/src/plugins/builtin/supply-chain/pane.tsx +71 -32
  381. package/src/plugins/builtin/themes/headless.ts +3 -0
  382. package/src/plugins/builtin/thirteenf/headless.ts +110 -25
  383. package/src/plugins/builtin/thirteenf/index.tsx +2 -1
  384. package/src/plugins/builtin/thirteenf/report-notes.ts +149 -0
  385. package/src/plugins/builtin/ticker-detail/headless.ts +7 -1
  386. package/src/plugins/builtin/ticker-detail/index.tsx +1 -0
  387. package/src/plugins/builtin/ticker-detail/overview/components.tsx +5 -60
  388. package/src/plugins/builtin/ticker-detail/overview/model.ts +9 -2
  389. package/src/plugins/builtin/ticker-detail/overview/pane.tsx +1 -1
  390. package/src/plugins/builtin/ticker-detail/overview-tab.tsx +26 -26
  391. package/src/plugins/builtin/ticker-detail/pane.tsx +1 -1
  392. package/src/plugins/builtin/ticker-detail/quote-footer.ts +7 -1
  393. package/src/plugins/builtin/ticker-detail/quote-monitor/card.tsx +20 -4
  394. package/src/plugins/builtin/ticker-detail/quote-monitor/index.tsx +2 -2
  395. package/src/plugins/builtin/time-sales/headless.ts +5 -1
  396. package/src/plugins/builtin/treasury-auctions/headless.ts +1 -0
  397. package/src/plugins/builtin/vol-surface/index.tsx +1 -1
  398. package/src/plugins/builtin/volatility/headless.ts +6 -1
  399. package/src/plugins/builtin/world-indices/headless.ts +2 -0
  400. package/src/plugins/builtin/world-venue-map/basemap-layer.tsx +157 -0
  401. package/src/plugins/builtin/world-venue-map/basemap.ts +214 -0
  402. package/src/plugins/builtin/world-venue-map/client.ts +45 -0
  403. package/src/plugins/builtin/world-venue-map/entity-detail.tsx +147 -0
  404. package/src/plugins/builtin/world-venue-map/entity-table.ts +59 -0
  405. package/src/plugins/builtin/world-venue-map/evidence.ts +77 -0
  406. package/src/plugins/builtin/world-venue-map/feed.ts +293 -0
  407. package/src/plugins/builtin/world-venue-map/geo-draw.tsx +248 -0
  408. package/src/plugins/builtin/world-venue-map/geo-series.ts +142 -0
  409. package/src/plugins/builtin/world-venue-map/geo-svg.tsx +447 -0
  410. package/src/plugins/builtin/world-venue-map/headless.ts +146 -0
  411. package/src/plugins/builtin/world-venue-map/ids.ts +1 -0
  412. package/src/plugins/builtin/world-venue-map/index.ts +67 -4
  413. package/src/plugins/builtin/world-venue-map/layered-pane.tsx +552 -0
  414. package/src/plugins/builtin/world-venue-map/layers.ts +348 -0
  415. package/src/plugins/builtin/world-venue-map/map-symbols.ts +220 -0
  416. package/src/plugins/builtin/world-venue-map/map.tsx +381 -45
  417. package/src/plugins/builtin/world-venue-map/model.ts +7 -4
  418. package/src/plugins/builtin/world-venue-map/natural-earth/index.chunk.ts +199 -0
  419. package/src/plugins/builtin/world-venue-map/natural-earth/tiles/e000n00.chunk.ts +4 -0
  420. package/src/plugins/builtin/world-venue-map/natural-earth/tiles/e000n15.chunk.ts +4 -0
  421. package/src/plugins/builtin/world-venue-map/natural-earth/tiles/e000n30.chunk.ts +4 -0
  422. package/src/plugins/builtin/world-venue-map/natural-earth/tiles/e000n45.chunk.ts +4 -0
  423. package/src/plugins/builtin/world-venue-map/natural-earth/tiles/e000n60.chunk.ts +4 -0
  424. package/src/plugins/builtin/world-venue-map/natural-earth/tiles/e000n75.chunk.ts +4 -0
  425. package/src/plugins/builtin/world-venue-map/natural-earth/tiles/e000s15.chunk.ts +4 -0
  426. package/src/plugins/builtin/world-venue-map/natural-earth/tiles/e000s30.chunk.ts +4 -0
  427. package/src/plugins/builtin/world-venue-map/natural-earth/tiles/e000s60.chunk.ts +4 -0
  428. package/src/plugins/builtin/world-venue-map/natural-earth/tiles/e015n00.chunk.ts +4 -0
  429. package/src/plugins/builtin/world-venue-map/natural-earth/tiles/e015n15.chunk.ts +4 -0
  430. package/src/plugins/builtin/world-venue-map/natural-earth/tiles/e015n30.chunk.ts +4 -0
  431. package/src/plugins/builtin/world-venue-map/natural-earth/tiles/e015n45.chunk.ts +4 -0
  432. package/src/plugins/builtin/world-venue-map/natural-earth/tiles/e015n60.chunk.ts +4 -0
  433. package/src/plugins/builtin/world-venue-map/natural-earth/tiles/e015n75.chunk.ts +4 -0
  434. package/src/plugins/builtin/world-venue-map/natural-earth/tiles/e015s15.chunk.ts +4 -0
  435. package/src/plugins/builtin/world-venue-map/natural-earth/tiles/e015s30.chunk.ts +4 -0
  436. package/src/plugins/builtin/world-venue-map/natural-earth/tiles/e015s45.chunk.ts +4 -0
  437. package/src/plugins/builtin/world-venue-map/natural-earth/tiles/e030n00.chunk.ts +4 -0
  438. package/src/plugins/builtin/world-venue-map/natural-earth/tiles/e030n15.chunk.ts +4 -0
  439. package/src/plugins/builtin/world-venue-map/natural-earth/tiles/e030n30.chunk.ts +4 -0
  440. package/src/plugins/builtin/world-venue-map/natural-earth/tiles/e030n45.chunk.ts +4 -0
  441. package/src/plugins/builtin/world-venue-map/natural-earth/tiles/e030n60.chunk.ts +4 -0
  442. package/src/plugins/builtin/world-venue-map/natural-earth/tiles/e030n75.chunk.ts +4 -0
  443. package/src/plugins/builtin/world-venue-map/natural-earth/tiles/e030s15.chunk.ts +4 -0
  444. package/src/plugins/builtin/world-venue-map/natural-earth/tiles/e030s30.chunk.ts +4 -0
  445. package/src/plugins/builtin/world-venue-map/natural-earth/tiles/e030s45.chunk.ts +4 -0
  446. package/src/plugins/builtin/world-venue-map/natural-earth/tiles/e030s60.chunk.ts +4 -0
  447. package/src/plugins/builtin/world-venue-map/natural-earth/tiles/e045n00.chunk.ts +4 -0
  448. package/src/plugins/builtin/world-venue-map/natural-earth/tiles/e045n15.chunk.ts +4 -0
  449. package/src/plugins/builtin/world-venue-map/natural-earth/tiles/e045n30.chunk.ts +4 -0
  450. package/src/plugins/builtin/world-venue-map/natural-earth/tiles/e045n45.chunk.ts +4 -0
  451. package/src/plugins/builtin/world-venue-map/natural-earth/tiles/e045n60.chunk.ts +4 -0
  452. package/src/plugins/builtin/world-venue-map/natural-earth/tiles/e045n75.chunk.ts +4 -0
  453. package/src/plugins/builtin/world-venue-map/natural-earth/tiles/e045s15.chunk.ts +4 -0
  454. package/src/plugins/builtin/world-venue-map/natural-earth/tiles/e045s30.chunk.ts +4 -0
  455. package/src/plugins/builtin/world-venue-map/natural-earth/tiles/e045s60.chunk.ts +4 -0
  456. package/src/plugins/builtin/world-venue-map/natural-earth/tiles/e060n00.chunk.ts +4 -0
  457. package/src/plugins/builtin/world-venue-map/natural-earth/tiles/e060n15.chunk.ts +4 -0
  458. package/src/plugins/builtin/world-venue-map/natural-earth/tiles/e060n30.chunk.ts +4 -0
  459. package/src/plugins/builtin/world-venue-map/natural-earth/tiles/e060n45.chunk.ts +4 -0
  460. package/src/plugins/builtin/world-venue-map/natural-earth/tiles/e060n60.chunk.ts +4 -0
  461. package/src/plugins/builtin/world-venue-map/natural-earth/tiles/e060n75.chunk.ts +4 -0
  462. package/src/plugins/builtin/world-venue-map/natural-earth/tiles/e060s15.chunk.ts +4 -0
  463. package/src/plugins/builtin/world-venue-map/natural-earth/tiles/e060s30.chunk.ts +4 -0
  464. package/src/plugins/builtin/world-venue-map/natural-earth/tiles/e060s60.chunk.ts +4 -0
  465. package/src/plugins/builtin/world-venue-map/natural-earth/tiles/e075n00.chunk.ts +4 -0
  466. package/src/plugins/builtin/world-venue-map/natural-earth/tiles/e075n15.chunk.ts +4 -0
  467. package/src/plugins/builtin/world-venue-map/natural-earth/tiles/e075n30.chunk.ts +4 -0
  468. package/src/plugins/builtin/world-venue-map/natural-earth/tiles/e075n45.chunk.ts +4 -0
  469. package/src/plugins/builtin/world-venue-map/natural-earth/tiles/e075n60.chunk.ts +4 -0
  470. package/src/plugins/builtin/world-venue-map/natural-earth/tiles/e075n75.chunk.ts +4 -0
  471. package/src/plugins/builtin/world-venue-map/natural-earth/tiles/e075s45.chunk.ts +4 -0
  472. package/src/plugins/builtin/world-venue-map/natural-earth/tiles/e090n00.chunk.ts +4 -0
  473. package/src/plugins/builtin/world-venue-map/natural-earth/tiles/e090n15.chunk.ts +4 -0
  474. package/src/plugins/builtin/world-venue-map/natural-earth/tiles/e090n30.chunk.ts +4 -0
  475. package/src/plugins/builtin/world-venue-map/natural-earth/tiles/e090n45.chunk.ts +4 -0
  476. package/src/plugins/builtin/world-venue-map/natural-earth/tiles/e090n60.chunk.ts +4 -0
  477. package/src/plugins/builtin/world-venue-map/natural-earth/tiles/e090n75.chunk.ts +4 -0
  478. package/src/plugins/builtin/world-venue-map/natural-earth/tiles/e090s15.chunk.ts +4 -0
  479. package/src/plugins/builtin/world-venue-map/natural-earth/tiles/e105n00.chunk.ts +4 -0
  480. package/src/plugins/builtin/world-venue-map/natural-earth/tiles/e105n15.chunk.ts +4 -0
  481. package/src/plugins/builtin/world-venue-map/natural-earth/tiles/e105n30.chunk.ts +4 -0
  482. package/src/plugins/builtin/world-venue-map/natural-earth/tiles/e105n45.chunk.ts +4 -0
  483. package/src/plugins/builtin/world-venue-map/natural-earth/tiles/e105n60.chunk.ts +4 -0
  484. package/src/plugins/builtin/world-venue-map/natural-earth/tiles/e105n75.chunk.ts +4 -0
  485. package/src/plugins/builtin/world-venue-map/natural-earth/tiles/e105s15.chunk.ts +4 -0
  486. package/src/plugins/builtin/world-venue-map/natural-earth/tiles/e105s30.chunk.ts +4 -0
  487. package/src/plugins/builtin/world-venue-map/natural-earth/tiles/e105s45.chunk.ts +4 -0
  488. package/src/plugins/builtin/world-venue-map/natural-earth/tiles/e120n00.chunk.ts +4 -0
  489. package/src/plugins/builtin/world-venue-map/natural-earth/tiles/e120n15.chunk.ts +4 -0
  490. package/src/plugins/builtin/world-venue-map/natural-earth/tiles/e120n30.chunk.ts +4 -0
  491. package/src/plugins/builtin/world-venue-map/natural-earth/tiles/e120n45.chunk.ts +4 -0
  492. package/src/plugins/builtin/world-venue-map/natural-earth/tiles/e120n60.chunk.ts +4 -0
  493. package/src/plugins/builtin/world-venue-map/natural-earth/tiles/e120s15.chunk.ts +4 -0
  494. package/src/plugins/builtin/world-venue-map/natural-earth/tiles/e120s30.chunk.ts +4 -0
  495. package/src/plugins/builtin/world-venue-map/natural-earth/tiles/e120s45.chunk.ts +4 -0
  496. package/src/plugins/builtin/world-venue-map/natural-earth/tiles/e135n00.chunk.ts +4 -0
  497. package/src/plugins/builtin/world-venue-map/natural-earth/tiles/e135n15.chunk.ts +4 -0
  498. package/src/plugins/builtin/world-venue-map/natural-earth/tiles/e135n30.chunk.ts +4 -0
  499. package/src/plugins/builtin/world-venue-map/natural-earth/tiles/e135n45.chunk.ts +4 -0
  500. package/src/plugins/builtin/world-venue-map/natural-earth/tiles/e135n60.chunk.ts +4 -0
  501. package/src/plugins/builtin/world-venue-map/natural-earth/tiles/e135n75.chunk.ts +4 -0
  502. package/src/plugins/builtin/world-venue-map/natural-earth/tiles/e135s15.chunk.ts +4 -0
  503. package/src/plugins/builtin/world-venue-map/natural-earth/tiles/e135s30.chunk.ts +4 -0
  504. package/src/plugins/builtin/world-venue-map/natural-earth/tiles/e135s45.chunk.ts +4 -0
  505. package/src/plugins/builtin/world-venue-map/natural-earth/tiles/e150n00.chunk.ts +4 -0
  506. package/src/plugins/builtin/world-venue-map/natural-earth/tiles/e150n15.chunk.ts +4 -0
  507. package/src/plugins/builtin/world-venue-map/natural-earth/tiles/e150n45.chunk.ts +4 -0
  508. package/src/plugins/builtin/world-venue-map/natural-earth/tiles/e150n60.chunk.ts +4 -0
  509. package/src/plugins/builtin/world-venue-map/natural-earth/tiles/e150n75.chunk.ts +4 -0
  510. package/src/plugins/builtin/world-venue-map/natural-earth/tiles/e150s15.chunk.ts +4 -0
  511. package/src/plugins/builtin/world-venue-map/natural-earth/tiles/e150s30.chunk.ts +4 -0
  512. package/src/plugins/builtin/world-venue-map/natural-earth/tiles/e150s45.chunk.ts +4 -0
  513. package/src/plugins/builtin/world-venue-map/natural-earth/tiles/e150s60.chunk.ts +4 -0
  514. package/src/plugins/builtin/world-venue-map/natural-earth/tiles/e165n00.chunk.ts +4 -0
  515. package/src/plugins/builtin/world-venue-map/natural-earth/tiles/e165n15.chunk.ts +4 -0
  516. package/src/plugins/builtin/world-venue-map/natural-earth/tiles/e165n45.chunk.ts +4 -0
  517. package/src/plugins/builtin/world-venue-map/natural-earth/tiles/e165n60.chunk.ts +4 -0
  518. package/src/plugins/builtin/world-venue-map/natural-earth/tiles/e165s15.chunk.ts +4 -0
  519. package/src/plugins/builtin/world-venue-map/natural-earth/tiles/e165s30.chunk.ts +4 -0
  520. package/src/plugins/builtin/world-venue-map/natural-earth/tiles/e165s45.chunk.ts +4 -0
  521. package/src/plugins/builtin/world-venue-map/natural-earth/tiles/e165s60.chunk.ts +4 -0
  522. package/src/plugins/builtin/world-venue-map/natural-earth/tiles/w015n00.chunk.ts +4 -0
  523. package/src/plugins/builtin/world-venue-map/natural-earth/tiles/w015n15.chunk.ts +4 -0
  524. package/src/plugins/builtin/world-venue-map/natural-earth/tiles/w015n30.chunk.ts +4 -0
  525. package/src/plugins/builtin/world-venue-map/natural-earth/tiles/w015n45.chunk.ts +4 -0
  526. package/src/plugins/builtin/world-venue-map/natural-earth/tiles/w015n60.chunk.ts +4 -0
  527. package/src/plugins/builtin/world-venue-map/natural-earth/tiles/w015n75.chunk.ts +4 -0
  528. package/src/plugins/builtin/world-venue-map/natural-earth/tiles/w015s15.chunk.ts +4 -0
  529. package/src/plugins/builtin/world-venue-map/natural-earth/tiles/w015s30.chunk.ts +4 -0
  530. package/src/plugins/builtin/world-venue-map/natural-earth/tiles/w015s45.chunk.ts +4 -0
  531. package/src/plugins/builtin/world-venue-map/natural-earth/tiles/w030n00.chunk.ts +4 -0
  532. package/src/plugins/builtin/world-venue-map/natural-earth/tiles/w030n15.chunk.ts +4 -0
  533. package/src/plugins/builtin/world-venue-map/natural-earth/tiles/w030n30.chunk.ts +4 -0
  534. package/src/plugins/builtin/world-venue-map/natural-earth/tiles/w030n60.chunk.ts +4 -0
  535. package/src/plugins/builtin/world-venue-map/natural-earth/tiles/w030n75.chunk.ts +4 -0
  536. package/src/plugins/builtin/world-venue-map/natural-earth/tiles/w030s30.chunk.ts +4 -0
  537. package/src/plugins/builtin/world-venue-map/natural-earth/tiles/w030s60.chunk.ts +4 -0
  538. package/src/plugins/builtin/world-venue-map/natural-earth/tiles/w045n30.chunk.ts +4 -0
  539. package/src/plugins/builtin/world-venue-map/natural-earth/tiles/w045n45.chunk.ts +4 -0
  540. package/src/plugins/builtin/world-venue-map/natural-earth/tiles/w045n60.chunk.ts +4 -0
  541. package/src/plugins/builtin/world-venue-map/natural-earth/tiles/w045n75.chunk.ts +4 -0
  542. package/src/plugins/builtin/world-venue-map/natural-earth/tiles/w045s15.chunk.ts +4 -0
  543. package/src/plugins/builtin/world-venue-map/natural-earth/tiles/w045s30.chunk.ts +4 -0
  544. package/src/plugins/builtin/world-venue-map/natural-earth/tiles/w045s60.chunk.ts +4 -0
  545. package/src/plugins/builtin/world-venue-map/natural-earth/tiles/w060n00.chunk.ts +4 -0
  546. package/src/plugins/builtin/world-venue-map/natural-earth/tiles/w060n30.chunk.ts +4 -0
  547. package/src/plugins/builtin/world-venue-map/natural-earth/tiles/w060n45.chunk.ts +4 -0
  548. package/src/plugins/builtin/world-venue-map/natural-earth/tiles/w060n60.chunk.ts +4 -0
  549. package/src/plugins/builtin/world-venue-map/natural-earth/tiles/w060n75.chunk.ts +4 -0
  550. package/src/plugins/builtin/world-venue-map/natural-earth/tiles/w060s15.chunk.ts +4 -0
  551. package/src/plugins/builtin/world-venue-map/natural-earth/tiles/w060s30.chunk.ts +4 -0
  552. package/src/plugins/builtin/world-venue-map/natural-earth/tiles/w060s45.chunk.ts +4 -0
  553. package/src/plugins/builtin/world-venue-map/natural-earth/tiles/w060s60.chunk.ts +4 -0
  554. package/src/plugins/builtin/world-venue-map/natural-earth/tiles/w075n00.chunk.ts +4 -0
  555. package/src/plugins/builtin/world-venue-map/natural-earth/tiles/w075n15.chunk.ts +4 -0
  556. package/src/plugins/builtin/world-venue-map/natural-earth/tiles/w075n30.chunk.ts +4 -0
  557. package/src/plugins/builtin/world-venue-map/natural-earth/tiles/w075n45.chunk.ts +4 -0
  558. package/src/plugins/builtin/world-venue-map/natural-earth/tiles/w075n60.chunk.ts +4 -0
  559. package/src/plugins/builtin/world-venue-map/natural-earth/tiles/w075n75.chunk.ts +4 -0
  560. package/src/plugins/builtin/world-venue-map/natural-earth/tiles/w075s15.chunk.ts +4 -0
  561. package/src/plugins/builtin/world-venue-map/natural-earth/tiles/w075s30.chunk.ts +4 -0
  562. package/src/plugins/builtin/world-venue-map/natural-earth/tiles/w075s45.chunk.ts +4 -0
  563. package/src/plugins/builtin/world-venue-map/natural-earth/tiles/w075s60.chunk.ts +4 -0
  564. package/src/plugins/builtin/world-venue-map/natural-earth/tiles/w090n00.chunk.ts +4 -0
  565. package/src/plugins/builtin/world-venue-map/natural-earth/tiles/w090n15.chunk.ts +4 -0
  566. package/src/plugins/builtin/world-venue-map/natural-earth/tiles/w090n30.chunk.ts +4 -0
  567. package/src/plugins/builtin/world-venue-map/natural-earth/tiles/w090n45.chunk.ts +4 -0
  568. package/src/plugins/builtin/world-venue-map/natural-earth/tiles/w090n60.chunk.ts +4 -0
  569. package/src/plugins/builtin/world-venue-map/natural-earth/tiles/w090n75.chunk.ts +4 -0
  570. package/src/plugins/builtin/world-venue-map/natural-earth/tiles/w090s15.chunk.ts +4 -0
  571. package/src/plugins/builtin/world-venue-map/natural-earth/tiles/w090s30.chunk.ts +4 -0
  572. package/src/plugins/builtin/world-venue-map/natural-earth/tiles/w090s45.chunk.ts +4 -0
  573. package/src/plugins/builtin/world-venue-map/natural-earth/tiles/w090s60.chunk.ts +4 -0
  574. package/src/plugins/builtin/world-venue-map/natural-earth/tiles/w105n00.chunk.ts +4 -0
  575. package/src/plugins/builtin/world-venue-map/natural-earth/tiles/w105n15.chunk.ts +4 -0
  576. package/src/plugins/builtin/world-venue-map/natural-earth/tiles/w105n30.chunk.ts +4 -0
  577. package/src/plugins/builtin/world-venue-map/natural-earth/tiles/w105n45.chunk.ts +4 -0
  578. package/src/plugins/builtin/world-venue-map/natural-earth/tiles/w105n60.chunk.ts +4 -0
  579. package/src/plugins/builtin/world-venue-map/natural-earth/tiles/w105n75.chunk.ts +4 -0
  580. package/src/plugins/builtin/world-venue-map/natural-earth/tiles/w105s15.chunk.ts +4 -0
  581. package/src/plugins/builtin/world-venue-map/natural-earth/tiles/w120n00.chunk.ts +4 -0
  582. package/src/plugins/builtin/world-venue-map/natural-earth/tiles/w120n15.chunk.ts +4 -0
  583. package/src/plugins/builtin/world-venue-map/natural-earth/tiles/w120n30.chunk.ts +4 -0
  584. package/src/plugins/builtin/world-venue-map/natural-earth/tiles/w120n45.chunk.ts +4 -0
  585. package/src/plugins/builtin/world-venue-map/natural-earth/tiles/w120n60.chunk.ts +4 -0
  586. package/src/plugins/builtin/world-venue-map/natural-earth/tiles/w120n75.chunk.ts +4 -0
  587. package/src/plugins/builtin/world-venue-map/natural-earth/tiles/w120s30.chunk.ts +4 -0
  588. package/src/plugins/builtin/world-venue-map/natural-earth/tiles/w135n30.chunk.ts +4 -0
  589. package/src/plugins/builtin/world-venue-map/natural-earth/tiles/w135n45.chunk.ts +4 -0
  590. package/src/plugins/builtin/world-venue-map/natural-earth/tiles/w135n60.chunk.ts +4 -0
  591. package/src/plugins/builtin/world-venue-map/natural-earth/tiles/w135n75.chunk.ts +4 -0
  592. package/src/plugins/builtin/world-venue-map/natural-earth/tiles/w135s30.chunk.ts +4 -0
  593. package/src/plugins/builtin/world-venue-map/natural-earth/tiles/w150n45.chunk.ts +4 -0
  594. package/src/plugins/builtin/world-venue-map/natural-earth/tiles/w150n60.chunk.ts +4 -0
  595. package/src/plugins/builtin/world-venue-map/natural-earth/tiles/w150s15.chunk.ts +4 -0
  596. package/src/plugins/builtin/world-venue-map/natural-earth/tiles/w150s30.chunk.ts +4 -0
  597. package/src/plugins/builtin/world-venue-map/natural-earth/tiles/w165n00.chunk.ts +4 -0
  598. package/src/plugins/builtin/world-venue-map/natural-earth/tiles/w165n15.chunk.ts +4 -0
  599. package/src/plugins/builtin/world-venue-map/natural-earth/tiles/w165n45.chunk.ts +4 -0
  600. package/src/plugins/builtin/world-venue-map/natural-earth/tiles/w165n60.chunk.ts +4 -0
  601. package/src/plugins/builtin/world-venue-map/natural-earth/tiles/w165s15.chunk.ts +4 -0
  602. package/src/plugins/builtin/world-venue-map/natural-earth/tiles/w165s30.chunk.ts +4 -0
  603. package/src/plugins/builtin/world-venue-map/natural-earth/tiles/w180n00.chunk.ts +4 -0
  604. package/src/plugins/builtin/world-venue-map/natural-earth/tiles/w180n15.chunk.ts +4 -0
  605. package/src/plugins/builtin/world-venue-map/natural-earth/tiles/w180n45.chunk.ts +4 -0
  606. package/src/plugins/builtin/world-venue-map/natural-earth/tiles/w180n60.chunk.ts +4 -0
  607. package/src/plugins/builtin/world-venue-map/natural-earth/tiles/w180s15.chunk.ts +4 -0
  608. package/src/plugins/builtin/world-venue-map/natural-earth/tiles/w180s30.chunk.ts +4 -0
  609. package/src/plugins/builtin/world-venue-map/natural-earth/tiles/w180s45.chunk.ts +4 -0
  610. package/src/plugins/builtin/world-venue-map/natural-earth/world-50m.chunk.ts +4 -0
  611. package/src/plugins/builtin/world-venue-map/pane.tsx +28 -43
  612. package/src/plugins/builtin/world-venue-map/use-geo.ts +55 -0
  613. package/src/plugins/builtin/world-venue-map/venue-header.tsx +32 -0
  614. package/src/plugins/builtin/yield-curve/headless.ts +16 -0
  615. package/src/plugins/catalog-browser.ts +2 -0
  616. package/src/plugins/catalog-manifest.ts +1 -0
  617. package/src/plugins/catalog-ui.ts +3 -1
  618. package/src/plugins/catalog.ts +1 -1
  619. package/src/plugins/host-link.ts +33 -1
  620. package/src/plugins/installer.ts +48 -12
  621. package/src/plugins/loader.ts +30 -3
  622. package/src/plugins/manager-node.ts +15 -5
  623. package/src/plugins/registry/index.ts +1 -1
  624. package/src/plugins/registry/pane-settings.ts +26 -7
  625. package/src/public/__snapshots__/public-api.test.ts.snap +2 -0
  626. package/src/renderers/dom/build-assets.ts +81 -3
  627. package/src/renderers/dom/data-table/row.tsx +52 -16
  628. package/src/renderers/dom/desktop/controls.tsx +7 -3
  629. package/src/renderers/dom/desktop/icons.tsx +1 -0
  630. package/src/renderers/dom/desktop/list-view.tsx +35 -10
  631. package/src/renderers/dom/desktop/popover.tsx +73 -14
  632. package/src/renderers/dom/host/box.tsx +69 -26
  633. package/src/renderers/dom/host/input.tsx +14 -3
  634. package/src/renderers/dom/host/tabs.tsx +37 -1
  635. package/src/renderers/dom/styles.css +41 -7
  636. package/src/renderers/electrobun/bun/desktop/backend-requests.ts +11 -6
  637. package/src/renderers/electrobun/bun/desktop/backend.ts +1 -0
  638. package/src/renderers/electrobun/bun/desktop/update.ts +181 -87
  639. package/src/renderers/electrobun/bun/index.ts +73 -6
  640. package/src/renderers/electrobun/bun/window/remembered-frame.ts +122 -0
  641. package/src/renderers/electrobun/shared/protocol.ts +3 -0
  642. package/src/renderers/electrobun/view/backend-rpc.ts +10 -4
  643. package/src/renderers/electrobun/view/cli-pane-shot-entry.tsx +3 -1
  644. package/src/renderers/electrobun/view/main.tsx +7 -1
  645. package/src/renderers/electrobun/view/renderer-window-error.ts +18 -0
  646. package/src/renderers/electrobun/view/rpc-timeout.ts +14 -3
  647. package/src/renderers/electrobun/view/update-host.ts +45 -21
  648. package/src/renderers/opentui/host.tsx +5 -0
  649. package/src/sources/gloomberb-cloud/index.ts +25 -4
  650. package/src/sources/gloomberb-cloud/normalizers.ts +36 -5
  651. package/src/sources/provider-router/cached-routes.ts +4 -1
  652. package/src/sources/provider-router/financials.ts +11 -8
  653. package/src/sources/provider-router/history.ts +15 -10
  654. package/src/sources/sec-registrant.ts +75 -0
  655. package/src/state/app/context/index.tsx +24 -8
  656. package/src/state/hooks/quote-streaming.ts +41 -26
  657. package/src/sync/core-contributors.ts +4 -0
  658. package/src/telemetry/benign-window-error.ts +7 -0
  659. package/src/telemetry/crash-reports-dom.ts +2 -0
  660. package/src/telemetry/crash-reports.ts +4 -1
  661. package/src/test-support/cli-context.ts +10 -2
  662. package/src/test-support/daily-nav.ts +25 -0
  663. package/src/theme/heat-colors.ts +357 -2
  664. package/src/tickers/instrument-kind.ts +34 -7
  665. package/src/tickers/search/asset-classes.ts +24 -9
  666. package/src/tickers/search/index.ts +44 -11
  667. package/src/tickers/search/ranking.ts +23 -3
  668. package/src/time-series/resolve.ts +1 -1
  669. package/src/time-series/use-chart-resolution.ts +1 -1
  670. package/src/types/context-menu.ts +6 -0
  671. package/src/types/data-provider.ts +2 -0
  672. package/src/types/financials.ts +5 -0
  673. package/src/types/headless.ts +79 -2
  674. package/src/types/plugin.ts +38 -6
  675. package/src/types/ticker.ts +15 -0
  676. package/src/ui/context-menu.tsx +1 -0
  677. package/src/ui/host.tsx +16 -0
  678. package/src/updater/index.ts +38 -13
  679. package/src/utils/async-deadline.ts +21 -0
  680. package/src/utils/cli-output.ts +5 -1
  681. package/src/utils/crypto-pair.ts +41 -0
  682. package/src/utils/currency-units.ts +14 -0
  683. package/src/utils/depositary-receipt.ts +26 -0
  684. package/src/utils/exchanges.ts +72 -0
  685. package/src/utils/fire-and-forget.ts +24 -0
  686. package/src/utils/format.ts +13 -0
  687. package/src/utils/price-earnings.ts +70 -3
  688. package/src/utils/price-history.ts +58 -13
  689. package/src/utils/rpc-timeout-error.ts +27 -0
  690. package/src/utils/sec.ts +13 -1
  691. package/src/utils/utc-time.ts +79 -0
@@ -46,6 +46,12 @@ export interface MarketHeatmapAsset {
46
46
  industry: string | null;
47
47
  marketState: string | null;
48
48
  source: MarketHeatmapSource;
49
+ /**
50
+ * The move of the last completed regular session, which `price`, `change`
51
+ * and `changePercent` then are. Null while the regular session trades, and
52
+ * for a name without that session's close.
53
+ */
54
+ regularChangePercent?: number | null;
49
55
  }
50
56
 
51
57
  export interface MarketHeatmapResult {
@@ -53,6 +59,10 @@ export interface MarketHeatmapResult {
53
59
  universe: MarketHeatmapUniverseId;
54
60
  source: MarketHeatmapSource;
55
61
  fetchedAt: number;
62
+ /** The US market session the snapshot describes; null when the server cannot tell. */
63
+ session?: "REGULAR" | "PRE" | "POST" | "CLOSED" | null;
64
+ /** The completed regular session every stored tile describes outside the regular session, as a New York date; null while it trades. */
65
+ regularSessionDate?: string | null;
56
66
  assets: MarketHeatmapAsset[];
57
67
  }
58
68
 
@@ -0,0 +1,26 @@
1
+ interface MemberFund { ticker: string; name: string; aliases: string[]; changes: "sp500" | "announcements" | "none" }
2
+ export interface FundMember {
3
+ id: string; symbol: string | null; name: string; sector: string | null;
4
+ weight: number | null; shares: number; holdingPrice: number; marketValue: number;
5
+ price: number | null; priceAsOf: string | null; changePercent: number | null; dailyAsOf: string | null;
6
+ return1WPercent: number | null; return1MPercent: number | null; returnYtdPercent: number | null;
7
+ contribution: number | null; stale: boolean;
8
+ }
9
+ export interface FundMembersPayload {
10
+ fund: MemberFund; asOf: string; fetchedAt: string; excludedDerivatives: number; stale: boolean;
11
+ quotesUnavailable: boolean; snapshotAsOf: string | null; fundDailyAsOf: string | null; quoteCap: number;
12
+ members: FundMember[];
13
+ aggregate: { sum: number | null; fundReturn: number | null; residual: number | null; tolerancePp: number;
14
+ withinTolerance: boolean | null; covered: number; total: number; coveredWeight: number; holdingsWeight: number; fresh1D: number };
15
+ }
16
+ export interface FundChange {
17
+ id: string; fund: string; effectiveDate: string | null; announcedAt: string | null;
18
+ added: string | null; removed: string | null; reason: string; headline: string | null; url: string;
19
+ kind: "history" | "announcement"; daysToGo: number | null;
20
+ estimates: { symbol: string; usd: number; advUsd: number; days: number; asOf: string; advAsOf: string | null }[];
21
+ }
22
+ export interface FundChangesPayload {
23
+ fund: MemberFund; changes: FundChange[]; asOf: string | null; stale: boolean; available: boolean;
24
+ estimateLabel: string; attribution: { text: string; url: string } | null;
25
+ }
26
+ export interface MemberFundsPayload { funds: (MemberFund & { asOf: string | null })[] }
@@ -4,7 +4,9 @@ import type {
4
4
  CloudTweetQueryType,
5
5
  } from "./types";
6
6
  import { isUsListingExchange, normalizeSymbol, parsePublicTickerKey, publicTickerKey } from "../utils/exchanges";
7
+ import { nonUsSecListingVenue } from "../utils/sec";
7
8
  import type { HistoryRetention } from "../sources/history-retention";
9
+ import type { CloudBeneficialOwnersParams } from "./beneficial-owners";
8
10
 
9
11
  export type CloudHistoryParams = {
10
12
  interval?: string;
@@ -228,6 +230,10 @@ export function cloudCreditBoardPath(board: "cdx" | "sovr", params: { days?: num
228
230
 
229
231
  export type CloudSecFilingsParams = {
230
232
  ticker: string;
233
+ /** The listing's venue. Sent only for a venue outside the US, with `name`. */
234
+ exchange?: string;
235
+ /** The listing's company name, from its own quote. */
236
+ name?: string;
231
237
  limit?: number;
232
238
  offset?: number;
233
239
  };
@@ -343,13 +349,36 @@ export function cloudProxyStatementPath(ticker: string, year: number): string {
343
349
  return `/cloud/proxies/${encodeURIComponent(normalizeIssuerResearchTicker(ticker))}/${year}`;
344
350
  }
345
351
 
352
+ /**
353
+ * A US listing, or a symbol with no venue, looks up its US ticker as before.
354
+ * A listing elsewhere sends its bare symbol with the venue and company name:
355
+ * its symbol can be another company's US ticker.
356
+ */
346
357
  export function cloudSecFilingsPath(params: CloudSecFilingsParams): string {
347
- const search = new URLSearchParams({ ticker: normalizeIssuerResearchTicker(params.ticker) });
358
+ const venue = nonUsSecListingVenue(params.ticker, params.exchange);
359
+ const search = new URLSearchParams({
360
+ ticker: venue ? parsePublicTickerKey(params.ticker).symbol : normalizeIssuerResearchTicker(params.ticker),
361
+ });
348
362
  if (params.limit != null) search.set("limit", String(params.limit));
349
363
  if (params.offset != null) search.set("offset", String(params.offset));
364
+ if (venue) {
365
+ search.set("exchange", venue);
366
+ const name = params.name?.trim();
367
+ if (name) search.set("name", name);
368
+ }
350
369
  return appendQuery("/cloud/sec/filings", search);
351
370
  }
352
371
 
372
+ /** Schedule 13D and 13G reports about the issuer behind `ticker`. */
373
+ export function cloudSecBeneficialOwnersPath(params: CloudBeneficialOwnersParams): string {
374
+ const search = new URLSearchParams({ ticker: normalizeIssuerResearchTicker(params.ticker) });
375
+ if (params.form) search.set("form", params.form);
376
+ if (params.history) search.set("history", "1");
377
+ if (params.limit != null) search.set("limit", String(params.limit));
378
+ if (params.offset != null) search.set("offset", String(params.offset));
379
+ return appendQuery("/cloud/sec/beneficial-owners", search);
380
+ }
381
+
353
382
  export function cloudSecFilingDocumentsPath(
354
383
  params: CloudSecFilingParams,
355
384
  ): string {
@@ -71,6 +71,7 @@ interface PerpCandle {
71
71
 
72
72
  interface UnderlyingReference {
73
73
  symbol: string
74
+ listingExchange?: string
74
75
  price: number
75
76
  currency: string
76
77
  asOf: string
@@ -78,7 +79,30 @@ interface UnderlyingReference {
78
79
  sourceUrl: string
79
80
  }
80
81
 
82
+ /**
83
+ * The venue's latest long/short account reading for one contract, in its own hourly bucket. Shares are
84
+ * fractions and may sum to less than one (flat accounts); OKX publishes only the ratio, so its shares are derived.
85
+ */
86
+ export interface PerpLongShortRatio {
87
+ venue: string
88
+ /** Key of what is counted, such as `accounts_all`; `definitionText` says it in words. */
89
+ definition: string
90
+ definitionText: string
91
+ period: string
92
+ longShare: number
93
+ shortShare: number
94
+ ratio: number | null
95
+ derived: boolean
96
+ bucketAt: string
97
+ observedAt: string
98
+ /** The bucket is more than three hours old. */
99
+ stale: boolean
100
+ }
101
+ /** Why a row has no reading: the venue publishes none, collection is off, or nothing is stored yet. */
102
+ type PerpLongShortReason = "unsupported" | "off" | "collecting"
103
+
81
104
  export interface PerpBoardRow extends PerpMarket {
105
+ equityMatch?: { listing: PerpEquityListing; underlying: PerpEquityListing; basis: "listing" | "issuer" }
82
106
  stale: boolean
83
107
  oiChange1h: number | null
84
108
  oiChange24h: number | null
@@ -87,6 +111,19 @@ export interface PerpBoardRow extends PerpMarket {
87
111
  underlying: UnderlyingReference | null
88
112
  underlyingPremium: number | null
89
113
  closedMarketPremium: number | null
114
+ /** Absent from servers older than the long/short series: read as null. */
115
+ longShortRatio?: PerpLongShortRatio | null
116
+ longShortRatioReason?: PerpLongShortReason | null
117
+ }
118
+
119
+ export type PerpLongShortPoint = {
120
+ time: string
121
+ definition: string
122
+ longShare: number
123
+ shortShare: number
124
+ ratio: number | null
125
+ derived: boolean
126
+ observedAt: string
90
127
  }
91
128
 
92
129
  type PerpHistoryPoint = {
@@ -105,11 +142,15 @@ type PerpHistoryPoint = {
105
142
  }
106
143
 
107
144
  export interface PerpBoardPayload {
145
+ listing?: PerpEquityListing | null;
108
146
  status: string; asOf: string | null; rows: PerpBoardRow[]; total: number; locked: number;
109
147
  access: "pro" | "preview"; sources?: unknown[];
110
148
  }
149
+ export interface PerpEquityListing { symbol: string; exchange: string }
111
150
  export interface PerpHistoryPayload {
112
151
  status: string; marketId: string; rows: PerpHistoryPoint[]; funding: PerpFunding[]; candles: PerpCandle[];
152
+ /** Absent from servers older than the long/short series: read as empty. */
153
+ longShortRatio?: PerpLongShortPoint[];
113
154
  locked: boolean; access: "pro" | "preview"; asOf: string | null;
114
155
  from?: string; to?: string; resolution?: "minute" | "hour" | "day"; truncated?: boolean;
115
156
  }
@@ -3,6 +3,7 @@ import { withDeadline } from "../utils/async-deadline";
3
3
  import {
4
4
  ApiRequestError,
5
5
  parseApiErrorCode,
6
+ parseApiErrorDetails,
6
7
  parseApiErrorMessage,
7
8
  parseRetryAfterMs,
8
9
  type RevisionConflictError,
@@ -391,6 +392,7 @@ export class CloudApiRequestTransport {
391
392
  res.status,
392
393
  parseRetryAfterMs(res.headers.get("Retry-After")),
393
394
  parseApiErrorCode(text),
395
+ parseApiErrorDetails(text),
394
396
  );
395
397
  }
396
398
 
@@ -404,8 +406,9 @@ export class CloudApiRequestTransport {
404
406
  };
405
407
  // Crash reports, usage counts and command-search reports are background
406
408
  // traffic: a rate-limited, timed-out or missing one must not show up as a
407
- // Cloud outage in the connections pane.
408
- if (path.startsWith("/telemetry/") || path === "/assist/searches") return request();
409
+ // Cloud outage in the connections pane. Nor must the map's probe for geo
410
+ // layers, which a server without them answers with 404.
411
+ if (path.startsWith("/telemetry/") || path === "/assist/searches" || path === "/cloud/geo/layers") return request();
409
412
  return this.connectionHealth.track(
410
413
  GLOOM_CLOUD_HTTP_CONNECTION_ID,
411
414
  operation,
@@ -12,6 +12,8 @@ import type { SyncSettings, SyncSnapshot } from "../sync/types";
12
12
 
13
13
  export interface ChatUserSummary {
14
14
  id: string;
15
+ /** A person, a managed assistant (Gloombot), or a Discord user bridged into public channels. */
16
+ accountType?: "human" | "managed_llm" | "discord";
15
17
  username: string | null;
16
18
  displayName: string;
17
19
  bio?: string | null;
@@ -295,7 +297,9 @@ export interface CloudSyncPushResponse {
295
297
  settings: SyncSettings;
296
298
  }
297
299
 
298
- export interface CloudQuotePayload extends Omit<Quote, "change" | "changePercent"> {
300
+ export interface CloudQuotePayload extends Omit<Quote, "change" | "changePercent" | "priceBasis" | "priceObservation"> {
301
+ /** The service labels daily NAV here; the app separates observation kind from price units. */
302
+ priceBasis?: Quote["priceBasis"] | "nav";
299
303
  // JSON encodes the provider's unavailable numeric values as null.
300
304
  change?: number | null;
301
305
  changePercent?: number | null;
@@ -1375,6 +1379,10 @@ export interface CloudMarketScreenerItem {
1375
1379
  change: number;
1376
1380
  changePercent: number;
1377
1381
  volume: number;
1382
+ /** Available average volume for this listing, independent of public ranking membership. */
1383
+ avgVolume?: number;
1384
+ /** Observation time of the optional retained metadata. */
1385
+ metadataAsOf?: string;
1378
1386
  tradeCount?: number;
1379
1387
  currency: string;
1380
1388
  high52w?: number;
@@ -8,7 +8,7 @@ import type { AppAction, AppState } from "../state/app/context";
8
8
  import type { TickerRecord } from "../types/ticker";
9
9
  import { findPaneInstance } from "../types/config";
10
10
  import type { ReleaseInfo } from "../updater";
11
- import { canSelfUpdate } from "../updater";
11
+ import { canRestartToApply, canSelfUpdate } from "../updater";
12
12
  import { getVisiblePaneCycleOrder } from "../components/layout/pane/cycle-order";
13
13
  import { requestFunctionHelp, useFunctionHelpHost } from "../plugins/builtin/help/function-card";
14
14
  import { buildRegistryHelpIndex, helpFunctionForPane } from "../plugins/builtin/help/function-index";
@@ -34,9 +34,10 @@ import {
34
34
  const KEYBINDING_NOTICE_DURATION_MS = 15_000;
35
35
 
36
36
  /**
37
- * Whether the install-update key has something to do: a release this build
37
+ * Whether the install-update key has something to retry: a release this build
38
38
  * can install itself whose last attempt failed. A fresh one downloads on its
39
- * own, and a manual or managed one names its own command.
39
+ * own, and a manual or managed one names its own command. (A downloaded
40
+ * desktop update has its own use of the key: restarting into it.)
40
41
  */
41
42
  export function canRetryUpdate(
42
43
  state: Pick<AppState, "updateAvailable" | "updateProgress" | "updateCheckInProgress">,
@@ -91,6 +92,7 @@ export function useAppGlobalShortcuts({
91
92
  keybindings = getDefaultKeybindings(),
92
93
  pluginRegistry,
93
94
  refreshTicker,
95
+ restartToApplyUpdate,
94
96
  startUpdate,
95
97
  state,
96
98
  }: {
@@ -101,6 +103,8 @@ export function useAppGlobalShortcuts({
101
103
  keybindings?: ResolvedKeybindings;
102
104
  pluginRegistry: PluginRegistry;
103
105
  refreshTicker: (symbol: string, exchange?: string, tickerOverride?: TickerRecord | null, priority?: number) => void;
106
+ /** Applies a downloaded desktop update and relaunches. Runs only on the user's key press. */
107
+ restartToApplyUpdate: () => void;
104
108
  startUpdate: (release: ReleaseInfo) => void;
105
109
  state: AppState;
106
110
  }) {
@@ -249,9 +253,13 @@ export function useAppGlobalShortcuts({
249
253
  refreshTicker(ticker.metadata.ticker, ticker.metadata.exchange, ticker, 1);
250
254
  }
251
255
  } else if (action === "install-update") {
252
- // A release that can install itself starts on its own, so the key is
253
- // for the one that failed: it tries again.
254
- if (canRetryUpdate(state)) {
256
+ // A release that can install itself downloads on its own, so the key is
257
+ // for the one that waits for a restart and for the one that failed.
258
+ if (!isDetachedWindow && canRestartToApply(state.updateProgress)) {
259
+ event.preventDefault();
260
+ event.stopPropagation();
261
+ restartToApplyUpdate();
262
+ } else if (canRetryUpdate(state)) {
255
263
  event.preventDefault();
256
264
  event.stopPropagation();
257
265
  startUpdate(state.updateAvailable!);
@@ -129,7 +129,7 @@ export const KEYBINDING_ACTIONS: readonly KeybindingActionDef[] = [
129
129
  {
130
130
  id: "install-update",
131
131
  category: "Global Keys",
132
- description: "Install an available app update when one is shown.",
132
+ description: "Restart into a downloaded app update, or retry one that failed.",
133
133
  defaults: ["U"],
134
134
  },
135
135
  {
@@ -1,8 +1,10 @@
1
- import { useCallback, useEffect, type Dispatch } from "react";
1
+ import { useCallback, useEffect, useRef, type Dispatch } from "react";
2
2
  import type { PluginRegistry } from "../../plugins/registry";
3
3
  import { saveConfigImmediately } from "../../state/config-save-scheduler";
4
4
  import type { AppAction, AppState } from "../../state/app/context";
5
5
  import {
6
+ applyUpdate,
7
+ canRestartToApply,
6
8
  canSelfUpdate,
7
9
  checkForUpdateDetailed,
8
10
  performUpdate,
@@ -15,6 +17,11 @@ import { runAutomated } from "../../telemetry/usage-counts";
15
17
 
16
18
  const UPDATE_CHECK_INTERVAL_MS = 60 * 60_000; // hourly
17
19
 
20
+ /** An update is being downloaded, applied, or is downloaded and waiting for a restart. */
21
+ function updateInFlight(progress: AppState["updateProgress"]): boolean {
22
+ return progress?.phase === "downloading" || progress?.phase === "replacing" || progress?.phase === "ready";
23
+ }
24
+
18
25
  export function useAppUpdateRuntime({
19
26
  enabled = true,
20
27
  dispatch,
@@ -36,7 +43,13 @@ export function useAppUpdateRuntime({
36
43
  }): {
37
44
  runUpdateCheck: (manual?: boolean) => Promise<void>;
38
45
  startUpdate: (release: ReleaseInfo) => void;
46
+ /** Installs the downloaded desktop update and relaunches. Does nothing unless one is ready. */
47
+ restartToApplyUpdate: () => void;
48
+ /** The command bar's Check for Updates: restarts into a downloaded update, otherwise checks. */
49
+ runUpdateCommand: () => void;
39
50
  } {
51
+ const restartingRef = useRef(false);
52
+
40
53
  const startUpdate = useCallback((release: ReleaseInfo) => {
41
54
  dispatch({ type: "SET_UPDATE_PROGRESS", progress: { phase: "downloading", percent: 0 } });
42
55
  void performUpdate(release, (progress) => {
@@ -44,7 +57,23 @@ export function useAppUpdateRuntime({
44
57
  });
45
58
  }, [dispatch]);
46
59
 
60
+ const restartToApplyUpdate = useCallback(() => {
61
+ if (!enabled || isDetachedWindow) return;
62
+ // The app relaunches here, so this must only ever follow the user's own
63
+ // request, and a second one while the first is working changes nothing.
64
+ if (restartingRef.current || !canRestartToApply(stateRef.current.updateProgress)) return;
65
+ restartingRef.current = true;
66
+ dispatch({ type: "SET_UPDATE_PROGRESS", progress: { phase: "replacing" } });
67
+ void applyUpdate((progress) => {
68
+ if (progress.phase === "error") restartingRef.current = false;
69
+ dispatch({ type: "SET_UPDATE_PROGRESS", progress });
70
+ });
71
+ }, [dispatch, enabled, isDetachedWindow, stateRef]);
72
+
47
73
  const runUpdateCheck = useCallback(async (manual = false) => {
74
+ // A staged update is the answer until it is applied: another check would
75
+ // swap the release under the "ready" state, and the host has nothing to add.
76
+ if (updateInFlight(stateRef.current.updateProgress)) return;
48
77
  if (manual) {
49
78
  dispatch({ type: "SET_UPDATE_CHECK_IN_PROGRESS", checking: true });
50
79
  dispatch({ type: "SET_UPDATE_NOTICE", notice: null });
@@ -88,7 +117,12 @@ export function useAppUpdateRuntime({
88
117
  }
89
118
 
90
119
  dispatch({ type: "SET_UPDATE_NOTICE", notice: `Update check failed: ${result.error}` });
91
- }, [dispatch]);
120
+ }, [dispatch, stateRef]);
121
+
122
+ const runUpdateCommand = useCallback(() => {
123
+ if (canRestartToApply(stateRef.current.updateProgress)) restartToApplyUpdate();
124
+ else void runUpdateCheck(true);
125
+ }, [restartToApplyUpdate, runUpdateCheck, stateRef]);
92
126
 
93
127
  useEffect(() => {
94
128
  if (!enabled || isDetachedWindow) return;
@@ -121,7 +155,9 @@ export function useAppUpdateRuntime({
121
155
  }, [enabled, isDetachedWindow, startUpdate, updateAvailable, updateCheckInProgress, updateProgress]);
122
156
 
123
157
  return {
158
+ restartToApplyUpdate,
124
159
  runUpdateCheck,
160
+ runUpdateCommand,
125
161
  startUpdate,
126
162
  };
127
163
  }
package/src/app.tsx CHANGED
@@ -268,7 +268,7 @@ function AppInner({
268
268
  tickerRepository,
269
269
  });
270
270
 
271
- const { runUpdateCheck, startUpdate } = useAppUpdateRuntime({
271
+ const { restartToApplyUpdate, runUpdateCheck, runUpdateCommand, startUpdate } = useAppUpdateRuntime({
272
272
  enabled: updatesEnabled,
273
273
  dispatch,
274
274
  isDetachedWindow,
@@ -409,6 +409,7 @@ function AppInner({
409
409
  keybindings,
410
410
  pluginRegistry,
411
411
  refreshTicker,
412
+ restartToApplyUpdate,
412
413
  startUpdate,
413
414
  state,
414
415
  });
@@ -450,10 +451,13 @@ function AppInner({
450
451
  desktopWindowBridge={desktopWindowBridge}
451
452
  >
452
453
  <ThemedAppRoot>
453
- <Header onOpenHelp={() => {
454
- recordFunctionOpen({ shortcut: "HELP", externalPluginId: null });
455
- pluginRegistry.showPane("help");
456
- }} />
454
+ <Header
455
+ onOpenHelp={() => {
456
+ recordFunctionOpen({ shortcut: "HELP", externalPluginId: null });
457
+ pluginRegistry.showPane("help");
458
+ }}
459
+ onRestartForUpdate={updatesEnabled && !isDetachedWindow ? restartToApplyUpdate : undefined}
460
+ />
457
461
  <TransientLayoutProvider>
458
462
  <Shell
459
463
  pluginRegistry={pluginRegistry}
@@ -486,7 +490,7 @@ function AppInner({
486
490
  tickerRepository={tickerRepository}
487
491
  pluginRegistry={pluginRegistry}
488
492
  quitApp={() => rendererHost.requestExit()}
489
- onCheckForUpdates={updatesEnabled ? () => runUpdateCheck(true) : undefined}
493
+ onCheckForUpdates={updatesEnabled ? runUpdateCommand : undefined}
490
494
  onNativeOccluderChange={setCommandBarNativeOccluder}
491
495
  />
492
496
  )}
@@ -84,6 +84,30 @@ export function loadPersistedBrokerAccounts(
84
84
  })?.value.accounts ?? null;
85
85
  }
86
86
 
87
+ /**
88
+ * The newest saved account snapshot of a profile, for readers without its
89
+ * adapter such as the CLI. Read only: without the adapter the current source
90
+ * key is unknown, so nothing is pruned.
91
+ */
92
+ export function peekPersistedBrokerAccounts(
93
+ resources: Pick<AppResourceStorePort, "list">,
94
+ instance: BrokerInstanceConfig,
95
+ ): BrokerAccount[] | null {
96
+ const records = resources.list<PersistedBrokerAccountSnapshot>({
97
+ namespace: brokerAccountNamespace(instance),
98
+ kind: BROKER_ACCOUNT_SNAPSHOT_KIND,
99
+ entityKey: instance.id,
100
+ }, {
101
+ schemaVersion: BROKER_ACCOUNT_SNAPSHOT_SCHEMA_VERSION,
102
+ allowExpired: true,
103
+ });
104
+ const newest = records.reduce<(typeof records)[number] | null>(
105
+ (latest, record) => (!latest || record.fetchedAt > latest.fetchedAt ? record : latest),
106
+ null,
107
+ );
108
+ return newest?.value.accounts ?? null;
109
+ }
110
+
87
111
  export function persistBrokerAccounts(
88
112
  resources: AppResourceStorePort,
89
113
  instance: BrokerInstanceConfig,
@@ -15,6 +15,14 @@ export function takeOption(args: string[], name: string): string | undefined {
15
15
  return value;
16
16
  }
17
17
 
18
+ /** Removes a boolean flag (`--history`) from `args` and says whether it was there. */
19
+ export function takeFlag(args: string[], name: string): boolean {
20
+ const index = args.indexOf(name);
21
+ if (index < 0) return false;
22
+ args.splice(index, 1);
23
+ return true;
24
+ }
25
+
18
26
  export function parseJsonPayload(value: string | undefined, ctx: CliCommandContext): unknown {
19
27
  if (!value) return {};
20
28
  try {
@@ -0,0 +1,75 @@
1
+ import { isCryptoInstrumentType } from "../../tickers/search/ranking";
2
+ import type { Quote } from "../../types/financials";
3
+ import { isCryptoPairSymbol } from "../../utils/crypto-pair";
4
+
5
+ /** Where a crypto pair that will not load can still be read. `fn CRYP` takes no argument. */
6
+ export const CRYPTO_BOARD_HINT = "Crypto prices may be briefly unavailable; the CRYP function (gloomberb fn CRYP) shows the crypto board.";
7
+
8
+ // The coins whose bare ticker is most often typed for the coin itself. The label is how the note
9
+ // names the coin and what a listing's name has to say before the note applies.
10
+ const MAJOR_COINS = new Map([
11
+ ["BTC", "bitcoin"],
12
+ ["ETH", "ethereum"],
13
+ ["SOL", "solana"],
14
+ ["XRP", "XRP"],
15
+ ["DOGE", "dogecoin"],
16
+ ["ADA", "cardano"],
17
+ ["LTC", "litecoin"],
18
+ ["BCH", "bitcoin cash"],
19
+ ["AVAX", "avalanche"],
20
+ ["DOT", "polkadot"],
21
+ ["LINK", "chainlink"],
22
+ ["BNB", "BNB"],
23
+ ]);
24
+
25
+ /**
26
+ * A bare coin ticker usually resolves to a listed fund, not the coin. The note applies only when
27
+ * the listing is not crypto and its own name says the coin (a "Bitcoin" trust), so a company that
28
+ * happens to share the letters (Interlink Electronics on LINK) is left alone.
29
+ */
30
+ function notTheCoinNote(symbol: string, quote: Pick<Quote, "name" | "instrumentType"> | null | undefined): string | null {
31
+ const coin = MAJOR_COINS.get(symbol);
32
+ const type = quote?.instrumentType?.trim();
33
+ const name = quote?.name?.trim();
34
+ if (!coin || !name || !type || isCryptoInstrumentType(type)) return null;
35
+ if (!new RegExp(`\\b${coin}\\b`, "i").test(name)) return null;
36
+ return `${symbol} is ${name}, not ${coin}. For ${coin} use ${symbol}-USD.`;
37
+ }
38
+
39
+ interface QuoteNoteResult {
40
+ target: { symbol: string };
41
+ quote: Pick<Quote, "name" | "instrumentType"> | null;
42
+ error: string | null;
43
+ }
44
+
45
+ /** The router words a failure as "<reason> for <symbol>"; drop the symbol so equal reasons group. */
46
+ function failureReason(message: string, symbol: string): string {
47
+ const line = (message.split("\n")[0] ?? "").trim().replace(/\.+$/, "");
48
+ const suffix = ` for ${symbol}`;
49
+ return line.toLowerCase().endsWith(suffix.toLowerCase()) ? line.slice(0, -suffix.length) : line;
50
+ }
51
+
52
+ /**
53
+ * Text-mode notes under a quote table: one line per distinct failure reason (with the crypto board
54
+ * pointer when a failed symbol is a crypto pair), then a line for each bare coin ticker that
55
+ * resolved to something else. `--exchange` names the listing on purpose, so it gets no coin note.
56
+ */
57
+ export function quoteNotes(results: QuoteNoteResult[], options: { exchange?: string } = {}): string[] {
58
+ const failures = new Map<string, string[]>();
59
+ for (const result of results) {
60
+ if (!result.error || result.quote) continue;
61
+ const reason = failureReason(result.error, result.target.symbol);
62
+ const symbols = failures.get(reason) ?? [];
63
+ if (!symbols.includes(result.target.symbol)) failures.set(reason, [...symbols, result.target.symbol]);
64
+ }
65
+ const notes = [...failures].map(([reason, symbols]) => (
66
+ `${symbols.join(", ")}: ${reason}${symbols.some(isCryptoPairSymbol) ? `. ${CRYPTO_BOARD_HINT}` : ""}`
67
+ ));
68
+ if (!options.exchange) {
69
+ for (const result of results) {
70
+ const note = notTheCoinNote(result.target.symbol, result.quote);
71
+ if (note) notes.push(note);
72
+ }
73
+ }
74
+ return notes;
75
+ }