gloomberb 0.18.3 → 0.18.5

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 (1018) hide show
  1. package/README.md +8 -8
  2. package/README.zh-CN.md +11 -11
  3. package/bin/{gloomberb → gloom} +3 -1
  4. package/package.json +6 -2
  5. package/patches/electrobun@1.18.1.patch +32 -1
  6. package/src/account/auth-model.ts +7 -3
  7. package/src/account/checkout-handoff.tsx +225 -0
  8. package/src/account/device-signin-dialog.tsx +2 -2
  9. package/src/account/device-signin.ts +2 -2
  10. package/src/account/upgrade-dialog.tsx +1 -1
  11. package/src/api-client/askg.ts +2 -2
  12. package/src/api-client/auth.ts +11 -6
  13. package/src/api-client/catalysts.ts +2 -1
  14. package/src/api-client/central-bank-rates.ts +6 -0
  15. package/src/api-client/collections.ts +5 -1
  16. package/src/api-client/cot.ts +2 -0
  17. package/src/api-client/crypto-etf-flows.ts +37 -0
  18. package/src/api-client/crypto-markets.ts +60 -0
  19. package/src/api-client/data.ts +98 -5
  20. package/src/api-client/doe.ts +15 -0
  21. package/src/api-client/equity-screener.ts +28 -0
  22. package/src/api-client/exchange-announcements.ts +38 -0
  23. package/src/api-client/fund-facts.ts +39 -0
  24. package/src/api-client/futures-curve.ts +9 -1
  25. package/src/api-client/hiring.ts +301 -0
  26. package/src/api-client/index.ts +182 -16
  27. package/src/api-client/live-scan.ts +91 -0
  28. package/src/api-client/market-discovery.ts +14 -0
  29. package/src/api-client/members.ts +18 -0
  30. package/src/api-client/mna.ts +6 -0
  31. package/src/api-client/paths.ts +18 -1
  32. package/src/api-client/request.ts +224 -26
  33. package/src/api-client/research-activity.ts +3 -10
  34. package/src/api-client/short-side-publications.ts +37 -0
  35. package/src/api-client/socket.ts +64 -4
  36. package/src/api-client/swap-curve.ts +35 -0
  37. package/src/api-client/themes.ts +7 -1
  38. package/src/api-client/types.ts +96 -2
  39. package/src/app/keybindings/index.ts +3 -0
  40. package/src/app/keybindings/labels.ts +18 -1
  41. package/src/app/keybindings/resolve.ts +14 -0
  42. package/src/app/pane-runtime/plugin-bindings.ts +9 -2
  43. package/src/app/runtime/broker-import.ts +43 -26
  44. package/src/app/runtime/desktop-deeplink.ts +5 -5
  45. package/src/app/runtime/plugin-bindings.ts +2 -2
  46. package/src/app/runtime/startup.ts +13 -0
  47. package/src/app/star-prompt/status-line.tsx +2 -2
  48. package/src/architecture/core-builtin-allowlist.json +5 -2
  49. package/src/architecture/ui-literals-allowlist.json +3 -3
  50. package/src/architecture/ui-tokens-allowlist.json +1 -1
  51. package/src/brokers/broker-portfolio-sync.ts +37 -0
  52. package/src/brokers/directory.ts +11 -0
  53. package/src/brokers/logos.ts +3 -1
  54. package/src/brokers/signed-in/adapter.ts +304 -26
  55. package/src/brokers/signed-in/client.ts +14 -2
  56. package/src/brokers/signed-in/connect.ts +10 -2
  57. package/src/brokers/sync-broker-instance.ts +9 -1
  58. package/src/capabilities/chart-series.ts +22 -6
  59. package/src/cli/bank-section.ts +1 -1
  60. package/src/cli/base-converter.ts +23 -14
  61. package/src/cli/central-bank-events.ts +1 -1
  62. package/src/cli/command-options.ts +59 -4
  63. package/src/cli/commands/api.ts +9 -6
  64. package/src/cli/commands/broker.ts +2 -2
  65. package/src/cli/commands/command-utils.ts +2 -2
  66. package/src/cli/commands/crypto-hints.ts +7 -20
  67. package/src/cli/commands/fred-series.ts +9 -2
  68. package/src/cli/commands/keybindings.ts +25 -2
  69. package/src/cli/commands/market.ts +1177 -278
  70. package/src/cli/commands/news-hints.ts +2 -2
  71. package/src/cli/commands/news-search.ts +59 -6
  72. package/src/cli/commands/options-chain.ts +59 -3
  73. package/src/cli/commands/options-leaps.ts +41 -26
  74. package/src/cli/commands/overview.ts +222 -61
  75. package/src/cli/commands/plugins.ts +9 -9
  76. package/src/cli/commands/remote.ts +13 -10
  77. package/src/cli/commands/search.ts +82 -46
  78. package/src/cli/commands/system.ts +27 -19
  79. package/src/cli/commands/themes.ts +1 -1
  80. package/src/cli/commands/ticker.ts +194 -48
  81. package/src/cli/context.ts +3 -2
  82. package/src/cli/desktop-pane-shot-view.ts +2 -2
  83. package/src/cli/desktop-pane-shot.ts +1 -1
  84. package/src/cli/earnings-calendar.ts +4 -4
  85. package/src/cli/entry.ts +18 -1
  86. package/src/cli/errors.ts +21 -3
  87. package/src/cli/exit-codes.ts +1 -1
  88. package/src/cli/export-source.ts +38 -4
  89. package/src/cli/freshness.ts +2 -8
  90. package/src/cli/fx-forward.ts +130 -0
  91. package/src/cli/fx-pair.ts +10 -9
  92. package/src/cli/glossary.ts +113 -20
  93. package/src/cli/help.ts +19 -13
  94. package/src/cli/history-export.ts +126 -0
  95. package/src/cli/history-rows.ts +226 -50
  96. package/src/cli/index-roots.ts +5 -45
  97. package/src/cli/index.ts +24 -18
  98. package/src/cli/known-gaps.ts +123 -27
  99. package/src/cli/listing-arg.ts +316 -46
  100. package/src/cli/name-entries.ts +30 -18
  101. package/src/cli/native-smoke.ts +2 -0
  102. package/src/cli/not-a-ticker.ts +19 -9
  103. package/src/cli/opentui-libc.ts +5 -0
  104. package/src/cli/options.ts +12 -0
  105. package/src/cli/pane-functions/capabilities.ts +75 -20
  106. package/src/cli/pane-functions/catalog.ts +24 -23
  107. package/src/cli/pane-functions/discovery.ts +1 -1
  108. package/src/cli/pane-functions/dom.ts +10 -7
  109. package/src/cli/pane-functions/financial-ratio-shot.ts +2 -2
  110. package/src/cli/pane-functions/freshness.ts +193 -30
  111. package/src/cli/pane-functions/function-help.ts +76 -30
  112. package/src/cli/pane-functions/headless.ts +59 -12
  113. package/src/cli/pane-functions/index.ts +28 -19
  114. package/src/cli/pane-functions/market-session.ts +15 -5
  115. package/src/cli/pane-functions/options.ts +22 -2
  116. package/src/cli/pane-functions/report-notices.ts +12 -4
  117. package/src/cli/pane-functions/report.ts +10 -6
  118. package/src/cli/pane-functions/resolver.ts +64 -11
  119. package/src/cli/pane-functions/screenshot-assessment.ts +322 -0
  120. package/src/cli/pane-functions/screenshot-bridge.ts +152 -0
  121. package/src/cli/pane-functions/screenshot-chart-evidence.ts +396 -0
  122. package/src/cli/pane-functions/screenshot-data-evidence.ts +383 -0
  123. package/src/cli/pane-functions/screenshot-evidence.ts +1 -1
  124. package/src/cli/pane-functions/screenshot-payload.ts +453 -0
  125. package/src/cli/pane-functions/screenshot-render.ts +316 -0
  126. package/src/cli/pane-functions/screenshot-types.ts +162 -0
  127. package/src/cli/pane-functions/shot-options.ts +8 -3
  128. package/src/cli/peso-dollar-rates.ts +79 -0
  129. package/src/cli/quote-answer.ts +45 -4
  130. package/src/cli/report-tables.ts +75 -19
  131. package/src/cli/restore-plugins.ts +42 -15
  132. package/src/cli/result.ts +164 -23
  133. package/src/cli/series-search.ts +5 -5
  134. package/src/cli/statement-filings.ts +19 -0
  135. package/src/cli/suffixed-listing-rows.ts +49 -0
  136. package/src/cli/symbol-args.ts +50 -15
  137. package/src/cli/symbol-cells.ts +120 -0
  138. package/src/cli/symbol-list.ts +198 -68
  139. package/src/cli/symbol-rows.ts +131 -25
  140. package/src/cli/ticker-resolution.ts +108 -11
  141. package/src/cli/treasury-yields.ts +5 -5
  142. package/src/cli/types.ts +2 -0
  143. package/src/cli/uncovered-instrument.ts +3 -3
  144. package/src/cli/unknown-command.ts +6 -6
  145. package/src/components/chart/composite/chart-layout.ts +131 -0
  146. package/src/components/chart/composite/composite-chart.tsx +395 -20
  147. package/src/components/chart/composite/format.ts +27 -0
  148. package/src/components/chart/composite/interactions.ts +7 -2
  149. package/src/components/chart/composite/legend.tsx +75 -3
  150. package/src/components/chart/composite/levels.ts +7 -0
  151. package/src/components/chart/composite/panel-gestures.ts +41 -0
  152. package/src/components/chart/composite/panel-labels.ts +2 -1
  153. package/src/components/chart/composite/panel-series.ts +1 -0
  154. package/src/components/chart/composite/panel-surface.tsx +314 -13
  155. package/src/components/chart/composite/price-axis-labels.tsx +27 -3
  156. package/src/components/chart/composite/range-statistics.ts +62 -0
  157. package/src/components/chart/composite/rasterizer.ts +44 -19
  158. package/src/components/chart/composite/scene.ts +20 -4
  159. package/src/components/chart/composite/series-axis-tags.tsx +16 -9
  160. package/src/components/chart/composite/text-renderer.ts +48 -21
  161. package/src/components/chart/composite/toolbar.tsx +52 -5
  162. package/src/components/chart/composite/types.ts +17 -0
  163. package/src/components/chart/composite/use-composite-chart-keyboard.ts +120 -13
  164. package/src/components/chart/composite/use-composite-value-scales.ts +44 -0
  165. package/src/components/chart/composite/use-composite-viewport.ts +12 -3
  166. package/src/components/chart/composite/value-scale.ts +149 -0
  167. package/src/components/chart/composite/volume-profile-paint.ts +6 -3
  168. package/src/components/chart/core/pointer.ts +2 -0
  169. package/src/components/chart-table/index.ts +2 -0
  170. package/src/components/chart-table/read.tsx +74 -0
  171. package/src/components/command-bar/commands/collection-list.ts +41 -19
  172. package/src/components/command-bar/commands/collection.ts +9 -3
  173. package/src/components/command-bar/commands/direct/index.ts +1 -1
  174. package/src/components/command-bar/commands/direct/runtime.ts +3 -2
  175. package/src/components/command-bar/pane-templates/items.ts +59 -6
  176. package/src/components/command-bar/pane-templates/workflow.ts +10 -1
  177. package/src/components/command-bar/panel/prompt-binding.ts +0 -8
  178. package/src/components/command-bar/routes/root/plugin-install.ts +1 -1
  179. package/src/components/command-bar/routes/root/provider-search.ts +42 -11
  180. package/src/components/command-bar/routes/root/results.ts +18 -4
  181. package/src/components/command-bar/routes/root/runtime.ts +15 -3
  182. package/src/components/command-bar/routes/root/search-providers.ts +25 -2
  183. package/src/components/command-bar/routes/root/selection.ts +6 -1
  184. package/src/components/command-bar/routes/root/shortcut-feedback.ts +4 -1
  185. package/src/components/command-bar/routes/root/shortcuts.ts +30 -3
  186. package/src/components/command-bar/routes/ticker-search/results.ts +73 -4
  187. package/src/components/command-bar/selection-runtime.ts +50 -10
  188. package/src/components/command-bar/surface/index.tsx +24 -2
  189. package/src/components/command-bar/view-model.ts +7 -0
  190. package/src/components/command-bar/workflow/alert.ts +1 -1
  191. package/src/components/command-bar/workflow/broker.ts +2 -2
  192. package/src/components/command-bar/workflow/collection-actions.ts +46 -7
  193. package/src/components/command-bar/workflow/collection-ticker.ts +32 -4
  194. package/src/components/command-bar/workflow/fields.ts +8 -2
  195. package/src/components/command-bar/workflow/ops.ts +18 -4
  196. package/src/components/command-bar/workflow/portfolio-position.ts +53 -4
  197. package/src/components/command-bar/workflow/submit.ts +3 -2
  198. package/src/components/command-bar/workflow/tickers.ts +5 -1
  199. package/src/components/company-logo.tsx +39 -0
  200. package/src/components/data-table/sections.ts +4 -2
  201. package/src/components/form-modal/confirm.tsx +2 -1
  202. package/src/components/form-modal/request.ts +5 -0
  203. package/src/components/form-modal/routes.ts +4 -1
  204. package/src/components/index.ts +12 -6
  205. package/src/components/layout/header.tsx +33 -46
  206. package/src/components/layout/market-summary.ts +9 -6
  207. package/src/components/layout/pane/capture-status.ts +1 -1
  208. package/src/components/layout/pane/footer/index.tsx +1 -0
  209. package/src/components/layout/pane/footer/model.ts +38 -5
  210. package/src/components/layout/shell/chrome.ts +19 -6
  211. package/src/components/layout/shell/index.tsx +2 -1
  212. package/src/components/layout/shell/pane/layers.tsx +19 -1
  213. package/src/components/layout/status-bar.tsx +2 -2
  214. package/src/components/market-board/index.tsx +11 -3
  215. package/src/components/onboarding/onboarding-frame.tsx +1 -1
  216. package/src/components/onboarding/onboarding-wizard.tsx +1 -0
  217. package/src/components/onboarding/portfolio-step/broker-setup-panel.tsx +2 -2
  218. package/src/components/onboarding/portfolio-step/positions-panel.tsx +2 -2
  219. package/src/components/onboarding/wizard-broker-sync.ts +4 -1
  220. package/src/components/pane-settings-dialog/desktop.tsx +20 -7
  221. package/src/components/pane-settings-dialog/tui.tsx +17 -9
  222. package/src/components/pane-settings-dialog/value.ts +8 -1
  223. package/src/components/pane-settings-dialog.tsx +44 -13
  224. package/src/components/sign-in-code-panel.tsx +27 -19
  225. package/src/components/ui/column-grid.tsx +48 -4
  226. package/src/components/ui/country-flag-art.tsx +180 -0
  227. package/src/components/ui/country-flag.tsx +118 -12
  228. package/src/components/ui/data-table/opentui/index.tsx +61 -2
  229. package/src/components/ui/data-table/opentui/model.ts +109 -2
  230. package/src/components/ui/data-table/types.ts +1 -1
  231. package/src/components/ui/display.tsx +10 -2
  232. package/src/components/ui/index.ts +3 -1
  233. package/src/components/ui/logo-mark.tsx +11 -2
  234. package/src/components/ui/query-bar.tsx +1 -1
  235. package/src/components/ui/row-notes.ts +79 -0
  236. package/src/core/state/app/layout.ts +6 -4
  237. package/src/core/state/app/state.ts +9 -0
  238. package/src/core/state/app/types.ts +3 -0
  239. package/src/data/cached-query.ts +8 -1
  240. package/src/data/config/chart-settings.ts +3 -3
  241. package/src/data/config/home.ts +10 -2
  242. package/src/data/config/layout.ts +4 -1
  243. package/src/data/config/store/node.ts +4 -0
  244. package/src/data/config/store/normalize.ts +13 -3
  245. package/src/data/config/store/portfolio-as-of-column.ts +2 -2
  246. package/src/data/json-storage.ts +2 -0
  247. package/src/data/saved-copies.ts +123 -0
  248. package/src/docs/snapshot.json +422 -112
  249. package/src/i18n/es.ts +30 -13
  250. package/src/i18n/ja.ts +30 -13
  251. package/src/i18n/ko.ts +30 -13
  252. package/src/i18n/zh-cn.ts +30 -13
  253. package/src/i18n/zh-tw.ts +30 -13
  254. package/src/layout/desks.ts +1 -1
  255. package/src/layout/launch-layout.ts +1 -1
  256. package/src/layout/pane-manager/floating-actions.ts +5 -3
  257. package/src/layout/pane-manager/floating.ts +43 -1
  258. package/src/layout/pane-manager/index.ts +2 -0
  259. package/src/layout/selected-ticker.ts +74 -0
  260. package/src/market-data/coordinator/financials.ts +10 -2
  261. package/src/market-data/coordinator/index.ts +3 -1
  262. package/src/market-data/coordinator/quotes.ts +4 -2
  263. package/src/market-data/depositary-pair.ts +251 -0
  264. package/src/market-data/futures-board.ts +1 -1
  265. package/src/market-data/futures-contract.ts +124 -40
  266. package/src/market-data/fx-closes.ts +17 -2
  267. package/src/market-data/hooks.tsx +19 -11
  268. package/src/market-data/market/change-basis.ts +81 -11
  269. package/src/market-data/market/dated-previous-close.ts +203 -0
  270. package/src/market-data/market/freshness.ts +34 -5
  271. package/src/market-data/market/futures-week.ts +68 -0
  272. package/src/market-data/market/period-return.ts +163 -0
  273. package/src/market-data/market/status.ts +16 -4
  274. package/src/market-data/market/trading-sessions.ts +13 -0
  275. package/src/market-data/market/year-to-date.ts +8 -13
  276. package/src/market-data/options-alternatives.ts +60 -0
  277. package/src/market-data/performance.ts +20 -14
  278. package/src/market-data/perpetual-premium.ts +32 -0
  279. package/src/market-data/published-apac-sessions.ts +2 -1
  280. package/src/market-data/published-futures-sessions.ts +69 -0
  281. package/src/market-data/quotes/contributions.ts +25 -3
  282. package/src/market-data/quotes/freshness.ts +42 -0
  283. package/src/market-data/quotes/intraday-bar.ts +37 -0
  284. package/src/market-data/quotes/regular-session-valuation.ts +13 -8
  285. package/src/market-data/quotes/resolution.ts +7 -2
  286. package/src/market-data/selectors.ts +3 -0
  287. package/src/market-data/tax-equivalent.ts +1 -1
  288. package/src/market-data/ticker-price-returns.ts +3 -1
  289. package/src/news/aggregator.ts +5 -1
  290. package/src/news/news-model.ts +4 -0
  291. package/src/news/types.ts +11 -0
  292. package/src/notifications/app-notifier.ts +1 -1
  293. package/src/notifications/notification-log.ts +6 -4
  294. package/src/plugins/auto-update.ts +2 -2
  295. package/src/plugins/builtin/account-management/index.tsx +1 -0
  296. package/src/plugins/builtin/account-management/pane.tsx +9 -8
  297. package/src/plugins/builtin/alerts/alert-engine.ts +34 -20
  298. package/src/plugins/builtin/alerts/calendar-events.ts +429 -0
  299. package/src/plugins/builtin/alerts/cli.ts +533 -85
  300. package/src/plugins/builtin/alerts/command.ts +12 -10
  301. package/src/plugins/builtin/alerts/constants.ts +1 -1
  302. package/src/plugins/builtin/alerts/event-rows.ts +9 -5
  303. package/src/plugins/builtin/alerts/events-pane.tsx +71 -56
  304. package/src/plugins/builtin/alerts/events.ts +107 -5
  305. package/src/plugins/builtin/alerts/fired-log.ts +119 -0
  306. package/src/plugins/builtin/alerts/format.ts +10 -3
  307. package/src/plugins/builtin/alerts/headless.ts +107 -41
  308. package/src/plugins/builtin/alerts/history-pane.tsx +105 -62
  309. package/src/plugins/builtin/alerts/history-rows.ts +92 -0
  310. package/src/plugins/builtin/alerts/history.ts +2 -0
  311. package/src/plugins/builtin/alerts/index.tsx +107 -30
  312. package/src/plugins/builtin/alerts/iv-level.ts +365 -0
  313. package/src/plugins/builtin/alerts/levels.ts +3 -3
  314. package/src/plugins/builtin/alerts/live.ts +3 -3
  315. package/src/plugins/builtin/alerts/metric-command.ts +61 -0
  316. package/src/plugins/builtin/alerts/metric-data.ts +70 -0
  317. package/src/plugins/builtin/alerts/metric-model.ts +175 -0
  318. package/src/plugins/builtin/alerts/metric-parity-fixture.json +725 -0
  319. package/src/plugins/builtin/alerts/pane.tsx +130 -49
  320. package/src/plugins/builtin/alerts/price.ts +35 -0
  321. package/src/plugins/builtin/alerts/quotes.ts +24 -0
  322. package/src/plugins/builtin/alerts/research-builder.ts +84 -11
  323. package/src/plugins/builtin/alerts/research-rules.ts +76 -3
  324. package/src/plugins/builtin/alerts/scheduled-check.ts +206 -32
  325. package/src/plugins/builtin/alerts/scheduled-sources.ts +26 -3
  326. package/src/plugins/builtin/alerts/scheduled.ts +188 -29
  327. package/src/plugins/builtin/alerts/storage.ts +38 -12
  328. package/src/plugins/builtin/alerts/targets.ts +12 -3
  329. package/src/plugins/builtin/alerts/types.ts +3 -0
  330. package/src/plugins/builtin/analytics/index.tsx +8 -2
  331. package/src/plugins/builtin/analytics/metrics.ts +1 -1
  332. package/src/plugins/builtin/analytics/risk-book.ts +215 -0
  333. package/src/plugins/builtin/analytics/risk-client.ts +13 -6
  334. package/src/plugins/builtin/analytics/risk-headless.ts +55 -21
  335. package/src/plugins/builtin/analytics/risk-math.ts +6 -3
  336. package/src/plugins/builtin/analytics/risk-model.ts +297 -104
  337. package/src/plugins/builtin/analytics/risk-options.ts +17 -2
  338. package/src/plugins/builtin/analytics/risk-pane.tsx +97 -36
  339. package/src/plugins/builtin/attention/pane.tsx +6 -2
  340. package/src/plugins/builtin/awards/headless.ts +7 -3
  341. package/src/plugins/builtin/awards/model.ts +18 -0
  342. package/src/plugins/builtin/awards/pane.tsx +6 -3
  343. package/src/plugins/builtin/backtest/headless.ts +13 -8
  344. package/src/plugins/builtin/backtest/pane.tsx +9 -4
  345. package/src/plugins/builtin/backtest/presets.ts +29 -3
  346. package/src/plugins/builtin/backtest/rules.ts +41 -5
  347. package/src/plugins/builtin/broker-manager/add-flow.tsx +12 -7
  348. package/src/plugins/builtin/broker-manager/detail.tsx +47 -19
  349. package/src/plugins/builtin/broker-manager/footer.ts +27 -11
  350. package/src/plugins/builtin/broker-manager/index.tsx +24 -14
  351. package/src/plugins/builtin/broker-manager/keyboard.ts +1 -1
  352. package/src/plugins/builtin/broker-manager/model.ts +18 -3
  353. package/src/plugins/builtin/broker-manager/pane-actions.tsx +183 -57
  354. package/src/plugins/builtin/broker-manager/table.ts +28 -12
  355. package/src/plugins/builtin/broker-trading/account-picker.tsx +2 -1
  356. package/src/plugins/builtin/broker-trading/chart-levels.ts +82 -13
  357. package/src/plugins/builtin/broker-trading/controller.ts +66 -24
  358. package/src/plugins/builtin/broker-trading/dock.tsx +22 -4
  359. package/src/plugins/builtin/broker-trading/headless.ts +2 -1
  360. package/src/plugins/builtin/broker-trading/index.tsx +19 -1
  361. package/src/plugins/builtin/broker-trading/linked-orders.ts +148 -0
  362. package/src/plugins/builtin/broker-trading/order-feed.ts +83 -10
  363. package/src/plugins/builtin/broker-trading/orders.tsx +109 -31
  364. package/src/plugins/builtin/broker-trading/overview-orders.tsx +9 -3
  365. package/src/plugins/builtin/broker-trading/pane-model.ts +30 -2
  366. package/src/plugins/builtin/broker-trading/pane.tsx +111 -24
  367. package/src/plugins/builtin/broker-trading/ticket-parts.tsx +36 -7
  368. package/src/plugins/builtin/broker-trading/ticket.tsx +112 -31
  369. package/src/plugins/builtin/buildout/cells.tsx +4 -0
  370. package/src/plugins/builtin/buildout/detail/index.tsx +5 -1
  371. package/src/plugins/builtin/buildout/detail/ui.tsx +7 -4
  372. package/src/plugins/builtin/buildout/pane/index.tsx +25 -12
  373. package/src/plugins/builtin/buildout/pane/status.tsx +0 -4
  374. package/src/plugins/builtin/builtin-plugin-meta.ts +2 -2
  375. package/src/plugins/builtin/catalysts/detail.tsx +3 -2
  376. package/src/plugins/builtin/catalysts/index.tsx +1 -1
  377. package/src/plugins/builtin/catalysts/model.ts +51 -5
  378. package/src/plugins/builtin/catalysts/pane.tsx +6 -8
  379. package/src/plugins/builtin/central-bank-rates/client.ts +5 -0
  380. package/src/plugins/builtin/central-bank-rates/headless.ts +36 -10
  381. package/src/plugins/builtin/central-bank-rates/model.ts +33 -8
  382. package/src/plugins/builtin/changelog/index.tsx +1 -0
  383. package/src/plugins/builtin/chart-composer/catalog-inventory.ts +4 -1
  384. package/src/plugins/builtin/chart-composer/chart-spec-edit.ts +3 -2
  385. package/src/plugins/builtin/chart-composer/chart-spec.ts +7 -0
  386. package/src/plugins/builtin/chart-composer/cli-options.ts +7 -10
  387. package/src/plugins/builtin/chart-composer/data-catalog-pane.tsx +7 -3
  388. package/src/plugins/builtin/chart-composer/editor/controller.ts +4 -0
  389. package/src/plugins/builtin/chart-composer/editor/model.ts +2 -0
  390. package/src/plugins/builtin/chart-composer/editor.tsx +9 -4
  391. package/src/plugins/builtin/chart-composer/formula.ts +71 -18
  392. package/src/plugins/builtin/chart-composer/headless-schema.ts +42 -29
  393. package/src/plugins/builtin/chart-composer/headless.ts +266 -37
  394. package/src/plugins/builtin/chart-composer/index.tsx +12 -2
  395. package/src/plugins/builtin/chart-composer/leverage-overlay.ts +142 -0
  396. package/src/plugins/builtin/chart-composer/pane.tsx +144 -30
  397. package/src/plugins/builtin/chart-composer/presets.ts +50 -15
  398. package/src/plugins/builtin/chart-composer/quick-add.tsx +40 -25
  399. package/src/plugins/builtin/chart-composer/series-catalog.ts +1 -0
  400. package/src/plugins/builtin/chart-composer/series-expression.ts +65 -6
  401. package/src/plugins/builtin/chart-composer/session-history.ts +31 -28
  402. package/src/plugins/builtin/chart-composer/session-range.ts +4 -2
  403. package/src/plugins/builtin/chart-composer/settings.ts +31 -19
  404. package/src/plugins/builtin/chart-composer/use-series-catalog.ts +44 -31
  405. package/src/plugins/builtin/chart-composer/viewport-labels.ts +18 -8
  406. package/src/plugins/builtin/chat/attachments/model.ts +3 -1
  407. package/src/plugins/builtin/chat/content/command-suggestions.ts +92 -0
  408. package/src/plugins/builtin/chat/content/composer.tsx +13 -6
  409. package/src/plugins/builtin/chat/content/footer.tsx +6 -3
  410. package/src/plugins/builtin/chat/content/index.tsx +51 -22
  411. package/src/plugins/builtin/chat/content/open-targets.ts +14 -3
  412. package/src/plugins/builtin/chat/controller/session-runtime.ts +4 -2
  413. package/src/plugins/builtin/chat/index.tsx +23 -0
  414. package/src/plugins/builtin/chat/message/desktop.tsx +1 -0
  415. package/src/plugins/builtin/chat/message/inline-tokens.tsx +23 -0
  416. package/src/plugins/builtin/chat/message/pane-chip.tsx +50 -20
  417. package/src/plugins/builtin/chat/pane-links/commands.ts +265 -0
  418. package/src/plugins/builtin/chat/pane-links/model.ts +12 -3
  419. package/src/plugins/builtin/chat/pane-links/open.ts +9 -2
  420. package/src/plugins/builtin/chat/people.ts +1 -1
  421. package/src/plugins/builtin/chat/unread-inbox-pane.tsx +10 -1
  422. package/src/plugins/builtin/clinical-trials/client.ts +5 -2
  423. package/src/plugins/builtin/clinical-trials/model.ts +13 -4
  424. package/src/plugins/builtin/clinical-trials/pane.tsx +32 -12
  425. package/src/plugins/builtin/clinical-trials/ticker-sponsor.ts +17 -0
  426. package/src/plugins/builtin/cloud/askg/controller.ts +1 -1
  427. package/src/plugins/builtin/cloud/askg/lock-note.ts +1 -1
  428. package/src/plugins/builtin/cloud/askg/tool-display.ts +1 -1
  429. package/src/plugins/builtin/cloud/auth-commands.ts +3 -3
  430. package/src/plugins/builtin/cloud/plugin.tsx +1 -1
  431. package/src/plugins/builtin/cloud/team/pane-sections.tsx +105 -47
  432. package/src/plugins/builtin/cloud/team/pane-ui.tsx +42 -4
  433. package/src/plugins/builtin/cloud/team/pane.tsx +204 -64
  434. package/src/plugins/builtin/cloud/thesis/store.ts +45 -22
  435. package/src/plugins/builtin/cloud-tweets/registration.ts +1 -0
  436. package/src/plugins/builtin/commodities-energy/index.tsx +29 -2
  437. package/src/plugins/builtin/commodities-energy/view-state.ts +2 -0
  438. package/src/plugins/builtin/commodity-balances/pane.tsx +11 -4
  439. package/src/plugins/builtin/company-attention/app-rank.tsx +7 -5
  440. package/src/plugins/builtin/company-attention/building-model.ts +222 -0
  441. package/src/plugins/builtin/company-attention/building.tsx +172 -0
  442. package/src/plugins/builtin/company-attention/client.ts +117 -1
  443. package/src/plugins/builtin/company-attention/evidence.ts +16 -3
  444. package/src/plugins/builtin/company-attention/headless.ts +101 -5
  445. package/src/plugins/builtin/company-attention/index.tsx +6 -3
  446. package/src/plugins/builtin/company-attention/model.ts +33 -7
  447. package/src/plugins/builtin/company-attention/moves-model.ts +253 -0
  448. package/src/plugins/builtin/company-attention/moves.tsx +159 -0
  449. package/src/plugins/builtin/company-attention/pane.tsx +79 -23
  450. package/src/plugins/builtin/company-attention/signals-model.ts +229 -0
  451. package/src/plugins/builtin/company-attention/signals.tsx +160 -0
  452. package/src/plugins/builtin/company-kpis/headless.ts +3 -2
  453. package/src/plugins/builtin/company-kpis/model.ts +2 -2
  454. package/src/plugins/builtin/company-kpis/pane.tsx +1 -1
  455. package/src/plugins/builtin/composite-plugins.ts +2 -1
  456. package/src/plugins/builtin/congress-trades/headless.ts +1 -1
  457. package/src/plugins/builtin/connections/index.ts +1 -0
  458. package/src/plugins/builtin/correlation/headless-schema.ts +3 -2
  459. package/src/plugins/builtin/correlation/headless.ts +5 -3
  460. package/src/plugins/builtin/cot/headless.ts +28 -6
  461. package/src/plugins/builtin/cot/model.ts +12 -0
  462. package/src/plugins/builtin/cot/pane.tsx +3 -2
  463. package/src/plugins/builtin/cpi/headless.ts +5 -1
  464. package/src/plugins/builtin/cpi/pane.tsx +11 -9
  465. package/src/plugins/builtin/credit-boards/model.ts +2 -0
  466. package/src/plugins/builtin/credit-documents/headless.ts +1 -1
  467. package/src/plugins/builtin/crypto-board/client.ts +86 -0
  468. package/src/plugins/builtin/crypto-board/defi-view.tsx +218 -0
  469. package/src/plugins/builtin/crypto-board/defi.ts +239 -0
  470. package/src/plugins/builtin/crypto-board/headless.ts +117 -6
  471. package/src/plugins/builtin/crypto-board/index.tsx +8 -3
  472. package/src/plugins/builtin/crypto-board/model.ts +40 -8
  473. package/src/plugins/builtin/crypto-board/pane.tsx +55 -21
  474. package/src/plugins/builtin/crypto-board/series.ts +19 -1
  475. package/src/plugins/builtin/crypto-etf-flows/client.ts +60 -0
  476. package/src/plugins/builtin/crypto-etf-flows/headless.ts +132 -0
  477. package/src/plugins/builtin/crypto-etf-flows/index.tsx +44 -0
  478. package/src/plugins/builtin/crypto-etf-flows/model.ts +121 -0
  479. package/src/plugins/builtin/crypto-etf-flows/pane.tsx +193 -0
  480. package/src/plugins/builtin/debug/index.tsx +1 -0
  481. package/src/plugins/builtin/dividend-yield/index.tsx +1 -1
  482. package/src/plugins/builtin/docs/index.tsx +1 -1
  483. package/src/plugins/builtin/docs/pane.tsx +2 -2
  484. package/src/plugins/builtin/docs/targets.ts +1 -1
  485. package/src/plugins/builtin/doe/client.ts +5 -1
  486. package/src/plugins/builtin/doe/headless.ts +12 -6
  487. package/src/plugins/builtin/doe/model.ts +43 -6
  488. package/src/plugins/builtin/doe/pane.tsx +18 -11
  489. package/src/plugins/builtin/earnings/board-model.ts +13 -6
  490. package/src/plugins/builtin/earnings/board-table.ts +4 -1
  491. package/src/plugins/builtin/earnings/board.tsx +253 -50
  492. package/src/plugins/builtin/earnings/calendar-model.ts +188 -0
  493. package/src/plugins/builtin/earnings/calendar.tsx +338 -0
  494. package/src/plugins/builtin/earnings/client.ts +4 -3
  495. package/src/plugins/builtin/earnings/headless.ts +53 -15
  496. package/src/plugins/builtin/earnings/history-model.ts +53 -36
  497. package/src/plugins/builtin/earnings/index.tsx +15 -22
  498. package/src/plugins/builtin/earnings/model.ts +17 -12
  499. package/src/plugins/builtin/earnings/scope.ts +89 -0
  500. package/src/plugins/builtin/earnings-calls/calendar.tsx +310 -0
  501. package/src/plugins/builtin/earnings-calls/data.ts +146 -2
  502. package/src/plugins/builtin/earnings-calls/headless.ts +151 -9
  503. package/src/plugins/builtin/earnings-calls/index.tsx +3 -3
  504. package/src/plugins/builtin/earnings-calls/lock-note.ts +1 -1
  505. package/src/plugins/builtin/earnings-calls/pane.tsx +149 -31
  506. package/src/plugins/builtin/earnings-calls/upcoming.ts +195 -0
  507. package/src/plugins/builtin/earnings-ripple/pane.tsx +10 -5
  508. package/src/plugins/builtin/econ/calendar-model.ts +144 -27
  509. package/src/plugins/builtin/econ/detail-view.tsx +48 -10
  510. package/src/plugins/builtin/econ/figures.ts +72 -0
  511. package/src/plugins/builtin/econ/fred-catalog.ts +23 -6
  512. package/src/plugins/builtin/econ/fred-series-map.ts +4 -0
  513. package/src/plugins/builtin/econ/index.tsx +144 -27
  514. package/src/plugins/builtin/econ/print-watch.ts +2 -1
  515. package/src/plugins/builtin/econ/types.ts +34 -1
  516. package/src/plugins/builtin/econ-statistics/client.ts +16 -3
  517. package/src/plugins/builtin/econ-statistics/defs.ts +4 -0
  518. package/src/plugins/builtin/econ-statistics/detail.tsx +2 -2
  519. package/src/plugins/builtin/econ-statistics/headless.ts +87 -28
  520. package/src/plugins/builtin/econ-statistics/index.tsx +3 -3
  521. package/src/plugins/builtin/econ-statistics/pane.tsx +2 -1
  522. package/src/plugins/builtin/econ-statistics/stats.ts +104 -0
  523. package/src/plugins/builtin/econ-statistics/view.ts +19 -1
  524. package/src/plugins/builtin/equity-screener/client.ts +21 -3
  525. package/src/plugins/builtin/equity-screener/headless.ts +68 -6
  526. package/src/plugins/builtin/equity-screener/live.ts +1 -1
  527. package/src/plugins/builtin/equity-screener/model.ts +6 -0
  528. package/src/plugins/builtin/equity-screener/pane.tsx +47 -12
  529. package/src/plugins/builtin/equity-screener/screen-check.ts +90 -0
  530. package/src/plugins/builtin/equity-screener/ticker-check.tsx +148 -0
  531. package/src/plugins/builtin/estimate-revisions/headless.ts +3 -1
  532. package/src/plugins/builtin/estimate-revisions/lock-note.ts +3 -3
  533. package/src/plugins/builtin/estimate-revisions/model.ts +8 -10
  534. package/src/plugins/builtin/exposure/charts.tsx +2 -2
  535. package/src/plugins/builtin/exposure/headless.ts +51 -6
  536. package/src/plugins/builtin/exposure/index.tsx +28 -2
  537. package/src/plugins/builtin/exposure/model.ts +20 -1
  538. package/src/plugins/builtin/exposure/pane.tsx +10 -5
  539. package/src/plugins/builtin/fear-greed/index.tsx +1 -1
  540. package/src/plugins/builtin/filing-events/index.tsx +1 -1
  541. package/src/plugins/builtin/futures/index.tsx +1 -0
  542. package/src/plugins/builtin/futures/model.ts +12 -10
  543. package/src/plugins/builtin/futures/returns.ts +8 -36
  544. package/src/plugins/builtin/futures/table.tsx +3 -3
  545. package/src/plugins/builtin/futures-curve/client.ts +40 -9
  546. package/src/plugins/builtin/futures-curve/headless.ts +39 -17
  547. package/src/plugins/builtin/futures-curve/model.ts +258 -69
  548. package/src/plugins/builtin/futures-curve/pane.tsx +46 -17
  549. package/src/plugins/builtin/fx-matrix/client.ts +20 -8
  550. package/src/plugins/builtin/fx-matrix/headless.ts +37 -16
  551. package/src/plugins/builtin/fx-matrix/index.tsx +25 -13
  552. package/src/plugins/builtin/fx-matrix/live-legs.ts +34 -0
  553. package/src/plugins/builtin/fx-matrix/settings.ts +2 -1
  554. package/src/plugins/builtin/gpu/headless.ts +9 -4
  555. package/src/plugins/builtin/help/index.tsx +13 -3
  556. package/src/plugins/builtin/help/keybindings-editor.tsx +18 -14
  557. package/src/plugins/builtin/holders/beneficial-model.ts +8 -11
  558. package/src/plugins/builtin/holders/beneficial-report.ts +6 -5
  559. package/src/plugins/builtin/holders/beneficial-view.tsx +7 -3
  560. package/src/plugins/builtin/holders/client.ts +13 -1
  561. package/src/plugins/builtin/holders/format.ts +28 -17
  562. package/src/plugins/builtin/holders/headless.ts +46 -7
  563. package/src/plugins/builtin/holders/index-holders.ts +264 -0
  564. package/src/plugins/builtin/holders/pane.tsx +79 -15
  565. package/src/plugins/builtin/holders/report-rows.ts +35 -7
  566. package/src/plugins/builtin/holders/table-model.ts +2 -1
  567. package/src/plugins/builtin/holders/treemap.tsx +2 -2
  568. package/src/plugins/builtin/insider/headless.ts +1 -1
  569. package/src/plugins/builtin/insider/signals-client.ts +1 -1
  570. package/src/plugins/builtin/insider/signals.tsx +1 -1
  571. package/src/plugins/builtin/ipo-calendar/pane.tsx +7 -4
  572. package/src/plugins/builtin/iv-history/client.ts +20 -0
  573. package/src/plugins/builtin/iv-history/headless.ts +7 -4
  574. package/src/plugins/builtin/iv-history/index.tsx +1 -1
  575. package/src/plugins/builtin/iv-history/model.ts +13 -4
  576. package/src/plugins/builtin/iv-history/series.ts +3 -1
  577. package/src/plugins/builtin/jobs/lock-note.ts +1 -1
  578. package/src/plugins/builtin/jobs/model.ts +4 -15
  579. package/src/plugins/builtin/jobs/pane.tsx +7 -5
  580. package/src/plugins/builtin/jobs/share-bars.tsx +11 -5
  581. package/src/plugins/builtin/jodi/pane.tsx +10 -4
  582. package/src/plugins/builtin/layout-manager/index.tsx +1 -0
  583. package/src/plugins/builtin/macro-day/headless.ts +20 -7
  584. package/src/plugins/builtin/macro-day/index.tsx +3 -2
  585. package/src/plugins/builtin/macro-day/model.ts +29 -8
  586. package/src/plugins/builtin/macro-day/pane.tsx +51 -13
  587. package/src/plugins/builtin/macro-day/releases.ts +55 -13
  588. package/src/plugins/builtin/market-heatmap/data.ts +9 -2
  589. package/src/plugins/builtin/market-heatmap/evidence.ts +1 -1
  590. package/src/plugins/builtin/market-heatmap/headless.ts +9 -6
  591. package/src/plugins/builtin/market-heatmap/index.tsx +3 -3
  592. package/src/plugins/builtin/market-heatmap/model.ts +10 -7
  593. package/src/plugins/builtin/market-movers/client.ts +33 -19
  594. package/src/plugins/builtin/market-movers/footer.ts +2 -2
  595. package/src/plugins/builtin/market-movers/headless.ts +8 -2
  596. package/src/plugins/builtin/market-movers/index.tsx +16 -10
  597. package/src/plugins/builtin/market-movers/screener.ts +29 -8
  598. package/src/plugins/builtin/market-movers/session-body.tsx +4 -2
  599. package/src/plugins/builtin/market-movers/session-table.ts +4 -2
  600. package/src/plugins/builtin/market-movers/table.ts +4 -1
  601. package/src/plugins/builtin/market-valuation/headless.ts +2 -0
  602. package/src/plugins/builtin/market-valuation/view.ts +5 -0
  603. package/src/plugins/builtin/members/breadth-pane.tsx +81 -0
  604. package/src/plugins/builtin/members/client.ts +19 -4
  605. package/src/plugins/builtin/members/headless.ts +24 -10
  606. package/src/plugins/builtin/members/index.tsx +9 -9
  607. package/src/plugins/builtin/members/model.ts +23 -4
  608. package/src/plugins/builtin/members/pane.tsx +31 -14
  609. package/src/plugins/builtin/mna/client.ts +1 -0
  610. package/src/plugins/builtin/mna/detail.tsx +20 -32
  611. package/src/plugins/builtin/mna/distress/detail.tsx +16 -4
  612. package/src/plugins/builtin/mna/distress/model.ts +3 -2
  613. package/src/plugins/builtin/mna/distress/pane.tsx +7 -4
  614. package/src/plugins/builtin/mna/headless.ts +6 -13
  615. package/src/plugins/builtin/mna/model.ts +93 -15
  616. package/src/plugins/builtin/mna/pane.tsx +5 -4
  617. package/src/plugins/builtin/news/headless.ts +12 -6
  618. package/src/plugins/builtin/news/index.tsx +10 -1
  619. package/src/plugins/builtin/news/wire/index.tsx +3 -2
  620. package/src/plugins/builtin/news/wire/news/command-bar-search.ts +26 -10
  621. package/src/plugins/builtin/news/wire/news/query-presets.ts +6 -2
  622. package/src/plugins/builtin/news/wire/rss/cli.ts +3 -3
  623. package/src/plugins/builtin/notes/cli.ts +49 -14
  624. package/src/plugins/builtin/openfda/pane.tsx +1 -1
  625. package/src/plugins/builtin/options/analytics.ts +26 -2
  626. package/src/plugins/builtin/options/carry.ts +2 -2
  627. package/src/plugins/builtin/options/index.tsx +1 -1
  628. package/src/plugins/builtin/options/model-spot.ts +5 -2
  629. package/src/plugins/builtin/options/strike-window.ts +2 -1
  630. package/src/plugins/builtin/options/table.ts +1 -7
  631. package/src/plugins/builtin/options/view.tsx +30 -13
  632. package/src/plugins/builtin/options-calculator/headless.ts +46 -7
  633. package/src/plugins/builtin/options-positioning/client.ts +19 -0
  634. package/src/plugins/builtin/options-positioning/headless.ts +54 -14
  635. package/src/plugins/builtin/options-positioning/index.tsx +3 -3
  636. package/src/plugins/builtin/options-positioning/model.ts +47 -8
  637. package/src/plugins/builtin/options-positioning/pane.tsx +68 -38
  638. package/src/plugins/builtin/options-scenario/client.ts +123 -28
  639. package/src/plugins/builtin/options-scenario/collar.ts +8 -6
  640. package/src/plugins/builtin/options-scenario/csp-screen-headless.ts +127 -0
  641. package/src/plugins/builtin/options-scenario/csp-screen-pane.tsx +165 -0
  642. package/src/plugins/builtin/options-scenario/csp-screen.ts +258 -0
  643. package/src/plugins/builtin/options-scenario/csp.ts +101 -21
  644. package/src/plugins/builtin/options-scenario/headless.ts +36 -15
  645. package/src/plugins/builtin/options-scenario/hedge.ts +20 -14
  646. package/src/plugins/builtin/options-scenario/index.tsx +28 -3
  647. package/src/plugins/builtin/options-scenario/model.ts +13 -0
  648. package/src/plugins/builtin/options-scenario/pane.tsx +9 -5
  649. package/src/plugins/builtin/perps/equity-row.tsx +11 -3
  650. package/src/plugins/builtin/perps/freshness.ts +14 -9
  651. package/src/plugins/builtin/perps/headless.ts +3 -1
  652. package/src/plugins/builtin/perps/list-perpetuals.ts +25 -4
  653. package/src/plugins/builtin/perps/live-rows.ts +168 -0
  654. package/src/plugins/builtin/perps/markets-section.tsx +154 -0
  655. package/src/plugins/builtin/perps/pane.tsx +49 -26
  656. package/src/plugins/builtin/perps/venue-markets.ts +96 -0
  657. package/src/plugins/builtin/plugin-marketplace/index.tsx +2 -1
  658. package/src/plugins/builtin/plugin-marketplace/pane.tsx +143 -59
  659. package/src/plugins/builtin/portfolio-list/cli/bulk-symbols.ts +72 -24
  660. package/src/plugins/builtin/portfolio-list/cli/portfolio-command.ts +158 -141
  661. package/src/plugins/builtin/portfolio-list/cli/render.ts +54 -22
  662. package/src/plugins/builtin/portfolio-list/cli/shared.ts +3 -3
  663. package/src/plugins/builtin/portfolio-list/cli/watchlist-command.ts +29 -24
  664. package/src/plugins/builtin/portfolio-list/headless.ts +7 -4
  665. package/src/plugins/builtin/portfolio-list/income.ts +13 -2
  666. package/src/plugins/builtin/portfolio-list/index.tsx +9 -2
  667. package/src/plugins/builtin/portfolio-list/pane/index.tsx +21 -8
  668. package/src/plugins/builtin/portfolio-list/pane/purchase-date-fx.ts +46 -0
  669. package/src/plugins/builtin/portfolio-list/summary/index.tsx +11 -8
  670. package/src/plugins/builtin/portfolio-list/summary/live-accounts.ts +16 -9
  671. package/src/plugins/builtin/portfolio-list/summary/totals.ts +2 -15
  672. package/src/plugins/builtin/power/client.ts +4 -1
  673. package/src/plugins/builtin/power/evidence.ts +22 -7
  674. package/src/plugins/builtin/power/gas.tsx +5 -1
  675. package/src/plugins/builtin/power/pane.tsx +8 -1
  676. package/src/plugins/builtin/power/prices.tsx +10 -3
  677. package/src/plugins/builtin/rate-path/pane.tsx +2 -2
  678. package/src/plugins/builtin/research/analyst-headless.ts +25 -8
  679. package/src/plugins/builtin/research/analyst-model.ts +68 -3
  680. package/src/plugins/builtin/research/corporate-actions-pane.tsx +63 -14
  681. package/src/plugins/builtin/research/event-model.ts +3 -1
  682. package/src/plugins/builtin/research/event-sources.ts +12 -4
  683. package/src/plugins/builtin/research/index.tsx +2 -1
  684. package/src/plugins/builtin/research/relative-valuation-basis.ts +58 -0
  685. package/src/plugins/builtin/research/relative-valuation-columns.ts +31 -2
  686. package/src/plugins/builtin/research/relative-valuation-currency.ts +12 -5
  687. package/src/plugins/builtin/research/relative-valuation-headless.ts +84 -26
  688. package/src/plugins/builtin/research/relative-valuation-model.ts +88 -19
  689. package/src/plugins/builtin/research/relative-valuation-pane.tsx +80 -13
  690. package/src/plugins/builtin/research/relative-valuation-peers.ts +1 -1
  691. package/src/plugins/builtin/reverse-dcf/model.ts +6 -2
  692. package/src/plugins/builtin/risk-factors/index.tsx +2 -2
  693. package/src/plugins/builtin/scanner/feed.ts +2 -2
  694. package/src/plugins/builtin/scanner/index.ts +24 -1
  695. package/src/plugins/builtin/scanner/live-condition-editor.tsx +222 -0
  696. package/src/plugins/builtin/scanner/live-feed.ts +168 -0
  697. package/src/plugins/builtin/scanner/live-headless.ts +114 -0
  698. package/src/plugins/builtin/scanner/live-model.ts +351 -0
  699. package/src/plugins/builtin/scanner/live-pane.tsx +677 -0
  700. package/src/plugins/builtin/scanner/live-track.ts +186 -0
  701. package/src/plugins/builtin/scanner/lock-note.ts +1 -1
  702. package/src/plugins/builtin/sec/forms.ts +13 -0
  703. package/src/plugins/builtin/sec/fund-abroad.ts +32 -0
  704. package/src/plugins/builtin/sec/fund-facts.ts +68 -8
  705. package/src/plugins/builtin/sec/headless.ts +85 -8
  706. package/src/plugins/builtin/sec/index.tsx +58 -12
  707. package/src/plugins/builtin/sectors/client.ts +2 -1
  708. package/src/plugins/builtin/sectors/sector-model.ts +11 -15
  709. package/src/plugins/builtin/series-inventory.ts +3 -0
  710. package/src/plugins/builtin/shared/broker-reconnect.ts +107 -22
  711. package/src/plugins/builtin/shared/cloud-upgrade.ts +34 -6
  712. package/src/plugins/builtin/shared/earnings-calendar.ts +375 -0
  713. package/src/plugins/builtin/{earnings/estimate-basis.ts → shared/earnings-estimate-basis.ts} +1 -1
  714. package/src/plugins/builtin/shared/earnings-report.ts +3 -3
  715. package/src/plugins/builtin/shared/fx-rate-freshness.ts +23 -1
  716. package/src/plugins/builtin/shared/job-posting.ts +129 -0
  717. package/src/plugins/builtin/shared/macro-releases.ts +65 -0
  718. package/src/plugins/builtin/shared/pro-lock-note.ts +3 -3
  719. package/src/plugins/builtin/shared/report-freshness.ts +3 -0
  720. package/src/plugins/builtin/shared/research-trading.tsx +21 -0
  721. package/src/plugins/builtin/shared/scanner-capture.ts +3 -0
  722. package/src/plugins/builtin/shared/series-cache.ts +2 -0
  723. package/src/plugins/builtin/shared/ticker-surface.ts +2 -1
  724. package/src/plugins/builtin/shared/use-quote-board.ts +8 -2
  725. package/src/plugins/builtin/shared/volatility/pricing.ts +7 -1
  726. package/src/plugins/builtin/short-interest/client.ts +2 -0
  727. package/src/plugins/builtin/short-interest/headless.ts +41 -12
  728. package/src/plugins/builtin/short-interest/index.tsx +23 -1
  729. package/src/plugins/builtin/short-interest/model.ts +70 -19
  730. package/src/plugins/builtin/short-interest/pane.tsx +19 -2
  731. package/src/plugins/builtin/short-interest/publications-client.ts +82 -0
  732. package/src/plugins/builtin/short-interest/publications-headless.ts +29 -0
  733. package/src/plugins/builtin/short-interest/publications-model.ts +50 -0
  734. package/src/plugins/builtin/short-interest/publications-pane.tsx +66 -0
  735. package/src/plugins/builtin/short-interest/schedule.ts +35 -2
  736. package/src/plugins/builtin/short-interest/surface.tsx +11 -4
  737. package/src/plugins/builtin/short-interest/types.ts +9 -0
  738. package/src/plugins/builtin/short-interest/watch-client.ts +14 -8
  739. package/src/plugins/builtin/short-interest/watch-model.ts +12 -25
  740. package/src/plugins/builtin/short-interest/watch-pane.tsx +5 -1
  741. package/src/plugins/builtin/supply-chain/flow.tsx +33 -9
  742. package/src/plugins/builtin/supply-chain/model.ts +51 -3
  743. package/src/plugins/builtin/supply-chain/pane.tsx +78 -39
  744. package/src/plugins/builtin/supply-chain/row-evidence.tsx +1 -1
  745. package/src/plugins/builtin/themes/headless.ts +11 -6
  746. package/src/plugins/builtin/themes/model.ts +15 -5
  747. package/src/plugins/builtin/themes/pane.tsx +27 -8
  748. package/src/plugins/builtin/thirteenf/headless.ts +5 -5
  749. package/src/plugins/builtin/thirteenf/signals.ts +3 -1
  750. package/src/plugins/builtin/ticker-detail/adr-pair/headless.ts +123 -0
  751. package/src/plugins/builtin/ticker-detail/adr-pair/model.ts +132 -0
  752. package/src/plugins/builtin/ticker-detail/adr-pair/tab.tsx +87 -0
  753. package/src/plugins/builtin/ticker-detail/data-panes/historical-prices.tsx +40 -26
  754. package/src/plugins/builtin/ticker-detail/data-panes/history-bars.ts +8 -4
  755. package/src/plugins/builtin/ticker-detail/data-panes/returns-history.ts +67 -3
  756. package/src/plugins/builtin/ticker-detail/data-panes/returns-model.ts +112 -5
  757. package/src/plugins/builtin/ticker-detail/data-panes/returns-pane.tsx +17 -2
  758. package/src/plugins/builtin/ticker-detail/financials/aggregation.ts +21 -7
  759. package/src/plugins/builtin/ticker-detail/financials/model.ts +36 -1
  760. package/src/plugins/builtin/ticker-detail/financials/offerings.ts +56 -0
  761. package/src/plugins/builtin/ticker-detail/financials/ratios.ts +62 -13
  762. package/src/plugins/builtin/ticker-detail/financials/tab.tsx +30 -4
  763. package/src/plugins/builtin/ticker-detail/headless-schema.ts +14 -2
  764. package/src/plugins/builtin/ticker-detail/headless.ts +148 -35
  765. package/src/plugins/builtin/ticker-detail/index.tsx +37 -5
  766. package/src/plugins/builtin/ticker-detail/overview/model.ts +65 -10
  767. package/src/plugins/builtin/ticker-detail/overview/pane.tsx +9 -1
  768. package/src/plugins/builtin/ticker-detail/overview-tab.tsx +68 -11
  769. package/src/plugins/builtin/ticker-detail/pane.tsx +11 -0
  770. package/src/plugins/builtin/ticker-detail/quote-footer.ts +14 -4
  771. package/src/plugins/builtin/ticker-detail/research-tabs.ts +11 -0
  772. package/src/plugins/builtin/vol-surface/charts.tsx +9 -4
  773. package/src/plugins/builtin/vol-surface/client.ts +7 -4
  774. package/src/plugins/builtin/vol-surface/headless.ts +71 -13
  775. package/src/plugins/builtin/vol-surface/index.tsx +2 -2
  776. package/src/plugins/builtin/vol-surface/model.ts +26 -9
  777. package/src/plugins/builtin/vol-surface/pane.tsx +44 -7
  778. package/src/plugins/builtin/vol-surface/tables.ts +31 -3
  779. package/src/plugins/builtin/volatility/dvol.ts +46 -0
  780. package/src/plugins/builtin/volatility/model.ts +5 -10
  781. package/src/plugins/builtin/volatility/pane.tsx +2 -2
  782. package/src/plugins/builtin/volatility/series.ts +26 -0
  783. package/src/plugins/builtin/world-indices/footer.ts +1 -1
  784. package/src/plugins/builtin/world-venue-map/basemap-layer.tsx +4 -3
  785. package/src/plugins/builtin/world-venue-map/basemap.ts +3 -1
  786. package/src/plugins/builtin/world-venue-map/chokepoint-chart.ts +40 -0
  787. package/src/plugins/builtin/world-venue-map/evidence.ts +1 -1
  788. package/src/plugins/builtin/world-venue-map/geo-series.ts +90 -11
  789. package/src/plugins/builtin/world-venue-map/headless.ts +1 -1
  790. package/src/plugins/builtin/world-venue-map/index.ts +3 -26
  791. package/src/plugins/builtin/world-venue-map/layers.ts +1 -1
  792. package/src/plugins/builtin/world-venue-map/map.tsx +2 -1
  793. package/src/plugins/builtin/world-venue-map/pane.tsx +4 -2
  794. package/src/plugins/builtin/world-venue-map/venue-header.tsx +15 -4
  795. package/src/plugins/builtin/yield-curve/client.ts +25 -0
  796. package/src/plugins/builtin/yield-curve/curves.ts +7 -4
  797. package/src/plugins/builtin/yield-curve/headless.ts +38 -4
  798. package/src/plugins/builtin/yield-curve/history.ts +4 -3
  799. package/src/plugins/builtin/yield-curve/index.tsx +12 -6
  800. package/src/plugins/builtin/yield-curve/swaps-model.ts +93 -0
  801. package/src/plugins/builtin/yield-curve/swaps.tsx +99 -0
  802. package/src/plugins/bundle.ts +1 -1
  803. package/src/plugins/catalog-browser.ts +15 -9
  804. package/src/plugins/compat.ts +3 -3
  805. package/src/plugins/dependencies.ts +75 -14
  806. package/src/plugins/extracted-plugins.ts +132 -34
  807. package/src/plugins/host-link.ts +149 -34
  808. package/src/plugins/installer.ts +35 -10
  809. package/src/plugins/loader.ts +206 -38
  810. package/src/plugins/manager-node.ts +2 -2
  811. package/src/plugins/marketplace/deactivation.ts +22 -0
  812. package/src/plugins/marketplace/model.ts +2 -2
  813. package/src/plugins/marketplace/packs.ts +1 -1
  814. package/src/plugins/ownership.ts +1 -1
  815. package/src/plugins/peer-retry.ts +155 -0
  816. package/src/plugins/registry/contributions.ts +3 -1
  817. package/src/plugins/registry/index.ts +4 -3
  818. package/src/plugins/registry/plugin-state.ts +3 -0
  819. package/src/plugins/seed-notice.ts +20 -0
  820. package/src/plugins/shortcut-argument.ts +39 -0
  821. package/src/portfolio/allocation.ts +1 -1
  822. package/src/portfolio/collection-name.ts +31 -0
  823. package/src/portfolio/column-values.ts +15 -13
  824. package/src/portfolio/cost-fx.ts +296 -19
  825. package/src/portfolio/manual-lots.ts +75 -0
  826. package/src/portfolio/mutations.ts +60 -22
  827. package/src/portfolio/suffixed-listings.ts +209 -0
  828. package/src/portfolio/totals-currency.ts +24 -0
  829. package/src/public/__snapshots__/public-api.test.ts.snap +15 -0
  830. package/src/public/time-series.ts +11 -8
  831. package/src/remote/schema.ts +1 -1
  832. package/src/renderers/browser/app-services.ts +1 -7
  833. package/src/renderers/browser/config-host.ts +5 -55
  834. package/src/renderers/browser/main.tsx +30 -60
  835. package/src/renderers/dom/boot-frame-page.ts +187 -0
  836. package/src/renderers/dom/boot-frame.ts +237 -0
  837. package/src/renderers/dom/build-assets.ts +46 -8
  838. package/src/renderers/dom/dom-ui-host.tsx +4 -29
  839. package/src/renderers/dom/host/ascii-text.ts +16 -2
  840. package/src/renderers/dom/host/box.tsx +43 -2
  841. package/src/renderers/dom/host/chart-surface.tsx +2 -0
  842. package/src/renderers/dom/host/hls.chunk.ts +3 -0
  843. package/src/renderers/dom/host/image-surface.tsx +49 -0
  844. package/src/renderers/dom/host/media-surface.tsx +24 -18
  845. package/src/renderers/dom/host/mouse.ts +30 -0
  846. package/src/renderers/dom/host/size-observer.ts +1 -1
  847. package/src/renderers/dom/host/style.ts +1 -1
  848. package/src/renderers/dom/styles.css +76 -0
  849. package/src/renderers/dom/test-utils.tsx +2 -1
  850. package/src/renderers/electrobun/bun/application-menu/index.ts +3 -3
  851. package/src/renderers/electrobun/bun/desktop/app-name.ts +222 -0
  852. package/src/renderers/electrobun/bun/desktop/backend-requests.ts +3 -0
  853. package/src/renderers/electrobun/bun/desktop/backend.ts +56 -3
  854. package/src/renderers/electrobun/bun/desktop/detached-windows.ts +1 -1
  855. package/src/renderers/electrobun/bun/desktop/host-requests.ts +9 -3
  856. package/src/renderers/electrobun/bun/desktop/initialization.ts +81 -18
  857. package/src/renderers/electrobun/bun/desktop/relaunch.ts +74 -25
  858. package/src/renderers/electrobun/bun/desktop/state-broadcaster.ts +1 -0
  859. package/src/renderers/electrobun/bun/desktop/update.ts +70 -3
  860. package/src/renderers/electrobun/bun/desktop/workspace/index.ts +2 -0
  861. package/src/renderers/electrobun/bun/external-plugins.ts +29 -7
  862. package/src/renderers/electrobun/bun/index.ts +36 -2
  863. package/src/renderers/electrobun/bun/window/boot-frame.ts +67 -0
  864. package/src/renderers/electrobun/bun/window/create.ts +4 -1
  865. package/src/renderers/electrobun/shared/app-name.ts +17 -0
  866. package/src/renderers/electrobun/shared/boot-frame.ts +7 -0
  867. package/src/renderers/electrobun/shared/protocol.ts +6 -1
  868. package/src/renderers/electrobun/view/cli-pane-shot-entry.tsx +1 -1
  869. package/src/renderers/electrobun/view/cli-pane-shot-frame.tsx +3 -3
  870. package/src/renderers/electrobun/view/config-host.ts +3 -0
  871. package/src/renderers/electrobun/view/desktop/window/snapshot.ts +1 -0
  872. package/src/renderers/electrobun/view/fatal-screen.tsx +1 -1
  873. package/src/renderers/electrobun/view/main.tsx +30 -4
  874. package/src/renderers/electrobun/view/news-source.ts +5 -5
  875. package/src/renderers/electrobun/view/remote/asset-data-client.ts +1 -1
  876. package/src/renderers/electrobun/view/ui-host.tsx +1 -1
  877. package/src/renderers/opentui/browser-open.ts +88 -0
  878. package/src/renderers/opentui/host.tsx +5 -14
  879. package/src/renderers/opentui/image/loader.ts +3 -2
  880. package/src/renderers/opentui/native-smoke.ts +10 -1
  881. package/src/renderers/opentui/pane-image/index.ts +2 -1
  882. package/src/renderers/opentui/render-lib.ts +253 -0
  883. package/src/renderers/opentui/render-timing-smoke.ts +1 -1
  884. package/src/renderers/opentui/start.tsx +1 -1
  885. package/src/renderers/opentui/toast-host.tsx +71 -43
  886. package/src/renderers/share/layout-view.tsx +2 -2
  887. package/src/renderers/share/main.tsx +4 -4
  888. package/src/renderers/share/view.tsx +1 -1
  889. package/src/series/resolve.ts +22 -6
  890. package/src/series/standalone.ts +30 -2
  891. package/src/series/types.ts +8 -1
  892. package/src/shares/api.ts +4 -1
  893. package/src/shares/pane.ts +1 -1
  894. package/src/sources/gloomberb-cloud/fred-series.ts +46 -1
  895. package/src/sources/gloomberb-cloud/index.ts +32 -16
  896. package/src/sources/gloomberb-cloud/news.ts +39 -0
  897. package/src/sources/gloomberb-cloud/normalizers.ts +16 -1
  898. package/src/sources/gloomberb-cloud/perpetuals.ts +49 -1
  899. package/src/sources/listing-symbols.ts +37 -0
  900. package/src/sources/provider-errors.ts +16 -2
  901. package/src/sources/provider-router/batches.ts +10 -2
  902. package/src/sources/provider-router/financial-routes.ts +21 -3
  903. package/src/sources/provider-router/financials.ts +15 -2
  904. package/src/sources/provider-router/history.ts +58 -15
  905. package/src/sources/provider-router/index.ts +146 -10
  906. package/src/sources/provider-router/primary.ts +1 -1
  907. package/src/sources/provider-router/search.ts +13 -2
  908. package/src/state/app/bootstrap.ts +23 -0
  909. package/src/state/app/context/index.tsx +3 -0
  910. package/src/state/hooks/inline-tickers.ts +30 -5
  911. package/src/sync/auth-transition.ts +19 -9
  912. package/src/sync/baseline.ts +10 -4
  913. package/src/sync/controller.ts +67 -17
  914. package/src/sync/core-contributors.ts +46 -14
  915. package/src/sync/react.ts +4 -1
  916. package/src/sync/types.ts +3 -0
  917. package/src/team/collections-sync.ts +2 -1
  918. package/src/team/collections.ts +178 -17
  919. package/src/telemetry/crash-reports.ts +17 -4
  920. package/src/telemetry/usage-counts.ts +0 -18
  921. package/src/test-support/builtin-panes.ts +1 -1
  922. package/src/theme/colors.ts +11 -30
  923. package/src/theme/ui-tokens.ts +37 -1
  924. package/src/tickers/company-name-listing.ts +210 -33
  925. package/src/tickers/company-name.ts +59 -0
  926. package/src/tickers/index-roots.ts +47 -0
  927. package/src/tickers/instrument-label.ts +5 -1
  928. package/src/tickers/listing-venues.ts +23 -0
  929. package/src/tickers/metadata.ts +10 -0
  930. package/src/tickers/perpetual-listing.ts +5 -2
  931. package/src/tickers/search/bare-symbol.ts +36 -0
  932. package/src/tickers/search/home-listing.ts +75 -0
  933. package/src/tickers/search/index.ts +111 -33
  934. package/src/tickers/search/ranking.ts +64 -5
  935. package/src/tickers/search/types.ts +5 -0
  936. package/src/tickers/search/upsert.ts +29 -0
  937. package/src/tickers/terminal-codes.ts +416 -40
  938. package/src/time-series/bar-aggregation.ts +243 -0
  939. package/src/time-series/base-series.ts +315 -0
  940. package/src/time-series/chart-bounds.ts +349 -0
  941. package/src/time-series/chart-seed.ts +142 -0
  942. package/src/time-series/daily-valuation.ts +62 -0
  943. package/src/time-series/economic.ts +5 -0
  944. package/src/time-series/field-catalog.ts +1 -3
  945. package/src/time-series/forward-valuation.ts +32 -0
  946. package/src/time-series/fundamentals.ts +173 -10
  947. package/src/time-series/history-acquisition.ts +499 -0
  948. package/src/time-series/hooks.ts +1 -0
  949. package/src/time-series/leverage.ts +100 -0
  950. package/src/time-series/market-resolution.ts +4 -2
  951. package/src/time-series/market.ts +2 -1
  952. package/src/time-series/price-comparison.ts +175 -30
  953. package/src/time-series/price-units.ts +72 -2
  954. package/src/time-series/range.ts +9 -1
  955. package/src/time-series/resolution.ts +174 -16
  956. package/src/time-series/resolve-context.ts +161 -0
  957. package/src/time-series/resolve.ts +185 -1587
  958. package/src/time-series/series-name.ts +38 -0
  959. package/src/time-series/series-presentation.ts +242 -0
  960. package/src/time-series/spec.ts +13 -7
  961. package/src/time-series/studies.ts +377 -82
  962. package/src/time-series/tail-reconcile.ts +121 -0
  963. package/src/time-series/transforms.ts +1 -0
  964. package/src/time-series/types.ts +34 -2
  965. package/src/time-series/use-chart-resolution.ts +4 -5
  966. package/src/time-series/valuation-releases.ts +39 -0
  967. package/src/types/broker.ts +10 -0
  968. package/src/types/config.ts +14 -0
  969. package/src/types/data-provider.ts +23 -1
  970. package/src/types/desktop-window.ts +2 -0
  971. package/src/types/exchange-rate.ts +6 -0
  972. package/src/types/financials.ts +145 -8
  973. package/src/types/headless.ts +117 -9
  974. package/src/types/instrument.ts +6 -0
  975. package/src/types/plugin.ts +66 -9
  976. package/src/types/price-history.ts +2 -0
  977. package/src/types/ticker.ts +13 -0
  978. package/src/types/trading.ts +59 -1
  979. package/src/ui/ascii-font.ts +13 -1
  980. package/src/ui/host.tsx +6 -1
  981. package/src/updater/command-names.ts +180 -0
  982. package/src/updater/index.ts +10 -5
  983. package/src/utils/calendar-date.ts +32 -15
  984. package/src/utils/cash-runway.ts +241 -0
  985. package/src/utils/central-banks.ts +42 -0
  986. package/src/utils/cli-output.ts +259 -80
  987. package/src/utils/contract-month.ts +16 -0
  988. package/src/utils/crypto-pair.ts +61 -3
  989. package/src/utils/currency-units.ts +29 -0
  990. package/src/utils/datetime-format.ts +10 -0
  991. package/src/utils/debug-log.ts +1 -1
  992. package/src/utils/decimal-comma.ts +39 -6
  993. package/src/utils/exchange-announcements.ts +71 -0
  994. package/src/utils/exchange-rate-snapshot.ts +10 -0
  995. package/src/utils/financial-statements.ts +89 -5
  996. package/src/utils/format.ts +34 -16
  997. package/src/utils/fundamentals.ts +150 -34
  998. package/src/utils/fx-market-hours.ts +10 -1
  999. package/src/utils/latest-financial-period.ts +8 -0
  1000. package/src/utils/linux-libc.ts +54 -0
  1001. package/src/utils/market-capitalization.ts +111 -15
  1002. package/src/utils/max-drawdown.ts +64 -0
  1003. package/src/utils/network-failure.ts +86 -0
  1004. package/src/utils/option-expiry.ts +186 -7
  1005. package/src/utils/options.ts +10 -0
  1006. package/src/utils/plugin-proxy-hosts.json +1 -0
  1007. package/src/utils/price-earnings.ts +11 -5
  1008. package/src/utils/price-history.ts +23 -8
  1009. package/src/utils/price-window.ts +131 -0
  1010. package/src/utils/release-date.ts +47 -0
  1011. package/src/utils/sec.ts +3 -0
  1012. package/src/utils/throttled-fetch.ts +11 -4
  1013. package/src/utils/trailing-eps.ts +67 -0
  1014. package/src/utils/typed-text.ts +21 -0
  1015. package/src/utils/utc-time.ts +24 -1
  1016. package/src/version.ts +6 -0
  1017. package/src/cli/pane-functions/screenshot.ts +0 -2122
  1018. package/src/renderers/browser/first-screen.ts +0 -193
