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
@@ -233,12 +233,18 @@ export async function resolveTickerListInput(
233
233
  rawInput: string,
234
234
  collectionId: string | null,
235
235
  deps: SharedWorkflowDeps,
236
+ keepToken?: (token: string) => boolean,
236
237
  ): Promise<string[]> {
237
238
  const tokens = parseTickerListInput(rawInput);
238
239
  const symbols: string[] = [];
239
240
  const seen = new Set<string>();
240
241
 
241
242
  for (const token of tokens) {
243
+ if (keepToken?.(token)) {
244
+ if (!seen.has(token)) symbols.push(token);
245
+ seen.add(token);
246
+ continue;
247
+ }
242
248
  const resolvedTicker = await resolveTickerInputOrThrow(token, null, collectionId, deps, { preserveListingKey: true });
243
249
  const symbol = resolvedTicker.symbol;
244
250
 
@@ -593,26 +593,45 @@ export function DataTableView<
593
593
  && (!isNavigable || isNavigable(item, index))
594
594
  ), [effectiveSelectedIndex, isNavigable]);
595
595
 
596
+ // The row handlers reach the latest cursor logic through a ref, so their
597
+ // identity survives a parent render. Most callers build `selection` inline,
598
+ // which used to give every handler a new identity on each render and made
599
+ // every visible row re-render its cells, even when nothing in it changed.
600
+ const rowHandlerStateRef = useRef({
601
+ activateIndex,
602
+ onRowContextMenu: tableProps.onRowContextMenu,
603
+ onRowMouseDown: tableProps.onRowMouseDown,
604
+ updateCursorIndex,
605
+ });
606
+ rowHandlerStateRef.current = {
607
+ activateIndex,
608
+ onRowContextMenu: tableProps.onRowContextMenu,
609
+ onRowMouseDown: tableProps.onRowMouseDown,
610
+ updateCursorIndex,
611
+ };
612
+
596
613
  const handleTableSelect = useCallback((_item: T, index: number) => {
597
- updateCursorIndex(index, { commit: "immediate" });
598
- }, [updateCursorIndex]);
614
+ rowHandlerStateRef.current.updateCursorIndex(index, { commit: "immediate" });
615
+ }, []);
599
616
 
600
617
  const handleTableActivate = useCallback((_item: T, index: number) => {
601
- activateIndex(index);
602
- }, [activateIndex]);
618
+ rowHandlerStateRef.current.activateIndex(index);
619
+ }, []);
603
620
 
604
621
  const handleRowMouseDown = useCallback((item: T, index: number, event: any) => {
605
- const handled = tableProps.onRowMouseDown?.(item, index, event);
622
+ const latest = rowHandlerStateRef.current;
623
+ const handled = latest.onRowMouseDown?.(item, index, event);
606
624
  if (handled === true) {
607
- updateCursorIndex(index, { commit: "immediate" });
625
+ latest.updateCursorIndex(index, { commit: "immediate" });
608
626
  }
609
627
  return handled;
610
- }, [tableProps.onRowMouseDown, updateCursorIndex]);
628
+ }, []);
611
629
 
612
630
  const handleRowContextMenu = useCallback((item: T, index: number, event: any) => {
613
- updateCursorIndex(index, { commit: "immediate" });
614
- tableProps.onRowContextMenu?.(item, index, event);
615
- }, [tableProps.onRowContextMenu, updateCursorIndex]);
631
+ const latest = rowHandlerStateRef.current;
632
+ latest.updateCursorIndex(index, { commit: "immediate" });
633
+ latest.onRowContextMenu?.(item, index, event);
634
+ }, []);
616
635
 
617
636
  // Wide tables scroll their columns on Shift+Left/Right, the way a chart pans,
618
637
  // and on Ctrl+Left/Right where the OS leaves those alone (macOS takes them to
@@ -37,6 +37,7 @@ import { useToastHost } from "../ui/toast";
37
37
  import { VERSION } from "../version";
38
38
  import { Button } from "./ui/button";
39
39
  import { Checkbox } from "./ui/checkbox";
40
+ import { FRAMED_TEXTAREA_DESKTOP_STYLE } from "./ui/fields";
40
41
  import { DialogFrame } from "./ui/frame";
41
42
  import { TERMINAL_MESSAGE_KEYS } from "./textarea-keys";
42
43
 
@@ -217,7 +218,7 @@ function FeedbackDialog({
217
218
  flexGrow={1}
218
219
  wrapText
219
220
  {...(nativePaneChrome
220
- ? { style: { padding: "6px 8px", lineHeight: "18px" }, onKeyDown: sendOnModifiedEnter }
221
+ ? { style: FRAMED_TEXTAREA_DESKTOP_STYLE, onKeyDown: sendOnModifiedEnter }
221
222
  : { keyBindings: TERMINAL_MESSAGE_KEYS, onSubmit: () => { void send(); } })}
222
223
  onInput={(value: string) => {
223
224
  messageValueRef.current = value;
@@ -19,7 +19,7 @@ import {
19
19
  import type { CommandBarFieldValue, CommandBarWorkflowField } from "../command-bar/workflow/types";
20
20
  import { TERMINAL_MESSAGE_KEYS } from "../textarea-keys";
21
21
  import { Checkbox } from "../ui/checkbox";
22
- import { FieldLabel, NumberField, TextField } from "../ui/fields";
22
+ import { FieldLabel, FRAMED_TEXTAREA_DESKTOP_STYLE, NumberField, TextField } from "../ui/fields";
23
23
  import { SelectField, type SelectFieldHandle } from "../ui/select-field";
24
24
  import { FORM_TEXTAREA_ROWS } from "./model";
25
25
 
@@ -132,7 +132,7 @@ function FormTextarea({
132
132
  flexGrow={1}
133
133
  wrapText
134
134
  {...(desktop
135
- ? { style: { padding: "6px 8px", lineHeight: "18px" }, onKeyDown: submitOnModifiedEnter }
135
+ ? { style: FRAMED_TEXTAREA_DESKTOP_STYLE, onKeyDown: submitOnModifiedEnter }
136
136
  : { keyBindings: TERMINAL_MESSAGE_KEYS, onSubmit: onSubmitField })}
137
137
  onInput={(nextValue: string) => onChange(nextValue)}
138
138
  />
@@ -131,7 +131,7 @@ export {
131
131
  IconButton, InlineQuickAddRow, KeyValueRow, ListView, loadingText, Menu, MenuPopover,
132
132
  MessageComposer, MultiSelectDialogButton, MultiSelectDialogContent, Notice, NumberField,
133
133
  NumberPromptDialog, openUrl, PageStackView, PaneLinkMenu, PaneStatusBody, Popover, Prose,
134
- QueryBar, READING_WIDTH, RemoteImage, Section, SectionHeading, SegmentedControl, SelectButton, ShortcutHint,
134
+ QueryBar, RangeTrack, RatioBar, READING_WIDTH, RemoteImage, Section, SectionHeading, SegmentedControl, SelectButton, ShortcutHint,
135
135
  Spinner, StatGrid, statGridColumns, statGridRows, Tabs, TextField, TextPromptDialog, unavailableText,
136
136
  useFieldRing, usePaneLinkMenuEntry, useQueryBarSearch,
137
137
  } from "./ui";
@@ -145,7 +145,7 @@ export type {
145
145
  MenuProps, MultiSelectDialogButtonHandle, MultiSelectPopoverAnchorPoint, MultiSelectRowAction,
146
146
  NoticeProps, NumberFieldProps, PaneStatusBodyProps, PopoverProps, ProseProps, QueryBarFilter,
147
147
  QueryBarMultiFilter, QueryBarProps, QueryBarSearch, QueryBarSearchFocus, QueryBarSelectFilter, QueryBarTextFilter,
148
- QueryBarToggleFilter, QueryBarView, SectionHeadingProps, SectionProps, SegmentedControlProps,
148
+ QueryBarToggleFilter, QueryBarView, RangeTrackProps, RatioBarProps, SectionHeadingProps, SectionProps, SegmentedControlProps,
149
149
  SelectButtonOption, SelectButtonProps, SelectControl, StatGridProps, StatItem, TabsProps,
150
150
  TextFieldProps, TextPromptDialogProps,
151
151
  } from "./ui";
@@ -32,6 +32,7 @@ import { contextMenuDivider, type ContextMenuItem } from "../../types/context-me
32
32
  import { useKeybindings } from "../../app/keybindings";
33
33
  import { useDialogState } from "../../ui/dialog";
34
34
  import { getShortcutDisplayMode } from "../../utils/shortcut-labels";
35
+ import { fireAndForget } from "../../utils/fire-and-forget";
35
36
  import {
36
37
  inputCaptureAllowsPaneManagementShortcut,
37
38
  modalSurfaceOwnsKey,
@@ -142,7 +143,7 @@ export function DetachedPaneShell({ pluginRegistry, desktopWindowBridge }: Detac
142
143
  if (takeDoubleEscapeClose(doubleEscapeState, desktopWindowBridge.paneId, Date.now())) {
143
144
  event.preventDefault();
144
145
  event.stopPropagation();
145
- if (!locked) void desktopWindowBridge.closeDetachedPane?.(desktopWindowBridge.paneId);
146
+ if (!locked) fireAndForget(desktopWindowBridge.closeDetachedPane?.(desktopWindowBridge.paneId), "desktop.closeDetachedPane");
146
147
  }
147
148
  return;
148
149
  }
@@ -170,7 +171,7 @@ export function DetachedPaneShell({ pluginRegistry, desktopWindowBridge }: Detac
170
171
  pluginRegistry.notify({ body: "Pane is locked. Unlock it in pane settings.", type: "info" });
171
172
  return;
172
173
  }
173
- void desktopWindowBridge.closeDetachedPane?.(desktopWindowBridge.paneId);
174
+ fireAndForget(desktopWindowBridge.closeDetachedPane?.(desktopWindowBridge.paneId), "desktop.closeDetachedPane");
174
175
  }, [desktopWindowBridge, locked, pluginRegistry]);
175
176
 
176
177
  const startWindowDrag = useCallback(() => {
@@ -212,7 +213,7 @@ export function DetachedPaneShell({ pluginRegistry, desktopWindowBridge }: Detac
212
213
  }, [desktopWindowBridge.paneId, focusPane, pluginRegistry]);
213
214
 
214
215
  const dockPane = desktopWindowBridge.dockDetachedPane
215
- ? () => { void desktopWindowBridge.dockDetachedPane?.(desktopWindowBridge.paneId); }
216
+ ? () => { fireAndForget(desktopWindowBridge.dockDetachedPane?.(desktopWindowBridge.paneId), "desktop.dockDetachedPane"); }
216
217
  : null;
217
218
 
218
219
  /** The same menu as a pane in the main window, minus what a window cannot do. */
@@ -428,9 +429,11 @@ export function DetachedPaneShell({ pluginRegistry, desktopWindowBridge }: Detac
428
429
  component={paneDef.component}
429
430
  paneId={instance.instanceId}
430
431
  paneType={instance.paneId}
432
+ title={title}
431
433
  focused={focused}
432
434
  width={bodyWidth}
433
435
  height={bodyHeight}
436
+ closePane={closePane}
434
437
  />
435
438
  </PaneHeaderTabsProvider>
436
439
  </PaneBodyFrame>
@@ -31,6 +31,8 @@ interface FloatingPaneWrapperProps {
31
31
  onHeaderContextMenu?: (event: any) => void;
32
32
  onActionMouseDown?: (event: any) => void;
33
33
  onCloseMouseDown?: (event: any) => void;
34
+ onRestoreMouseDown?: (event: any) => void;
35
+ fullscreen?: boolean;
34
36
  onResizeMouseDown?: (event: any) => void;
35
37
  onResizeMouseDrag?: (event: any) => void;
36
38
  onResizeMouseDragEnd?: (event: any) => void;
@@ -80,6 +82,8 @@ export function FloatingPaneWrapper({
80
82
  onHeaderContextMenu,
81
83
  onActionMouseDown,
82
84
  onCloseMouseDown,
85
+ onRestoreMouseDown,
86
+ fullscreen = false,
83
87
  onResizeMouseDown,
84
88
  onResizeMouseDrag,
85
89
  onResizeMouseDragEnd,
@@ -137,6 +141,8 @@ export function FloatingPaneWrapper({
137
141
  onHeaderContextMenu={onHeaderContextMenu}
138
142
  onActionMouseDown={onActionMouseDown}
139
143
  onCloseMouseDown={onCloseMouseDown}
144
+ onRestoreMouseDown={onRestoreMouseDown}
145
+ fullscreen={fullscreen}
140
146
  />
141
147
 
142
148
  <PaneBodyFrame layoutProps={bodyFrame.layoutProps} backgroundColor={bg}>
@@ -239,14 +239,15 @@ function HeaderCommandPrompt({
239
239
  );
240
240
  }
241
241
 
242
- function UpdateStatus() {
242
+ function UpdateStatus({ onRestart }: { onRestart?: () => void }) {
243
243
  const colors = useThemeColors();
244
244
  const dispatch = useAppDispatch();
245
245
  const updateAvailable = useAppSelector((state) => state.updateAvailable);
246
246
  const updateProgress = useAppSelector((state) => state.updateProgress);
247
247
  const updateCheckInProgress = useAppSelector((state) => state.updateCheckInProgress);
248
248
  const updateNotice = useAppSelector((state) => state.updateNotice);
249
- const retryKey = useActionShortcut("install-update");
249
+ // One key: Restart for a downloaded update, retry for a failed one.
250
+ const updateKey = useActionShortcut("install-update");
250
251
 
251
252
  useEffect(() => {
252
253
  if (!updateNotice || updateAvailable || updateProgress || updateCheckInProgress) return;
@@ -278,15 +279,28 @@ function UpdateStatus() {
278
279
  </Box>
279
280
  );
280
281
  }
282
+ if (updateProgress.phase === "ready") {
283
+ // A desktop update waits for the user: the app never relaunches by itself.
284
+ // The terminal binary is already swapped in and only needs a new launch.
285
+ if (updateProgress.canRestart && onRestart) {
286
+ return (
287
+ <Box flexDirection="row" gap={1} alignItems="center">
288
+ <Text fg={colors.headerText}>{t("Update ready")}</Text>
289
+ <Button compact label="Restart" shortcut={updateKey || undefined} onPress={onRestart} stopPropagation />
290
+ </Box>
291
+ );
292
+ }
293
+ return <Text fg={colors.headerText}>{t("Update ready, restart to apply")}</Text>;
294
+ }
281
295
  if (updateProgress.phase === "done") {
282
- return <Text fg={colors.headerText}>{t(updateProgress.message ?? "Update installed, restart to apply")}</Text>;
296
+ return <Text fg={colors.headerText}>{t(updateProgress.message ?? "Update ready, restart to apply")}</Text>;
283
297
  }
284
298
  if (updateProgress.phase === "error") {
285
- const retry = retryKey && canRetryUpdate({ updateAvailable, updateProgress, updateCheckInProgress });
299
+ const retry = updateKey && canRetryUpdate({ updateAvailable, updateProgress, updateCheckInProgress });
286
300
  return (
287
301
  <Box flexDirection="row">
288
302
  <Text fg={colors.headerText}>{tf("Update failed: {error}", { error: updateProgress.error ?? "Unknown error" })}</Text>
289
- {retry ? <Text fg={blendHex(colors.headerText, colors.header, 0.62)}>{` ${retryKey} ${t("retry")}`}</Text> : null}
303
+ {retry ? <Text fg={blendHex(colors.headerText, colors.header, 0.62)}>{` ${updateKey} ${t("retry")}`}</Text> : null}
290
304
  </Box>
291
305
  );
292
306
  }
@@ -378,8 +392,11 @@ function HeaderMarketSummary({ nativePaneChrome, width }: { nativePaneChrome: bo
378
392
 
379
393
  export function Header({
380
394
  onOpenHelp,
395
+ onRestartForUpdate,
381
396
  }: {
382
397
  onOpenHelp?: () => void;
398
+ /** Applies a downloaded desktop update and relaunches; the header offers Restart only when it is given. */
399
+ onRestartForUpdate?: () => void;
383
400
  }) {
384
401
  const colors = useThemeColors();
385
402
  const rendererHost = useRendererHost();
@@ -444,7 +461,7 @@ export function Header({
444
461
  <Box width={prompt.left} />
445
462
  {commandPrompt}
446
463
  <Box flexGrow={1} paddingLeft={2} paddingRight={2} minWidth={0}>
447
- <UpdateStatus />
464
+ <UpdateStatus onRestart={onRestartForUpdate} />
448
465
  </Box>
449
466
  {onOpenHelp ? (
450
467
  <Box flexShrink={0} data-gloom-role="header-help-action" style={{ marginRight: 8 }}>
@@ -470,7 +487,7 @@ export function Header({
470
487
  <Box width={prompt.left} />
471
488
  {commandPrompt}
472
489
  <Box flexGrow={1} minWidth={0} paddingLeft={2}>
473
- <UpdateStatus />
490
+ <UpdateStatus onRestart={onRestartForUpdate} />
474
491
  </Box>
475
492
  {marketSummary}
476
493
  {showWindowControls ? <WindowControls /> : null}
@@ -3,7 +3,7 @@ import { Button } from "../ui/button";
3
3
  import { confirmDialog } from "../ui/confirm-dialog";
4
4
  import { EmptyState } from "../ui/status";
5
5
  import { runsExternalPlugins } from "../../plugins/current-target";
6
- import { activateInstalledPlugin } from "../../plugins/builtin/plugin-marketplace/activation";
6
+ import { activateInstall } from "../../plugins/builtin/plugin-marketplace/activation";
7
7
  import { installConsent } from "../../plugins/builtin/plugin-marketplace/model";
8
8
  import { getMarketplaceHost, getPluginManager } from "../../plugins/builtin/plugin-marketplace/store";
9
9
  import type { PaneDef, PaneProps } from "../../types/plugin";
@@ -115,7 +115,7 @@ function MissingPanePlaceholder({ paneType, width }: PaneProps) {
115
115
  // Bring it into this session so the pane replaces the placeholder rather
116
116
  // than waiting for a restart; a plugin that cannot load live says so.
117
117
  const host = getMarketplaceHost();
118
- const activated = host ? await activateInstalledPlugin(result.directory, host, installer) : null;
118
+ const activated = host ? await activateInstall(result, host, installer) : null;
119
119
  if (activated && !activated.ok) setNotice({ text: `Installed but did not load: ${activated.error}`, error: true });
120
120
  else if (!activated || activated.restart) setNotice({ text: "Installed. Restart to finish.", error: false });
121
121
  } finally {
@@ -7,6 +7,7 @@ import { useThemeColors } from "../../../theme/theme-context";
7
7
  import { PaneKeyboardScrollController } from "../../../state/pane-scroll-registry";
8
8
  import type { PaneDef } from "../../../types/plugin";
9
9
  import { Box } from "../../../ui";
10
+ import { PaneErrorBoundary } from "./error-boundary";
10
11
 
11
12
  // Under GLOOMBERB_PERF_TRACE every pane commit is reported by pane, which is
12
13
  // how a store update that fans out to the whole layout gets attributed. The
@@ -29,29 +30,39 @@ interface PaneContentProps {
29
30
  component: PaneDef["component"];
30
31
  paneId: string;
31
32
  paneType: string;
33
+ /** The header's title, named by the failure card when the pane throws. */
34
+ title: string;
32
35
  focused: boolean;
33
36
  width: number;
34
37
  height: number;
35
38
  /** False while the pane is covered on screen; its streams drop to the off-screen cadence. */
36
39
  inView?: boolean;
40
+ /** Passed to the pane as `close` (floating panes). */
37
41
  onClose?: (paneId: string) => void;
42
+ /** Takes the pane out of its layout; the failure card offers it. Keep it stable: the content is memoized. */
43
+ closePane?: (paneId: string) => void;
38
44
  }
39
45
 
40
46
  export const PaneContent = memo(function PaneContent({
41
47
  component: Component,
42
48
  paneId,
43
49
  paneType,
50
+ title,
44
51
  focused,
45
52
  width,
46
53
  height,
47
54
  inView = true,
48
55
  onClose,
56
+ closePane,
49
57
  }: PaneContentProps) {
50
58
  useAppLanguage();
51
59
  useThemeColors();
52
60
  const close = useCallback(() => {
53
61
  onClose?.(paneId);
54
62
  }, [onClose, paneId]);
63
+ const closeFailedPane = useCallback(() => {
64
+ closePane?.(paneId);
65
+ }, [closePane, paneId]);
55
66
 
56
67
  return (
57
68
  <PaneInstanceProvider paneId={paneId}>
@@ -67,16 +78,18 @@ export const PaneContent = memo(function PaneContent({
67
78
  overflow="hidden"
68
79
  data-gloom-role="pane-content"
69
80
  >
70
- <PaneRenderTrace paneId={paneId} paneType={paneType}>
71
- <Component
72
- paneId={paneId}
73
- paneType={paneType}
74
- focused={focused}
75
- width={width}
76
- height={height}
77
- close={onClose ? close : undefined}
78
- />
79
- </PaneRenderTrace>
81
+ <PaneErrorBoundary paneType={paneType} title={title} onClose={closePane ? closeFailedPane : undefined}>
82
+ <PaneRenderTrace paneId={paneId} paneType={paneType}>
83
+ <Component
84
+ paneId={paneId}
85
+ paneType={paneType}
86
+ focused={focused}
87
+ width={width}
88
+ height={height}
89
+ close={onClose ? close : undefined}
90
+ />
91
+ </PaneRenderTrace>
92
+ </PaneErrorBoundary>
80
93
  </Box>
81
94
  </PaneInViewProvider>
82
95
  </PaneInstanceProvider>
@@ -0,0 +1,103 @@
1
+ import { Component, type ErrorInfo, type ReactNode } from "react";
2
+ import { tf } from "../../../i18n";
3
+ import { getSharedRegistry } from "../../../plugins/registry/shared";
4
+ import { reportCrash } from "../../../telemetry/crash-reports";
5
+ import { debugLog } from "../../../utils/debug-log";
6
+ import { Button } from "../../ui/button";
7
+ import { PaneStatusBody } from "../../ui/status";
8
+
9
+ const MAX_MESSAGE_LENGTH = 200;
10
+
11
+ /** The first line of what was thrown, clipped: the card has one line for it. */
12
+ function failureMessage(error: unknown): string {
13
+ const raw = error instanceof Error
14
+ ? error.message || error.name
15
+ : typeof error === "string" ? error : String(error);
16
+ const line = raw.split("\n").find((part) => part.trim())?.trim() || "Unknown error";
17
+ return line.length > MAX_MESSAGE_LENGTH ? `${line.slice(0, MAX_MESSAGE_LENGTH - 3)}...` : line;
18
+ }
19
+
20
+ function failureKey(error: unknown): string {
21
+ return error instanceof Error ? `${error.name}\n${error.message}` : String(error);
22
+ }
23
+
24
+ interface PaneErrorBoundaryProps {
25
+ paneType: string;
26
+ title: string;
27
+ /** Takes the pane out of the layout; without it the card offers Reload only. */
28
+ onClose?: () => void;
29
+ children: ReactNode;
30
+ }
31
+
32
+ interface PaneErrorBoundaryState {
33
+ error: { value: unknown } | null;
34
+ }
35
+
36
+ /**
37
+ * Keeps a pane that throws while rendering inside its own frame: the pane body
38
+ * becomes a failure card with Reload and Close, and every other pane, the
39
+ * command bar and the layout keep working. The pane's header stays outside, so
40
+ * it can still be moved or closed from its menu.
41
+ *
42
+ * Only render errors reach it. Event handlers, effects and async work fail the
43
+ * way they always have.
44
+ */
45
+ export class PaneErrorBoundary extends Component<PaneErrorBoundaryProps, PaneErrorBoundaryState> {
46
+ override state: PaneErrorBoundaryState = { error: null };
47
+ private reportedKey: string | null = null;
48
+
49
+ static getDerivedStateFromError(error: unknown): PaneErrorBoundaryState {
50
+ return { error: { value: error } };
51
+ }
52
+
53
+ override componentDidCatch(error: unknown, errorInfo: ErrorInfo): void {
54
+ // A pane that fails again after Reload, or re-renders its card, is still
55
+ // the same failure: reported once.
56
+ const key = failureKey(error);
57
+ if (key === this.reportedKey) return;
58
+ this.reportedKey = key;
59
+ const { paneType } = this.props;
60
+ const plugin = getSharedRegistry()?.getPanePluginId(paneType);
61
+ reportCrash(error, { kind: "render", pane: paneType, plugin, componentStack: errorInfo.componentStack });
62
+ // Logged under the owning plugin, so the Plugins pane counts it as one of its errors.
63
+ debugLog.createLogger(plugin ?? "pane").error(`Pane ${paneType} stopped rendering: ${failureMessage(error)}`, {
64
+ componentStack: errorInfo.componentStack,
65
+ });
66
+ }
67
+
68
+ private readonly reload = () => {
69
+ this.setState({ error: null });
70
+ };
71
+
72
+ override render(): ReactNode {
73
+ const { error } = this.state;
74
+ if (!error) return this.props.children;
75
+ return (
76
+ <FallbackGuard>
77
+ <PaneStatusBody
78
+ error={failureMessage(error.value)}
79
+ errorTitle={tf("{title} stopped working.", { title: this.props.title })}
80
+ actions={(
81
+ <>
82
+ <Button label="Reload pane" variant="primary" compact onPress={this.reload} />
83
+ {this.props.onClose && <Button label="Close pane" variant="secondary" compact onPress={this.props.onClose} />}
84
+ </>
85
+ )}
86
+ />
87
+ </FallbackGuard>
88
+ );
89
+ }
90
+ }
91
+
92
+ /** A card that cannot render leaves the body empty rather than taking the app down with it. */
93
+ class FallbackGuard extends Component<{ children: ReactNode }, { failed: boolean }> {
94
+ override state = { failed: false };
95
+
96
+ static getDerivedStateFromError(): { failed: boolean } {
97
+ return { failed: true };
98
+ }
99
+
100
+ override render(): ReactNode {
101
+ return this.state.failed ? null : this.props.children;
102
+ }
103
+ }
@@ -66,17 +66,17 @@ export function PaneFooterProvider({
66
66
  const value = useMemo(() => ({ register, unregister }), [register, unregister]);
67
67
  const footer = useMemo(() => combinePaneFooterRegistrations(registrations), [registrations]);
68
68
 
69
- const [arrowClaims, setArrowClaims] = useState<ReadonlySet<string>>(() => new Set());
70
- const setArrowClaim = useCallback((id: string, claimed: boolean) => {
71
- setArrowClaims((current) => {
72
- if (current.has(id) === claimed) return current;
73
- const next = new Set(current);
74
- if (claimed) next.add(id);
75
- else next.delete(id);
76
- return next;
77
- });
78
- }, []);
79
- const arrowValue = useMemo(() => ({ claimed: arrowClaims.size > 0, setArrowClaim }), [arrowClaims, setArrowClaim]);
69
+ const [arrowClaims, setArrowClaim] = useMemberSet();
70
+ const [strips, setStrip] = useMemberSet();
71
+ const [holds, setArrowHold] = useMemberSet();
72
+ const arrowValue = useMemo<PaneArrowState>(() => ({
73
+ claimed: arrowClaims.size > 0,
74
+ strip: strips.size > 0,
75
+ held: holds.size > 0,
76
+ setArrowClaim,
77
+ setStrip,
78
+ setArrowHold,
79
+ }), [arrowClaims, holds, setArrowClaim, setArrowHold, setStrip, strips]);
80
80
 
81
81
  return (
82
82
  <PaneFooterContext.Provider value={value}>
@@ -87,22 +87,57 @@ export function PaneFooterProvider({
87
87
  );
88
88
  }
89
89
 
90
- const PaneArrowContext = createContext<{ claimed: boolean; setArrowClaim(id: string, claimed: boolean): void } | null>(null);
90
+ function useMemberSet(): [ReadonlySet<string>, (id: string, member: boolean) => void] {
91
+ const [members, setMembers] = useState<ReadonlySet<string>>(() => new Set());
92
+ const setMember = useCallback((id: string, member: boolean) => {
93
+ setMembers((current) => {
94
+ if (current.has(id) === member) return current;
95
+ const next = new Set(current);
96
+ if (member) next.add(id);
97
+ else next.delete(id);
98
+ return next;
99
+ });
100
+ }, []);
101
+ return [members, setMember];
102
+ }
103
+
104
+ interface PaneArrowState {
105
+ /** A focused tab strip owns Left, Right, h and l. */
106
+ claimed: boolean;
107
+ /** The pane has a tab strip that walks its tabs by keyboard. */
108
+ strip: boolean;
109
+ /** Content the user moved into (a chart) holds the strip's keys until Esc. */
110
+ held: boolean;
111
+ setArrowClaim(id: string, claimed: boolean): void;
112
+ setStrip(id: string, present: boolean): void;
113
+ setArrowHold(id: string, held: boolean): void;
114
+ }
115
+
116
+ const PaneArrowContext = createContext<PaneArrowState | null>(null);
117
+
118
+ function usePaneArrowMember(set: ((id: string, member: boolean) => void) | undefined, member: boolean) {
119
+ const id = useId();
120
+ useEffect(() => {
121
+ if (!set) return;
122
+ set(id, member);
123
+ return () => set(id, false);
124
+ }, [id, member, set]);
125
+ }
91
126
 
92
127
  /**
93
- * A focused tab strip owns Left and Right in its pane. It claims them here, so
94
- * a read-only chart in the same pane leaves them to the strip and the arrows
95
- * keep walking the tabs.
128
+ * A tab strip's keys. A focused strip owns Left, Right, h and l in its pane and
129
+ * claims them, so a chart in the same pane leaves them to it and the arrows
130
+ * keep walking the tabs. While content the user moved into holds them (a chart
131
+ * after Down, Enter or a click), the strip lets go until that content hands
132
+ * them back with Esc. Returns whether the strip has its keys now.
96
133
  */
97
- export function usePaneArrowClaim(claimed: boolean) {
134
+ export function usePaneTabStripKeys(navigates: boolean, focused: boolean): { active: boolean; held: boolean } {
98
135
  const context = useContext(PaneArrowContext);
99
- const id = useId();
100
- const setArrowClaim = context?.setArrowClaim;
101
- useEffect(() => {
102
- if (!setArrowClaim) return;
103
- setArrowClaim(id, claimed);
104
- return () => setArrowClaim(id, false);
105
- }, [claimed, id, setArrowClaim]);
136
+ const held = context?.held ?? false;
137
+ const active = navigates && focused && !held;
138
+ usePaneArrowMember(context?.setStrip, navigates);
139
+ usePaneArrowMember(context?.setArrowClaim, active);
140
+ return { active, held: navigates && held };
106
141
  }
107
142
 
108
143
  /** Whether a tab strip in this pane owns Left and Right. */
@@ -110,6 +145,16 @@ export function usePaneArrowsClaimed(): boolean {
110
145
  return useContext(PaneArrowContext)?.claimed ?? false;
111
146
  }
112
147
 
148
+ /** Whether this pane has a tab strip that content can hand the keys back to. */
149
+ export function usePaneHasTabStrip(): boolean {
150
+ return useContext(PaneArrowContext)?.strip ?? false;
151
+ }
152
+
153
+ /** While `held`, the pane's tab strips leave Left, Right, h and l to the caller. */
154
+ export function usePaneArrowHold(held: boolean) {
155
+ usePaneArrowMember(useContext(PaneArrowContext)?.setArrowHold, held);
156
+ }
157
+
113
158
  export function PaneFooterScope({
114
159
  active,
115
160
  children,