@@ -28,6 +28,7 @@ function desktopStateKey(snapshot: DesktopSharedStateSnapshot): string {
28
28
  paneState: snapshot.paneState,
29
29
  focusedPaneId: snapshot.focusedPaneId,
30
30
  statusBarVisible: snapshot.statusBarVisible,
31
+ brokerSyncErrors: snapshot.brokerSyncErrors ?? {},
31
32
  });
32
33
  }
33
34
 
@@ -33,13 +33,14 @@ import {
33
33
  import { logFailure } from "../../../../utils/log-failure";
34
34
  import { compareSemver, isPrereleaseVersion } from "../../../../utils/semver";
35
35
  import { VERSION } from "../../../../version";
36
+ import { DESKTOP_APP_NAME, LEGACY_DESKTOP_APP_NAME } from "../../shared/app-name";
36
37
 
37
38
  type ElectrobunUpdater = typeof Electrobun.Updater;
38
39
 
39
40
  /**
40
41
  * The part of Electrobun's updater this flow uses. Tests pass a fake, because
41
42
  * the real module cannot be loaded or exercised outside the packaged app.
42
- * `setUpdateSource` is Gloomberb's patch (patches/electrobun@*.patch).
43
+ * `setUpdateSource` is this app's patch (patches/electrobun@*.patch).
43
44
  */
44
45
  export type ElectrobunUpdaterApi = Pick<
45
46
  ElectrobunUpdater,
@@ -51,7 +52,7 @@ export type ElectrobunUpdaterApi = Pick<
51
52
  | "getStatusHistory"
52
53
  | "onStatusChange"
53
54
  | "setUpdateSource"
54
- > & {
55
+ > & Partial<Pick<ElectrobunUpdater, "appDataFolder">> & {
55
56
  localInfo: Pick<ElectrobunUpdater["localInfo"], "channel" | "baseUrl">;
56
57
  };
57
58
 
@@ -81,6 +82,8 @@ function isUpdateAside(entry: string, appName: string): boolean {
81
82
  * process runs from: starting from it means the install that left them worked.
82
83
  * macOS keeps the app in its bundle, Linux in `<app data>/app` (`bin/bun`
83
84
  * inside it); Windows installs through its own script and leaves none.
85
+ * Beside `Gloom.app` it also takes `Gloomberb.app.previous`: the copy the
86
+ * update that brought the new name moved aside, under the old one.
84
87
  * Resolves to the paths it removed.
85
88
  */
86
89
  export async function removeUpdateAsides(
@@ -92,9 +95,12 @@ export async function removeUpdateAsides(
92
95
  : platform === "linux" && basename(dirname(execPath)) === "bin" ? dirname(dirname(execPath)) : undefined;
93
96
  if (!app) return [];
94
97
  const folder = dirname(app);
98
+ const names = platform === "darwin" && basename(app) === `${DESKTOP_APP_NAME}.app`
99
+ ? [basename(app), `${LEGACY_DESKTOP_APP_NAME}.app`]
100
+ : [basename(app)];
95
101
  const removed: string[] = [];
96
102
  for (const entry of await readdir(folder).catch(() => [] as string[])) {
97
- if (!isUpdateAside(entry, basename(app))) continue;
103
+ if (!names.some((name) => isUpdateAside(entry, name))) continue;
98
104
  const path = join(folder, entry);
99
105
  // One that still cannot be removed (another user's) is tried again at the next start.
100
106
  const done = await rm(path, { recursive: true, force: true }).then(() => true, logFailure("desktop-update", "Could not remove an old copy of the app", false));
@@ -103,6 +109,65 @@ export async function removeUpdateAsides(
103
109
  return removed;
104
110
  }
105
111
 
112
+ const TAR_BLOCK = 512;
113
+
114
+ /**
115
+ * The first path in a tar, read from its leading headers: a ustar name and
116
+ * prefix, or the long name a pax (`x`) or GNU (`L`) header gives it. Null when
117
+ * `bytes` ends before one.
118
+ */
119
+ export function firstTarPath(bytes: Uint8Array): string | null {
120
+ const decoder = new TextDecoder();
121
+ const field = (start: number, length: number) => {
122
+ const raw = bytes.subarray(start, start + length);
123
+ const end = raw.indexOf(0);
124
+ return decoder.decode(end === -1 ? raw : raw.subarray(0, end));
125
+ };
126
+ let longName: string | null = null;
127
+ for (let header = 0; header + TAR_BLOCK <= bytes.length;) {
128
+ if (bytes[header] === 0) return null;
129
+ const type = String.fromCharCode(bytes[header + 156] ?? 0);
130
+ const size = Number.parseInt(field(header + 124, 12).trim() || "0", 8);
131
+ const data = header + TAR_BLOCK;
132
+ if (type === "x" || type === "L" || type === "g" || type === "K") {
133
+ if (!Number.isFinite(size) || data + size > bytes.length) return null;
134
+ if (type === "L") longName = field(data, size);
135
+ if (type === "x") longName = /(?:^|\n)\d+ path=([^\n]*)\n/.exec(decoder.decode(bytes.subarray(data, data + size)))?.[1] ?? longName;
136
+ header = data + Math.ceil(size / TAR_BLOCK) * TAR_BLOCK;
137
+ continue;
138
+ }
139
+ if (longName) return longName;
140
+ const name = field(header, 100);
141
+ // POSIX ustar ("ustar\0") only: GNU tar keeps other fields where the prefix would be.
142
+ const prefix = field(header + 257, 6) === "ustar" ? field(header + 345, 155) : "";
143
+ return prefix ? `${prefix}/${name}` : name;
144
+ }
145
+ return null;
146
+ }
147
+
148
+ /**
149
+ * Removes the unpacked update archives in Electrobun's `self-extraction`
150
+ * folder whose app carries its name from before the rename. The one that
151
+ * matters is the Windows archive an install from then updated from: it is
152
+ * packed again with the folder renamed (scripts/write-legacy-desktop-files.ts),
153
+ * so its bytes are not those of the archive the next release's patch is made
154
+ * from, and bspatch would turn it into a broken build. Without it the updater
155
+ * downloads the full archive instead. Resolves to the paths it removed.
156
+ */
157
+ async function removeLegacyUpdateArchives(folder: string): Promise<string[]> {
158
+ const removed: string[] = [];
159
+ for (const entry of await readdir(folder).catch(() => [] as string[])) {
160
+ if (!entry.endsWith(".tar")) continue;
161
+ const path = join(folder, entry);
162
+ const head = await Bun.file(path).slice(0, 64 * 1024).bytes().catch(() => null);
163
+ const top = head ? firstTarPath(head)?.replace(/^\.\//, "").split("/")[0] : undefined;
164
+ if (top !== LEGACY_DESKTOP_APP_NAME && top !== `${LEGACY_DESKTOP_APP_NAME}.app`) continue;
165
+ const done = await rm(path, { force: true }).then(() => true, logFailure("desktop-update", "Could not remove an update archive from before the rename", false));
166
+ if (done) removed.push(path);
167
+ }
168
+ return removed;
169
+ }
170
+
106
171
  /**
107
172
  * Where the running app sits, for update failure reports and for what an
108
173
  * install that cannot replace it means. Electrobun replaces the macOS bundle
@@ -464,6 +529,8 @@ export function createElectrobunDesktopUpdater(
464
529
  }
465
530
  target = result.release;
466
531
 
532
+ const appData = await updater.appDataFolder?.().catch(() => null);
533
+ if (appData) await removeLegacyUpdateArchives(join(appData, "self-extraction"));
467
534
  await updater.downloadUpdate();
468
535
  const updateInfo = updater.updateInfo();
469
536
  if (updateInfo?.error) {
@@ -151,6 +151,7 @@ export function createDesktopWorkspace(
151
151
  paneState: clonePaneStateMap(sharedState.paneState),
152
152
  focusedPaneId: sharedState.focusedPaneId,
153
153
  statusBarVisible: sharedState.statusBarVisible,
154
+ brokerSyncErrors: { ...sharedState.brokerSyncErrors },
154
155
  mainStateRevision: sharedState.mainStateRevision,
155
156
  layoutChanged: sharedState.layoutChanged,
156
157
  });
@@ -179,6 +180,7 @@ export function createDesktopWorkspace(
179
180
  paneState: filterPaneState(syncedConfig.layout, clonePaneStateMap(snapshot.paneState)),
180
181
  focusedPaneId: snapshot.focusedPaneId,
181
182
  statusBarVisible: snapshot.statusBarVisible,
183
+ brokerSyncErrors: { ...snapshot.brokerSyncErrors },
182
184
  mainStateRevision: snapshot.mainStateRevision ?? currentRevision,
183
185
  layoutChanged: snapshot.layoutChanged,
184
186
  };
@@ -14,6 +14,7 @@ import {
14
14
  loadExternalPlugin,
15
15
  } from "../../../plugins/loader";
16
16
  import { createNodePluginManager } from "../../../plugins/manager-node";
17
+ import { deactivatePluginForRemoval } from "../../../plugins/marketplace/deactivation";
17
18
  import { readPluginIcon } from "../../../plugins/plugin-icon";
18
19
  import type { PluginRegistry } from "../../../plugins/registry";
19
20
  import { desktopRendererCapabilityManifests } from "./desktop/initialization";
@@ -157,6 +158,33 @@ export async function collectExternalPluginBundles(): Promise<DesktopExternalPlu
157
158
  return bundles;
158
159
  }
159
160
 
161
+ let prefetchedBundles: Promise<DesktopExternalPluginBundle[]> | null = null;
162
+
163
+ /**
164
+ * Starts compiling every plugin for the view before it asks. The bundle cache
165
+ * above lives in memory, so the first window of a launch always compiles;
166
+ * started at launch, that runs while the view loads its own bundle.
167
+ */
168
+ export function prefetchExternalPluginBundles(): void {
169
+ if (prefetchedBundles) return;
170
+ const bundles = collectExternalPluginBundles();
171
+ // The view's request reports a failure; this one only must not go unhandled.
172
+ bundles.catch(() => {
173
+ // Intentional ignore: the window that takes these bundles reports the failure.
174
+ });
175
+ prefetchedBundles = bundles;
176
+ }
177
+
178
+ /**
179
+ * The bundles for a window: the launch's prefetch once, then a new collection,
180
+ * which the mtime cache keeps cheap, so a later window sees plugins installed since.
181
+ */
182
+ export function takeExternalPluginBundles(): Promise<DesktopExternalPluginBundle[]> {
183
+ const prefetched = prefetchedBundles;
184
+ prefetchedBundles = null;
185
+ return prefetched ?? collectExternalPluginBundles();
186
+ }
187
+
160
188
  /** One plugin, compiled fresh, so the view can activate what was just installed or updated. */
161
189
  export function bundleExternalPluginDirectory(directory: string): Promise<DesktopExternalPluginBundle | null> {
162
190
  return bundlePluginDirectory(join(getPluginsDir(), directory), { fresh: true });
@@ -209,12 +237,6 @@ export function deactivateExternalPlugin(
209
237
  registry: PluginRegistry,
210
238
  pluginId: string,
211
239
  ): { capabilityManifests: ReturnType<typeof desktopRendererCapabilityManifests> } {
212
- if (registry.allPlugins.has(pluginId)) {
213
- try {
214
- registry.unregister(pluginId);
215
- } catch (error) {
216
- log.error(`Deactivating ${pluginId} failed: ${error instanceof Error ? error.message : String(error)}`);
217
- }
218
- }
240
+ deactivatePluginForRemoval(registry, pluginId);
219
241
  return { capabilityManifests: desktopRendererCapabilityManifests(registry.capabilities) };
220
242
  }
@@ -1,4 +1,5 @@
1
- import Electrobun, { ApplicationMenu, Screen } from "electrobun/bun";
1
+ import Electrobun, { ApplicationMenu, Screen, Utils } from "electrobun/bun";
2
+ import { homedir } from "os";
2
3
  import { debugLog } from "../../../utils/debug-log";
3
4
  import { setConfigStoreHost } from "../../../data/config/store";
4
5
  import * as nodeConfigStoreHost from "../../../data/config/store/node";
@@ -6,6 +7,7 @@ import { ELECTROBUN_CONTEXT_MENU_ACTION } from "../shared/protocol";
6
7
  import { contextMenuSelectionMessage } from "./context-menu/click";
7
8
  import { applicationMenuCommand, createApplicationMenuGate } from "./application-menu/click";
8
9
  import { DesktopBackend } from "./desktop/backend";
10
+ import { startDesktopBackend } from "./desktop/initialization";
9
11
  import {
10
12
  MAIN_WINDOW_MIN_SIZE,
11
13
  defaultMainWindowFrame,
@@ -13,6 +15,7 @@ import {
13
15
  } from "./window/frame";
14
16
  import { MAIN_WINDOW_RPC_KEY } from "./window/focus";
15
17
  import { createAppWindow } from "./window/create";
18
+ import { desktopBootFramePath, desktopBootFramePreload, readDesktopBootFrame } from "./window/boot-frame";
16
19
  import { getWindowFrame } from "./window/events";
17
20
  import {
18
21
  fitWindowFrameToDisplays,
@@ -23,6 +26,8 @@ import {
23
26
  } from "./window/remembered-frame";
24
27
  import { reapStaleTerminalMedia } from "../../opentui/terminal-media";
25
28
  import { installProcessCrashListeners } from "../../../telemetry/crash-reports-node";
29
+ import { renameLegacyMacApp } from "./desktop/app-name";
30
+ import { scheduleDesktopRelaunch } from "./desktop/relaunch";
26
31
 
27
32
  console.log = (...args) => console.error(...args);
28
33
  console.info = (...args) => console.error(...args);
@@ -40,6 +45,27 @@ setConfigStoreHost(nodeConfigStoreHost);
40
45
  // before the config, and its off switch, has been read.
41
46
  installProcessCrashListeners();
42
47
 
48
+ // An install from before the rename runs from Gloomberb.app, where its updater
49
+ // put this build. It takes the new name and opens again from there before any
50
+ // window shows. Anywhere else this returns without touching the disk.
51
+ const appRename = await renameLegacyMacApp({
52
+ execPath: process.execPath,
53
+ platform: process.platform,
54
+ homeDir: homedir(),
55
+ pathEnv: process.env.PATH ?? "",
56
+ }).catch((error: unknown) => {
57
+ console.error("[desktop] could not give the app its new name", error instanceof Error ? error.message : String(error));
58
+ return null;
59
+ });
60
+ if (appRename?.kind === "renamed") {
61
+ scheduleDesktopRelaunch(appRename.bundle);
62
+ Utils.quit();
63
+ // The process is exiting; nothing below may open a window meanwhile.
64
+ await new Promise<never>(() => {});
65
+ } else if (appRename?.kind === "skipped") {
66
+ console.error(`[desktop] kept the app's old name: ${appRename.reason}`);
67
+ }
68
+
43
69
  function readOpenUrlEvent(event: unknown): string | null {
44
70
  const data = event && typeof event === "object" ? (event as { data?: unknown }).data : null;
45
71
  if (!data || typeof data !== "object") return null;
@@ -135,13 +161,21 @@ function scheduleRememberedWindow(): void {
135
161
  }
136
162
 
137
163
  const mainWindow = createAppWindow({
138
- title: "Gloomberb",
164
+ title: "Gloom",
139
165
  frame: initialMainWindowFrame,
140
166
  rpc: mainRpc,
141
167
  minSize: MAIN_WINDOW_MIN_SIZE,
142
168
  onFrameChange: scheduleRememberedWindow,
169
+ // The layout the window last drew, which its page draws before its script
170
+ // has loaded (dom/boot-frame.ts).
171
+ preload: desktopBootFramePreload(readDesktopBootFrame(desktopBootFramePath())),
143
172
  });
144
173
  backend.mainWindow = mainWindow;
174
+ // The window is loading its view; the services it will ask for start now
175
+ // rather than when it asks. Its `init` reports a failure, and retries.
176
+ startDesktopBackend(backend).catch((error) => {
177
+ console.error("[desktop] startup failed", error instanceof Error ? error.stack ?? error.message : String(error));
178
+ });
145
179
  if (rememberedWindow?.fullscreen) {
146
180
  try { mainWindow.setFullScreen(true); } catch { /* the framed window is still the one they sized */ }
147
181
  } else if (rememberedWindow?.maximized) {
@@ -0,0 +1,67 @@
1
+ import { mkdirSync, readFileSync, renameSync, rmSync, writeFileSync } from "fs";
2
+ import { dirname, join } from "path";
3
+ import { getGloomberbDirs } from "../../../../data/config/home";
4
+ import { isBootFrame, type BootFrame } from "../../../dom/boot-frame-page";
5
+ import { DESKTOP_BOOT_FRAME_GLOBAL } from "../../shared/boot-frame";
6
+
7
+ /**
8
+ * The main window's launch frame lives beside the remembered window frame:
9
+ * read before the config, and drawn for this machine's screen.
10
+ */
11
+ const FILE_NAME = "desktop-boot-frame.json";
12
+
13
+ export function desktopBootFramePath(env: NodeJS.ProcessEnv = process.env): string {
14
+ return join(dirname(getGloomberbDirs(env).configFile), FILE_NAME);
15
+ }
16
+
17
+ export function readDesktopBootFrame(path: string): BootFrame | null {
18
+ try {
19
+ const frame: unknown = JSON.parse(readFileSync(path, "utf8"));
20
+ return isBootFrame(frame) ? frame : null;
21
+ } catch {
22
+ return null;
23
+ }
24
+ }
25
+
26
+ interface BootFrameSender {
27
+ /** The main window's view; a popped-out pane's draws no frame. */
28
+ mainWindow: boolean;
29
+ /** A session is up. After all data was reset there is none until the next launch. */
30
+ session: boolean;
31
+ }
32
+
33
+ /**
34
+ * Keeps the frame a view sent, if it may: from the main window, while a
35
+ * session is up, and of the right shape and size. A closing window's last
36
+ * frame, sent after a reset, is dropped. Returns whether it was written.
37
+ */
38
+ export function saveDesktopBootFrame(path: string, frame: unknown, sender: BootFrameSender): boolean {
39
+ if (!sender.mainWindow || !sender.session || !isBootFrame(frame)) return false;
40
+ mkdirSync(dirname(path), { recursive: true });
41
+ const temporary = `${path}.${process.pid}.tmp`;
42
+ writeFileSync(temporary, JSON.stringify(frame));
43
+ renameSync(temporary, path);
44
+ return true;
45
+ }
46
+
47
+ /**
48
+ * Forgets the frame, with the rest of the data on a reset. It sits beside
49
+ * the config, which a custom data folder is not, so removing the data folder
50
+ * alone could leave it behind.
51
+ */
52
+ export function removeDesktopBootFrame(path: string): void {
53
+ rmSync(path, { force: true });
54
+ }
55
+
56
+ /**
57
+ * The main window's preload: the frame its page draws before its script
58
+ * loads, or null for the bare shell. Set either way, which is how the page
59
+ * tells the main window from a popped-out pane's.
60
+ */
61
+ export function desktopBootFramePreload(frame: BootFrame | null): string {
62
+ const json = JSON.stringify(frame)
63
+ .replace(/</g, "\\u003c")
64
+ .replace(/\u2028/g, "\\u2028")
65
+ .replace(/\u2029/g, "\\u2029");
66
+ return `window.${DESKTOP_BOOT_FRAME_GLOBAL} = ${json};`;
67
+ }
@@ -51,17 +51,20 @@ interface AppWindowOptions {
51
51
  minSize: WindowMinimumSize;
52
52
  /** Runs after each move or resize has been applied to the cached frame. */
53
53
  onFrameChange?: () => void;
54
+ /** Script run in the page before its own. */
55
+ preload?: string;
54
56
  }
55
57
 
56
58
  /**
57
59
  * Opens a window on the app view with this platform's chrome and icon, keeps
58
60
  * its cached frame current as it moves, and holds it to `minSize` on resize.
59
61
  */
60
- export function createAppWindow({ title, frame, rpc, minSize, onFrameChange }: AppWindowOptions): BrowserWindow {
62
+ export function createAppWindow({ title, frame, rpc, minSize, onFrameChange, preload }: AppWindowOptions): BrowserWindow {
61
63
  const window = new BrowserWindow({
62
64
  title,
63
65
  frame,
64
66
  url: "views://mainview/index.html",
67
+ ...(preload ? { preload } : {}),
65
68
  renderer: desktopWindowRenderer(),
66
69
  rpc,
67
70
  styleMask: desktopWindowStyleMask(),
@@ -0,0 +1,17 @@
1
+ /**
2
+ * The desktop app is Gloom. Builds up to 0.18.4 were named Gloomberb, and an
3
+ * install from then still is: `Gloomberb.app` on a Mac, a `Gloomberb` folder
4
+ * inside the Windows update archive, and an updater that asks the release for
5
+ * `<channel>-<os>-<arch>-Gloomberb.*` files. The release keeps publishing
6
+ * those under the old name (scripts/write-legacy-desktop-files.ts), and a Mac
7
+ * bundle still named Gloomberb.app renames itself (bun/desktop/app-name.ts).
8
+ */
9
+ export const DESKTOP_APP_NAME = "Gloom";
10
+ export const LEGACY_DESKTOP_APP_NAME = "Gloomberb";
11
+
12
+ /**
13
+ * Kept through the rename. Electrobun names the app's data and update folders
14
+ * after it, and macOS ties the app's settings, WebKit storage and permissions
15
+ * to it.
16
+ */
17
+ export const DESKTOP_APP_IDENTIFIER = "com.vincelwt.gloomberb";
@@ -0,0 +1,7 @@
1
+ /**
2
+ * Where the main window's page finds the launch frame (dom/boot-frame.ts):
3
+ * the Bun process sets it in the window's preload, before the page's own
4
+ * scripts run. A window it is not set in, one holding a popped-out pane,
5
+ * draws no frame.
6
+ */
7
+ export const DESKTOP_BOOT_FRAME_GLOBAL = "__gloomDesktopBootFrame";
@@ -10,6 +10,7 @@ import type { CapabilityManifest } from "../../../capabilities";
10
10
  import type { PluginOperationResult, PluginPin } from "../../../plugins/marketplace/store";
11
11
  import type { RemoteControlRequest, RemoteControlResponse } from "../../../remote/types";
12
12
  import type { HttpProxyRequestEnvelope, HttpProxyResponseEnvelope } from "../../../utils/http-proxy-response";
13
+ import type { BootFrame } from "../../dom/boot-frame-page";
13
14
 
14
15
  export const ELECTROBUN_CONTEXT_MENU_ACTION = "gloom.context-menu.select";
15
16
 
@@ -27,6 +28,8 @@ export interface ElectrobunBackendInit {
27
28
  hostName?: string;
28
29
  windowKind: "main" | "detached";
29
30
  paneId?: string;
31
+ /** What the launch's plugin seed could not install, for the main window to say once. */
32
+ pluginSeedNotice?: { body: string; type: "error" | "info" };
30
33
  /** What the view needs to send crash reports and usage counts the same way the Bun process would. */
31
34
  telemetry: ElectrobunTelemetryInit;
32
35
  }
@@ -203,7 +206,7 @@ interface DesktopBackendRequestMap {
203
206
  "host.exit": { request: null; response: null };
204
207
  "host.windowControl": { request: { action: DesktopWindowControlAction }; response: null };
205
208
  "host.windowFullscreen": { request: null; response: boolean };
206
- "host.openExternal": { request: { url: string }; response: null };
209
+ "host.openExternal": { request: { url: string }; response: boolean };
207
210
  "host.copyText": { request: { text: string }; response: null };
208
211
  "host.focusWindow": { request: null; response: null };
209
212
  "host.copyPngImage": { request: { pngBase64: string }; response: null };
@@ -217,6 +220,8 @@ interface DesktopBackendRequestMap {
217
220
  response: null;
218
221
  };
219
222
  "host.showContextMenu": { request: { menu: DesktopContextMenuItem[] }; response: boolean };
223
+ /** The layout the main window draws at the next launch before its script loads (dom/boot-frame.ts). Only the main window's is kept. */
224
+ "host.saveBootFrame": { request: { frame: BootFrame }; response: null };
220
225
  /** The unread count for the Dock icon badge: `""` (none), `"1"` to `"99"` or `"99+"`. Only the main window's is applied. */
221
226
  "host.setAppBadge": { request: { label: string }; response: null };
222
227
  /** `channel` absent (an older view) means stable. */
@@ -185,7 +185,7 @@ async function restoreShotCloudSession(): Promise<void> {
185
185
 
186
186
  /**
187
187
  * Runs an asset-data request in the Bun process so the page sees exactly what
188
- * `gloomberb fn` sees. The page can only reach the cloud API on its own, and
188
+ * `gloom fn` sees. The page can only reach the cloud API on its own, and
189
189
  * the cloud is one source among several: analyst rating price targets and part
190
190
  * of the corporate action history come from providers the router merges in.
191
191
  */
@@ -125,8 +125,8 @@ function useShotStatusLine(enabled: boolean, hasAsOf: () => boolean): ShotStatus
125
125
  }
126
126
 
127
127
  /**
128
- * Static captures retain warnings and optional source status without action
129
- * shortcuts. With `statusLine` the footer also carries the capture's dated
128
+ * Static captures retain warnings, what a filter leaves out (`capture`) and
129
+ * optional source status without action shortcuts. With `statusLine` the footer also carries the capture's dated
130
130
  * status line (`Fri 9 Oct close · 15 min delayed · markets closed until Mon`),
131
131
  * inside the requested size: the body gives up the footer row for it. The
132
132
  * pane's own text that says the same goes, so the date is said once: its `as
@@ -149,7 +149,7 @@ export function PaneShotFrame({ paneId, title, width, height, preserveStatus = f
149
149
  const datesData = statusLine && dates === "data";
150
150
  return <PaneFooterProvider>{(registeredFooter) => {
151
151
  const status: PaneFooterSegment[] = statusLine ? [{ id: "shot-status", parts: [{ text: statusText, tone: "label" }] }] : [];
152
- const info = registeredFooter.info.filter((segment) => (preserveStatus || segment.icon === "warning")
152
+ const info = registeredFooter.info.filter((segment) => (preserveStatus || segment.icon === "warning" || segment.capture)
153
153
  && !(datesPaneData(segment) && (datesData || crowded))
154
154
  && !(segment.quoteStatus && statusLine && dates !== null));
155
155
  shownAsOf.current = info.some(datesPaneData);
@@ -1,4 +1,5 @@
1
1
  import { setConfigStoreHost, type ConfigStoreHost } from "../../../data/config/store";
2
+ import { stopBootFrameRecorders } from "../../dom/boot-frame";
2
3
  import type { AppConfig } from "../../../types/config";
3
4
  import { backendRequest, getElectrobunBackendInitSnapshot } from "./backend-rpc";
4
5
 
@@ -20,6 +21,8 @@ const electrobunConfigStoreHost: ConfigStoreHost = {
20
21
  return config;
21
22
  },
22
23
  async resetAllData(dataDir: string) {
24
+ // Before the reset, or the frame saved as the window closes would bring the old layout back.
25
+ stopBootFrameRecorders();
23
26
  await backendRequest("config.resetAllData", { dataDir });
24
27
  },
25
28
  async exportConfig(config: AppConfig, destPath: string) {
@@ -32,6 +32,7 @@ export function detachedSnapshotKey(snapshot: DesktopSharedStateSnapshot, paneId
32
32
  portfolios: snapshot.config.portfolios,
33
33
  watchlists: snapshot.config.watchlists,
34
34
  brokerInstances: snapshot.config.brokerInstances,
35
+ brokerSyncErrors: snapshot.brokerSyncErrors ?? {},
35
36
  pluginConfig: snapshot.config.pluginConfig,
36
37
  disabledPlugins: snapshot.config.disabledPlugins,
37
38
  chartPreferences: snapshot.config.chartPreferences,
@@ -21,7 +21,7 @@ function formatFatalError(error: unknown, details?: string): string {
21
21
  }
22
22
 
23
23
  export function DesktopFatalScreen({
24
- title = "Gloomberb crashed",
24
+ title = "Gloom crashed",
25
25
  error,
26
26
  details,
27
27
  source,
@@ -26,6 +26,7 @@ import { installElectrobunUpdateHost } from "./update-host";
26
26
  import { installScreenshotWatermark } from "./screenshot-watermark";
27
27
  import { installElectrobunWindowFullscreenTracking } from "./window-fullscreen";
28
28
  import { installDomMarketDataFrames } from "../../dom/data-frames";
29
+ import { releaseBootFrameWhenDrawn, startBootFrameRecorder } from "../../dom/boot-frame";
29
30
  import { DomErrorBoundary, DomHostProviders } from "../../dom/dom-host-providers";
30
31
  import { DesktopFatalScreen } from "./fatal-screen";
31
32
  import { resolveRendererWindowError } from "./renderer-window-error";
@@ -45,6 +46,7 @@ import { getMarketplaceHost, setPluginManager, type PluginManager } from "../../
45
46
  import { remoteNotesFilesIO, setNotesFilesIO } from "../../../plugins/builtin/notes/files";
46
47
  import { NOTES_FILES_CAPABILITY_ID } from "../../../capabilities";
47
48
  import { loadOfficialPluginIds } from "../../../plugins/marketplace/feed";
49
+ import { setPluginSeedNotice } from "../../../plugins/seed-notice";
48
50
  import { crashReportsEnabled, installCrashReporter, reportCrash } from "../../../telemetry/crash-reports";
49
51
  import { browserDoNotTrack, installWindowCrashListeners } from "../../../telemetry/crash-reports-dom";
50
52
  import { currentTelemetryConfig } from "../../../telemetry/live-config";
@@ -72,9 +74,14 @@ const bootLog = debugLog.createLogger("electrobun-web-boot");
72
74
  let appMounted = false;
73
75
 
74
76
  appRootElement.tabIndex = -1;
75
- root.render(<div className="gloom-loading">Starting Gloomberb...</div>);
77
+ // The page drew the layout this window last drew, or the bare shell, before
78
+ // this script loaded (dom/boot-frame.ts); it stays until the app has drawn its own.
79
+ const releaseBootFrame = releaseBootFrameWhenDrawn(document, appRootElement);
80
+ /** How long after the app mounts the launch frame stays at most. */
81
+ const BOOT_FRAME_RELEASE_FALLBACK_MS = 4_000;
76
82
 
77
- function renderFatalError(error: unknown, details?: string, title = "Gloomberb failed to start"): void {
83
+ function renderFatalError(error: unknown, details?: string, title = "Gloom failed to start"): void {
84
+ releaseBootFrame();
78
85
  root.render(
79
86
  <DesktopFatalScreen
80
87
  title={title}
@@ -94,7 +101,7 @@ window.__gloomRenderFatalError = (error, details, source) => {
94
101
  }) === "ignore") {
95
102
  return;
96
103
  }
97
- renderFatalError(error, details, "Gloomberb crashed");
104
+ renderFatalError(error, details, "Gloom crashed");
98
105
  };
99
106
 
100
107
  function focusWebSurface(): void {
@@ -113,9 +120,13 @@ function requestStartupFocus(): void {
113
120
 
114
121
  async function boot() {
115
122
  bootLog.info("boot started");
123
+ // Both asked for at once: the Bun process compiles the plugins while it
124
+ // answers `init`, rather than after this view asks a second time.
116
125
  const backendInitPromise = initElectrobunBackend();
126
+ const externalBundlesPromise = backendRequest("plugins.listExternal");
117
127
  // Avoid a premature global unhandled-rejection render while UI chunks load.
118
128
  void backendInitPromise.catch(() => {});
129
+ void externalBundlesPromise.catch(() => {});
119
130
 
120
131
  installElectrobunConfigStoreHost();
121
132
  installElectrobunBrokerRemoteClient();
@@ -156,6 +167,8 @@ async function boot() {
156
167
  : init.desktopSnapshot;
157
168
  const config = desktopSnapshot?.config ?? init.config;
158
169
  applyLanguageFromConfig(config);
170
+ // Said by the app once it is up, as the terminal says it.
171
+ setPluginSeedNotice(init.pluginSeedNotice ?? null);
159
172
  const desktopWindowBridge = createDesktopWindowBridge(init.windowKind, init.paneId);
160
173
  const desktopApplicationMenuBridge: DesktopApplicationMenuBridge = {
161
174
  subscribe: (listener) => onBackendMessage("application-menu.select", ({ command }) => listener(command)),
@@ -172,7 +185,11 @@ async function boot() {
172
185
  "startup.electrobun.load-external-plugins",
173
186
  async () => {
174
187
  try {
175
- return await loadDesktopExternalPlugins(await backendRequest("plugins.listExternal"));
188
+ // Asked once more if the early request failed: it waits for the
189
+ // whole launch, which a first run's plugin downloads can stretch past
190
+ // the request's time limit.
191
+ const bundles = await externalBundlesPromise.catch(() => backendRequest("plugins.listExternal"));
192
+ return await loadDesktopExternalPlugins(bundles);
176
193
  } catch (error) {
177
194
  debugLog.createLogger("desktop-plugins").error(`External plugin load failed: ${error}`);
178
195
  return [];
@@ -245,6 +262,15 @@ async function boot() {
245
262
  );
246
263
  appMounted = true;
247
264
  });
265
+ // A layout with neither panes nor a status bar has nothing to wait for.
266
+ window.setTimeout(releaseBootFrame, BOOT_FRAME_RELEASE_FALLBACK_MS);
267
+ if (init.windowKind === "main") {
268
+ startBootFrameRecorder({
269
+ doc: document,
270
+ root: appRootElement,
271
+ save: (frame) => { void backendRequest("host.saveBootFrame", { frame }).catch(() => {}); },
272
+ });
273
+ }
248
274
  requestStartupFocus();
249
275
  bootLog.info("root render scheduled", {
250
276
  layoutPanes: config.layout.instances.length,
@@ -1,6 +1,6 @@
1
1
  import { apiClient } from "../../../api-client";
2
2
  import { newsProvider, type NewsCapability } from "../../../capabilities";
3
- import { cloudNewsParams, mapCloudNewsArticle } from "../../../sources/gloomberb-cloud/news";
3
+ import { cloudNewsReadArticles, mapCloudNewsArticle, readCloudNews } from "../../../sources/gloomberb-cloud/news";
4
4
  import type { NewsArticle, NewsPage, NewsQuery } from "../../../news/types";
5
5
 
6
6
  interface BackendNews {
@@ -10,7 +10,7 @@ interface BackendNews {
10
10
  getNewsPage(query: NewsQuery): Promise<NewsPage>;
11
11
  }
12
12
 
13
- type CloudNewsClient = Pick<typeof apiClient, "getCloudNews" | "getCloudNewsStory">;
13
+ type CloudNewsClient = Pick<typeof apiClient, "getCloudNews" | "getCloudNewsStory" | "searchCloudNews">;
14
14
 
15
15
  /**
16
16
  * The view's only news source: the desktop view runs without capability
@@ -28,10 +28,10 @@ export function createDesktopNewsSource(backend: BackendNews, client: CloudNewsC
28
28
  fetchNews: (query) => backend.getNews(query),
29
29
  fetchNewsPage: async (query) => {
30
30
  try {
31
- const response = await client.getCloudNews(cloudNewsParams(query));
31
+ const read = await readCloudNews(client, query);
32
32
  return {
33
- articles: response.items.map((item) => mapCloudNewsArticle(item, query.ticker)),
34
- nextCursor: response.nextCursor ?? null,
33
+ articles: cloudNewsReadArticles(read, query.ticker),
34
+ nextCursor: read.nextCursor ?? null,
35
35
  };
36
36
  } catch {
37
37
  // The aggregate page keeps RSS failures beside any usable stories.
@@ -121,7 +121,7 @@ export function createRemoteAssetDataClient(): RemoteAssetDataClient {
121
121
 
122
122
  const base: RemoteAssetDataClientBase = {
123
123
  id: "desktop-backend",
124
- name: "Gloomberb Backend",
124
+ name: "Gloom Backend",
125
125
  getCachedFinancialsForTargets: (targets, options) => (
126
126
  hasRendererOperation(assetDataOperations, "getCachedFinancialsForTargets")
127
127
  ? invoke<Map<string, TickerFinancials>>(ASSET_DATA_CAPABILITY_ID, "getCachedFinancialsForTargets", { targets, options })
@@ -33,7 +33,7 @@ export const webRendererHost: RendererHost = {
33
33
  await backendRequest("host.windowControl", { action });
34
34
  },
35
35
  async openExternal(url) {
36
- await backendRequest("host.openExternal", { url });
36
+ return await backendRequest("host.openExternal", { url });
37
37
  },
38
38
  async copyText(text) {
39
39
  try {