gloomberb 0.18.2 → 0.18.4

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (954) 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 +106 -5
  6. package/src/account/checkout-handoff.tsx +225 -0
  7. package/src/account/device-signin-dialog.tsx +2 -2
  8. package/src/account/device-signin.ts +2 -2
  9. package/src/account/upgrade-dialog.tsx +1 -1
  10. package/src/api-client/askg.ts +2 -2
  11. package/src/api-client/auth.ts +2 -2
  12. package/src/api-client/central-bank-rates.ts +6 -0
  13. package/src/api-client/collections.ts +5 -1
  14. package/src/api-client/cot.ts +2 -0
  15. package/src/api-client/crypto-etf-flows.ts +37 -0
  16. package/src/api-client/crypto-markets.ts +60 -0
  17. package/src/api-client/data.ts +99 -5
  18. package/src/api-client/doe.ts +15 -0
  19. package/src/api-client/equity-screener.ts +28 -0
  20. package/src/api-client/exchange-announcements.ts +38 -0
  21. package/src/api-client/fund-facts.ts +39 -0
  22. package/src/api-client/futures-curve.ts +9 -1
  23. package/src/api-client/hiring.ts +301 -0
  24. package/src/api-client/index.ts +24 -5
  25. package/src/api-client/market-discovery.ts +14 -0
  26. package/src/api-client/members.ts +6 -0
  27. package/src/api-client/mna.ts +6 -0
  28. package/src/api-client/paths.ts +18 -1
  29. package/src/api-client/request.ts +26 -7
  30. package/src/api-client/short-side-publications.ts +37 -0
  31. package/src/api-client/socket.ts +64 -4
  32. package/src/api-client/swap-curve.ts +35 -0
  33. package/src/api-client/telemetry.ts +17 -0
  34. package/src/api-client/themes.ts +7 -1
  35. package/src/api-client/types.ts +90 -2
  36. package/src/app/global-shortcuts.ts +1 -16
  37. package/src/app/pane-runtime/plugin-bindings.ts +9 -2
  38. package/src/app/runtime/desktop-deeplink.ts +5 -5
  39. package/src/app/runtime/plugin-bindings.ts +2 -2
  40. package/src/app/runtime/startup.ts +13 -0
  41. package/src/app/runtime/update.ts +28 -8
  42. package/src/app/star-prompt/status-line.tsx +2 -2
  43. package/src/architecture/core-builtin-allowlist.json +5 -2
  44. package/src/architecture/pane-tabs-allowlist.json +65 -0
  45. package/src/architecture/ui-literals-allowlist.json +3 -3
  46. package/src/architecture/ui-tokens-allowlist.json +1 -1
  47. package/src/brokers/broker-portfolio-sync.ts +37 -0
  48. package/src/brokers/directory.ts +11 -0
  49. package/src/brokers/logos.ts +3 -1
  50. package/src/brokers/signed-in/adapter.ts +304 -26
  51. package/src/brokers/signed-in/client.ts +14 -2
  52. package/src/brokers/signed-in/connect.ts +10 -2
  53. package/src/brokers/sync-broker-instance.ts +9 -1
  54. package/src/capabilities/chart-series.ts +22 -6
  55. package/src/cli/bank-section.ts +1 -1
  56. package/src/cli/base-converter.ts +23 -14
  57. package/src/cli/central-bank-events.ts +1 -1
  58. package/src/cli/command-options.ts +59 -4
  59. package/src/cli/commands/api.ts +9 -6
  60. package/src/cli/commands/broker.ts +2 -2
  61. package/src/cli/commands/command-utils.ts +2 -2
  62. package/src/cli/commands/crypto-hints.ts +7 -20
  63. package/src/cli/commands/fred-series.ts +4 -2
  64. package/src/cli/commands/keybindings.ts +2 -2
  65. package/src/cli/commands/market.ts +1189 -296
  66. package/src/cli/commands/news-hints.ts +2 -2
  67. package/src/cli/commands/news-search.ts +59 -6
  68. package/src/cli/commands/options-leaps.ts +41 -26
  69. package/src/cli/commands/overview.ts +121 -48
  70. package/src/cli/commands/plugins.ts +9 -9
  71. package/src/cli/commands/remote.ts +13 -10
  72. package/src/cli/commands/search.ts +64 -44
  73. package/src/cli/commands/system.ts +27 -19
  74. package/src/cli/commands/themes.ts +1 -1
  75. package/src/cli/commands/ticker.ts +272 -70
  76. package/src/cli/context.ts +3 -2
  77. package/src/cli/desktop-pane-shot-view.ts +2 -2
  78. package/src/cli/desktop-pane-shot.ts +1 -1
  79. package/src/cli/earnings-calendar.ts +4 -4
  80. package/src/cli/entry.ts +18 -1
  81. package/src/cli/errors.ts +20 -2
  82. package/src/cli/exit-codes.ts +1 -1
  83. package/src/cli/export-source.ts +10 -4
  84. package/src/cli/freshness.ts +2 -8
  85. package/src/cli/fx-forward.ts +130 -0
  86. package/src/cli/fx-pair.ts +10 -9
  87. package/src/cli/glossary.ts +64 -20
  88. package/src/cli/help.ts +20 -14
  89. package/src/cli/history-export.ts +126 -0
  90. package/src/cli/history-rows.ts +196 -43
  91. package/src/cli/index-roots.ts +5 -45
  92. package/src/cli/index.ts +32 -18
  93. package/src/cli/issuer-membership.ts +103 -0
  94. package/src/cli/known-gaps.ts +118 -25
  95. package/src/cli/listing-arg.ts +315 -43
  96. package/src/cli/name-entries.ts +73 -22
  97. package/src/cli/native-smoke.ts +2 -0
  98. package/src/cli/not-a-ticker.ts +19 -9
  99. package/src/cli/opentui-libc.ts +5 -0
  100. package/src/cli/options.ts +12 -0
  101. package/src/cli/pane-functions/capabilities.ts +77 -20
  102. package/src/cli/pane-functions/catalog.ts +40 -23
  103. package/src/cli/pane-functions/discovery.ts +1 -1
  104. package/src/cli/pane-functions/dom.ts +12 -8
  105. package/src/cli/pane-functions/financial-ratio-shot.ts +2 -2
  106. package/src/cli/pane-functions/freshness.ts +174 -23
  107. package/src/cli/pane-functions/function-help.ts +66 -27
  108. package/src/cli/pane-functions/headless.ts +48 -16
  109. package/src/cli/pane-functions/index.ts +82 -21
  110. package/src/cli/pane-functions/options.ts +22 -2
  111. package/src/cli/pane-functions/report-notices.ts +12 -4
  112. package/src/cli/pane-functions/report.ts +5 -5
  113. package/src/cli/pane-functions/resolver.ts +65 -14
  114. package/src/cli/pane-functions/screenshot-assessment.ts +322 -0
  115. package/src/cli/pane-functions/screenshot-bridge.ts +152 -0
  116. package/src/cli/pane-functions/screenshot-chart-evidence.ts +396 -0
  117. package/src/cli/pane-functions/screenshot-data-evidence.ts +383 -0
  118. package/src/cli/pane-functions/screenshot-evidence.ts +1 -1
  119. package/src/cli/pane-functions/screenshot-payload.ts +453 -0
  120. package/src/cli/pane-functions/screenshot-render.ts +316 -0
  121. package/src/cli/pane-functions/screenshot-types.ts +162 -0
  122. package/src/cli/pane-functions/shot-options.ts +8 -3
  123. package/src/cli/peso-dollar-rates.ts +79 -0
  124. package/src/cli/quote-answer.ts +38 -3
  125. package/src/cli/report-tables.ts +190 -27
  126. package/src/cli/restore-plugins.ts +29 -14
  127. package/src/cli/result.ts +122 -25
  128. package/src/cli/series-search.ts +5 -5
  129. package/src/cli/statement-filings.ts +19 -0
  130. package/src/cli/suffixed-listing-rows.ts +49 -0
  131. package/src/cli/symbol-args.ts +50 -15
  132. package/src/cli/symbol-cells.ts +120 -0
  133. package/src/cli/symbol-list.ts +226 -60
  134. package/src/cli/symbol-rows.ts +131 -25
  135. package/src/cli/ticker-resolution.ts +108 -11
  136. package/src/cli/treasury-yields.ts +5 -5
  137. package/src/cli/types.ts +2 -0
  138. package/src/cli/uncovered-instrument.ts +3 -3
  139. package/src/cli/unknown-command.ts +6 -6
  140. package/src/components/chart/composite/chart-layout.ts +131 -0
  141. package/src/components/chart/composite/composite-chart.tsx +387 -21
  142. package/src/components/chart/composite/drawing-store.ts +26 -6
  143. package/src/components/chart/composite/interactions.ts +9 -3
  144. package/src/components/chart/composite/legend.tsx +75 -3
  145. package/src/components/chart/composite/levels.ts +5 -0
  146. package/src/components/chart/composite/panel-gestures.ts +41 -0
  147. package/src/components/chart/composite/panel-labels.ts +2 -1
  148. package/src/components/chart/composite/panel-surface.tsx +316 -11
  149. package/src/components/chart/composite/price-axis-labels.tsx +27 -3
  150. package/src/components/chart/composite/rasterizer.ts +44 -19
  151. package/src/components/chart/composite/scene.ts +16 -4
  152. package/src/components/chart/composite/text-renderer.ts +48 -21
  153. package/src/components/chart/composite/toolbar.tsx +52 -5
  154. package/src/components/chart/composite/types.ts +19 -0
  155. package/src/components/chart/composite/use-composite-chart-keyboard.ts +120 -13
  156. package/src/components/chart/composite/use-composite-value-scales.ts +44 -0
  157. package/src/components/chart/composite/use-composite-viewport.ts +12 -3
  158. package/src/components/chart/composite/value-scale.ts +149 -0
  159. package/src/components/chart/composite/volume-profile-paint.ts +6 -3
  160. package/src/components/chart/core/pointer.ts +2 -0
  161. package/src/components/chart-table/index.ts +2 -0
  162. package/src/components/chart-table/read.tsx +74 -0
  163. package/src/components/command-bar/commands/collection-list.ts +41 -19
  164. package/src/components/command-bar/commands/collection.ts +9 -3
  165. package/src/components/command-bar/commands/direct/index.ts +1 -1
  166. package/src/components/command-bar/commands/direct/runtime.ts +3 -2
  167. package/src/components/command-bar/pane-templates/items.ts +59 -6
  168. package/src/components/command-bar/pane-templates/workflow.ts +10 -1
  169. package/src/components/command-bar/routes/root/command-items.ts +32 -6
  170. package/src/components/command-bar/routes/root/plugin-install.ts +1 -1
  171. package/src/components/command-bar/routes/root/provider-search.ts +42 -11
  172. package/src/components/command-bar/routes/root/results.ts +18 -4
  173. package/src/components/command-bar/routes/root/runtime.ts +15 -3
  174. package/src/components/command-bar/routes/root/search-providers.ts +25 -2
  175. package/src/components/command-bar/routes/root/selection.ts +6 -1
  176. package/src/components/command-bar/routes/root/shortcut-feedback.ts +4 -1
  177. package/src/components/command-bar/routes/root/shortcuts.ts +30 -3
  178. package/src/components/command-bar/routes/ticker-search/results.ts +73 -4
  179. package/src/components/command-bar/selection-runtime.ts +50 -10
  180. package/src/components/command-bar/surface/index.tsx +24 -2
  181. package/src/components/command-bar/view-model.ts +7 -0
  182. package/src/components/command-bar/workflow/broker.ts +2 -2
  183. package/src/components/command-bar/workflow/collection-actions.ts +46 -7
  184. package/src/components/command-bar/workflow/collection-ticker.ts +32 -4
  185. package/src/components/command-bar/workflow/fields.ts +8 -2
  186. package/src/components/command-bar/workflow/ops.ts +18 -4
  187. package/src/components/command-bar/workflow/portfolio-position.ts +53 -4
  188. package/src/components/command-bar/workflow/submit.ts +3 -2
  189. package/src/components/command-bar/workflow/tickers.ts +5 -1
  190. package/src/components/company-logo.tsx +39 -0
  191. package/src/components/data-table/sections.ts +4 -2
  192. package/src/components/data-table/view.tsx +23 -3
  193. package/src/components/form-modal/confirm.tsx +2 -1
  194. package/src/components/form-modal/request.ts +5 -0
  195. package/src/components/form-modal/routes.ts +4 -1
  196. package/src/components/index.ts +13 -6
  197. package/src/components/layout/detached-pane-shell.tsx +1 -0
  198. package/src/components/layout/floating-pane.tsx +1 -0
  199. package/src/components/layout/header.tsx +234 -60
  200. package/src/components/layout/market-summary.ts +9 -6
  201. package/src/components/layout/pane/capture-status.ts +1 -1
  202. package/src/components/layout/pane/footer/model.ts +11 -5
  203. package/src/components/layout/pane/header.tsx +10 -3
  204. package/src/components/layout/pane/index.tsx +1 -0
  205. package/src/components/layout/pane/pane-tabs.tsx +9 -1
  206. package/src/components/layout/shell/chrome.ts +19 -6
  207. package/src/components/layout/shell/index.tsx +2 -1
  208. package/src/components/layout/shell/pane/layers.tsx +19 -1
  209. package/src/components/layout/status-bar.tsx +2 -2
  210. package/src/components/market-board/index.tsx +11 -3
  211. package/src/components/onboarding/onboarding-wizard.tsx +1 -0
  212. package/src/components/onboarding/portfolio-step/broker-setup-panel.tsx +2 -2
  213. package/src/components/onboarding/wizard-broker-sync.ts +4 -1
  214. package/src/components/pane-settings-dialog/desktop.tsx +20 -7
  215. package/src/components/pane-settings-dialog/tui.tsx +17 -9
  216. package/src/components/pane-settings-dialog/value.ts +8 -1
  217. package/src/components/pane-settings-dialog.tsx +44 -13
  218. package/src/components/sign-in-code-panel.tsx +27 -19
  219. package/src/components/ui/column-grid.tsx +48 -4
  220. package/src/components/ui/country-flag-art.tsx +180 -0
  221. package/src/components/ui/country-flag.tsx +118 -12
  222. package/src/components/ui/data-table/opentui/index.tsx +61 -2
  223. package/src/components/ui/data-table/opentui/model.ts +109 -2
  224. package/src/components/ui/data-table/types.ts +1 -1
  225. package/src/components/ui/display.tsx +5 -1
  226. package/src/components/ui/index.ts +3 -1
  227. package/src/components/ui/logo-mark.tsx +11 -2
  228. package/src/components/ui/query-bar.tsx +1 -1
  229. package/src/components/ui/row-notes.ts +79 -0
  230. package/src/components/ui/stat-grid.tsx +28 -3
  231. package/src/components/ui/status.tsx +3 -1
  232. package/src/core/app-services.ts +4 -0
  233. package/src/core/state/app/layout.ts +4 -4
  234. package/src/data/cached-query.ts +8 -1
  235. package/src/data/config/chart-settings.ts +3 -3
  236. package/src/data/config/home.ts +10 -2
  237. package/src/data/config/layout.ts +4 -1
  238. package/src/data/config/store/node.ts +4 -0
  239. package/src/data/config/store/normalize.ts +13 -3
  240. package/src/data/config/store/portfolio-as-of-column.ts +2 -2
  241. package/src/data/json-storage.ts +2 -0
  242. package/src/data/saved-copies.ts +84 -0
  243. package/src/docs/snapshot.json +65 -32
  244. package/src/i18n/es.ts +51 -12
  245. package/src/i18n/ja.ts +51 -12
  246. package/src/i18n/ko.ts +51 -12
  247. package/src/i18n/zh-cn.ts +51 -12
  248. package/src/i18n/zh-tw.ts +51 -12
  249. package/src/layout/desks.ts +1 -1
  250. package/src/layout/launch-layout.ts +1 -1
  251. package/src/layout/pane-manager/floating-actions.ts +5 -3
  252. package/src/layout/pane-manager/floating.ts +43 -1
  253. package/src/layout/pane-manager/index.ts +2 -0
  254. package/src/layout/selected-ticker.ts +74 -0
  255. package/src/market-data/depositary-pair.ts +251 -0
  256. package/src/market-data/futures-board.ts +1 -1
  257. package/src/market-data/futures-contract.ts +124 -40
  258. package/src/market-data/fx-closes.ts +17 -2
  259. package/src/market-data/hooks.tsx +19 -11
  260. package/src/market-data/market/change-basis.ts +49 -7
  261. package/src/market-data/market/freshness.ts +34 -5
  262. package/src/market-data/market/period-return.ts +163 -0
  263. package/src/market-data/market/trading-sessions.ts +13 -0
  264. package/src/market-data/market/year-to-date.ts +8 -13
  265. package/src/market-data/performance.ts +20 -14
  266. package/src/market-data/perpetual-premium.ts +32 -0
  267. package/src/market-data/published-apac-sessions.ts +2 -1
  268. package/src/market-data/published-futures-sessions.ts +69 -0
  269. package/src/market-data/quotes/contributions.ts +5 -1
  270. package/src/market-data/quotes/freshness.ts +42 -0
  271. package/src/market-data/quotes/intraday-bar.ts +37 -0
  272. package/src/market-data/quotes/regular-session-valuation.ts +13 -8
  273. package/src/market-data/quotes/resolution.ts +4 -2
  274. package/src/market-data/tax-equivalent.ts +1 -1
  275. package/src/market-data/ticker-price-returns.ts +3 -1
  276. package/src/news/aggregator.ts +5 -1
  277. package/src/news/news-model.ts +4 -0
  278. package/src/news/types.ts +11 -0
  279. package/src/notifications/app-notifier.ts +1 -1
  280. package/src/plugins/auto-update.ts +2 -2
  281. package/src/plugins/builtin/account-management/index.tsx +1 -0
  282. package/src/plugins/builtin/account-management/pane.tsx +9 -8
  283. package/src/plugins/builtin/alerts/alert-engine.ts +30 -18
  284. package/src/plugins/builtin/alerts/calendar-events.ts +378 -0
  285. package/src/plugins/builtin/alerts/cli.ts +485 -76
  286. package/src/plugins/builtin/alerts/command.ts +5 -10
  287. package/src/plugins/builtin/alerts/event-rows.ts +9 -5
  288. package/src/plugins/builtin/alerts/events-pane.tsx +71 -56
  289. package/src/plugins/builtin/alerts/events.ts +108 -5
  290. package/src/plugins/builtin/alerts/fired-log.ts +78 -0
  291. package/src/plugins/builtin/alerts/format.ts +2 -1
  292. package/src/plugins/builtin/alerts/headless.ts +100 -39
  293. package/src/plugins/builtin/alerts/history-pane.tsx +105 -62
  294. package/src/plugins/builtin/alerts/history-rows.ts +89 -0
  295. package/src/plugins/builtin/alerts/index.tsx +45 -18
  296. package/src/plugins/builtin/alerts/iv-level.ts +365 -0
  297. package/src/plugins/builtin/alerts/levels.ts +3 -3
  298. package/src/plugins/builtin/alerts/pane.tsx +97 -29
  299. package/src/plugins/builtin/alerts/price.ts +35 -0
  300. package/src/plugins/builtin/alerts/quotes.ts +24 -0
  301. package/src/plugins/builtin/alerts/research-builder.ts +84 -11
  302. package/src/plugins/builtin/alerts/research-rules.ts +77 -3
  303. package/src/plugins/builtin/alerts/scheduled-check.ts +206 -32
  304. package/src/plugins/builtin/alerts/scheduled-sources.ts +26 -3
  305. package/src/plugins/builtin/alerts/scheduled.ts +188 -29
  306. package/src/plugins/builtin/alerts/storage.ts +13 -10
  307. package/src/plugins/builtin/alerts/targets.ts +12 -3
  308. package/src/plugins/builtin/analytics/index.tsx +8 -2
  309. package/src/plugins/builtin/analytics/metrics.ts +1 -1
  310. package/src/plugins/builtin/analytics/risk-book.ts +215 -0
  311. package/src/plugins/builtin/analytics/risk-client.ts +13 -6
  312. package/src/plugins/builtin/analytics/risk-headless.ts +55 -21
  313. package/src/plugins/builtin/analytics/risk-math.ts +6 -3
  314. package/src/plugins/builtin/analytics/risk-model.ts +297 -104
  315. package/src/plugins/builtin/analytics/risk-options.ts +17 -2
  316. package/src/plugins/builtin/analytics/risk-pane.tsx +107 -43
  317. package/src/plugins/builtin/attention/pane.tsx +22 -16
  318. package/src/plugins/builtin/awards/headless.ts +7 -3
  319. package/src/plugins/builtin/awards/model.ts +18 -0
  320. package/src/plugins/builtin/awards/pane.tsx +12 -9
  321. package/src/plugins/builtin/backtest/export.ts +1 -1
  322. package/src/plugins/builtin/backtest/headless.ts +3 -3
  323. package/src/plugins/builtin/backtest/rules.ts +41 -5
  324. package/src/plugins/builtin/broker-manager/add-flow.tsx +12 -7
  325. package/src/plugins/builtin/broker-manager/detail.tsx +47 -19
  326. package/src/plugins/builtin/broker-manager/footer.ts +27 -11
  327. package/src/plugins/builtin/broker-manager/index.tsx +21 -12
  328. package/src/plugins/builtin/broker-manager/keyboard.ts +1 -1
  329. package/src/plugins/builtin/broker-manager/model.ts +12 -2
  330. package/src/plugins/builtin/broker-manager/pane-actions.tsx +183 -57
  331. package/src/plugins/builtin/broker-manager/table.ts +28 -12
  332. package/src/plugins/builtin/broker-trading/account-picker.tsx +2 -1
  333. package/src/plugins/builtin/broker-trading/chart-levels.ts +82 -13
  334. package/src/plugins/builtin/broker-trading/controller.ts +45 -13
  335. package/src/plugins/builtin/broker-trading/dock.tsx +24 -4
  336. package/src/plugins/builtin/broker-trading/headless.ts +2 -1
  337. package/src/plugins/builtin/broker-trading/index.tsx +7 -1
  338. package/src/plugins/builtin/broker-trading/linked-orders.ts +148 -0
  339. package/src/plugins/builtin/broker-trading/order-feed.ts +75 -7
  340. package/src/plugins/builtin/broker-trading/orders.tsx +109 -31
  341. package/src/plugins/builtin/broker-trading/overview-orders.tsx +9 -3
  342. package/src/plugins/builtin/broker-trading/pane-model.ts +30 -2
  343. package/src/plugins/builtin/broker-trading/pane.tsx +115 -26
  344. package/src/plugins/builtin/broker-trading/ticket-parts.tsx +36 -7
  345. package/src/plugins/builtin/broker-trading/ticket.tsx +122 -36
  346. package/src/plugins/builtin/buildout/cells.tsx +4 -0
  347. package/src/plugins/builtin/buildout/detail/index.tsx +5 -1
  348. package/src/plugins/builtin/buildout/detail/ui.tsx +7 -4
  349. package/src/plugins/builtin/buildout/pane/index.tsx +34 -18
  350. package/src/plugins/builtin/buildout/pane/status.tsx +0 -4
  351. package/src/plugins/builtin/builtin-plugin-meta.ts +1 -1
  352. package/src/plugins/builtin/catalysts/client.ts +2 -2
  353. package/src/plugins/builtin/catalysts/detail.tsx +3 -2
  354. package/src/plugins/builtin/catalysts/index.tsx +1 -1
  355. package/src/plugins/builtin/catalysts/model.ts +49 -4
  356. package/src/plugins/builtin/catalysts/pane.tsx +9 -11
  357. package/src/plugins/builtin/central-bank-rates/client.ts +5 -0
  358. package/src/plugins/builtin/central-bank-rates/headless.ts +36 -10
  359. package/src/plugins/builtin/central-bank-rates/model.ts +33 -8
  360. package/src/plugins/builtin/changelog/index.tsx +1 -0
  361. package/src/plugins/builtin/chart-composer/catalog-inventory.ts +1 -0
  362. package/src/plugins/builtin/chart-composer/chart-spec-edit.ts +2 -1
  363. package/src/plugins/builtin/chart-composer/chart-spec.ts +7 -0
  364. package/src/plugins/builtin/chart-composer/cli-options.ts +2 -5
  365. package/src/plugins/builtin/chart-composer/data-catalog-pane.tsx +2 -1
  366. package/src/plugins/builtin/chart-composer/editor/controller.ts +2 -0
  367. package/src/plugins/builtin/chart-composer/editor.tsx +4 -1
  368. package/src/plugins/builtin/chart-composer/headless-schema.ts +28 -26
  369. package/src/plugins/builtin/chart-composer/headless.ts +253 -35
  370. package/src/plugins/builtin/chart-composer/index.tsx +12 -2
  371. package/src/plugins/builtin/chart-composer/leverage-overlay.ts +142 -0
  372. package/src/plugins/builtin/chart-composer/pane.tsx +128 -28
  373. package/src/plugins/builtin/chart-composer/series-catalog.ts +1 -0
  374. package/src/plugins/builtin/chart-composer/series-expression.ts +65 -6
  375. package/src/plugins/builtin/chart-composer/session-history.ts +15 -21
  376. package/src/plugins/builtin/chart-composer/session-range.ts +4 -2
  377. package/src/plugins/builtin/chart-composer/settings.ts +31 -19
  378. package/src/plugins/builtin/chart-composer/use-series-catalog.ts +5 -6
  379. package/src/plugins/builtin/chart-composer/viewport-labels.ts +18 -8
  380. package/src/plugins/builtin/chat/attachments/model.ts +3 -1
  381. package/src/plugins/builtin/chat/content/index.tsx +1 -1
  382. package/src/plugins/builtin/chat/pane-links/open.ts +1 -1
  383. package/src/plugins/builtin/chat/people.ts +1 -1
  384. package/src/plugins/builtin/clinical-trials/client.ts +5 -2
  385. package/src/plugins/builtin/clinical-trials/model.ts +13 -4
  386. package/src/plugins/builtin/clinical-trials/pane.tsx +32 -12
  387. package/src/plugins/builtin/clinical-trials/ticker-sponsor.ts +17 -0
  388. package/src/plugins/builtin/cloud/askg/controller.ts +1 -1
  389. package/src/plugins/builtin/cloud/askg/lock-note.ts +1 -1
  390. package/src/plugins/builtin/cloud/askg/tool-display.ts +1 -1
  391. package/src/plugins/builtin/cloud/auth-commands.ts +3 -3
  392. package/src/plugins/builtin/cloud/team/pane-sections.tsx +105 -47
  393. package/src/plugins/builtin/cloud/team/pane-ui.tsx +42 -4
  394. package/src/plugins/builtin/cloud/team/pane.tsx +204 -64
  395. package/src/plugins/builtin/cloud/thesis/store.ts +45 -22
  396. package/src/plugins/builtin/cloud-tweets/registration.ts +1 -0
  397. package/src/plugins/builtin/commodities-energy/index.tsx +29 -2
  398. package/src/plugins/builtin/commodities-energy/view-state.ts +2 -0
  399. package/src/plugins/builtin/commodity-balances/pane.tsx +14 -8
  400. package/src/plugins/builtin/company-attention/app-rank.tsx +11 -10
  401. package/src/plugins/builtin/company-attention/building-model.ts +222 -0
  402. package/src/plugins/builtin/company-attention/building.tsx +172 -0
  403. package/src/plugins/builtin/company-attention/client.ts +117 -1
  404. package/src/plugins/builtin/company-attention/evidence.ts +16 -3
  405. package/src/plugins/builtin/company-attention/headless.ts +101 -5
  406. package/src/plugins/builtin/company-attention/index.tsx +6 -3
  407. package/src/plugins/builtin/company-attention/model.ts +33 -7
  408. package/src/plugins/builtin/company-attention/moves-model.ts +253 -0
  409. package/src/plugins/builtin/company-attention/moves.tsx +159 -0
  410. package/src/plugins/builtin/company-attention/pane.tsx +89 -31
  411. package/src/plugins/builtin/company-attention/signals-model.ts +229 -0
  412. package/src/plugins/builtin/company-attention/signals.tsx +160 -0
  413. package/src/plugins/builtin/company-kpis/headless.ts +3 -2
  414. package/src/plugins/builtin/company-kpis/model.ts +2 -2
  415. package/src/plugins/builtin/company-kpis/pane.tsx +5 -4
  416. package/src/plugins/builtin/composite-plugins.ts +2 -1
  417. package/src/plugins/builtin/congress-trades/headless.ts +1 -1
  418. package/src/plugins/builtin/connections/index.ts +1 -0
  419. package/src/plugins/builtin/correlation/headless-schema.ts +3 -2
  420. package/src/plugins/builtin/correlation/headless.ts +7 -4
  421. package/src/plugins/builtin/correlation/relationship/model.ts +1 -0
  422. package/src/plugins/builtin/correlation/settings.ts +1 -0
  423. package/src/plugins/builtin/cot/headless.ts +28 -6
  424. package/src/plugins/builtin/cot/model.ts +12 -0
  425. package/src/plugins/builtin/cot/pane.tsx +7 -5
  426. package/src/plugins/builtin/cpi/headless.ts +5 -1
  427. package/src/plugins/builtin/cpi/pane.tsx +11 -9
  428. package/src/plugins/builtin/credit-boards/model.ts +2 -0
  429. package/src/plugins/builtin/credit-documents/headless.ts +1 -1
  430. package/src/plugins/builtin/credit-documents/pane.tsx +8 -7
  431. package/src/plugins/builtin/crypto-board/client.ts +86 -0
  432. package/src/plugins/builtin/crypto-board/defi-view.tsx +218 -0
  433. package/src/plugins/builtin/crypto-board/defi.ts +239 -0
  434. package/src/plugins/builtin/crypto-board/headless.ts +117 -6
  435. package/src/plugins/builtin/crypto-board/index.tsx +8 -3
  436. package/src/plugins/builtin/crypto-board/model.ts +40 -8
  437. package/src/plugins/builtin/crypto-board/pane.tsx +55 -21
  438. package/src/plugins/builtin/crypto-board/series.ts +19 -1
  439. package/src/plugins/builtin/crypto-etf-flows/client.ts +60 -0
  440. package/src/plugins/builtin/crypto-etf-flows/headless.ts +132 -0
  441. package/src/plugins/builtin/crypto-etf-flows/index.tsx +44 -0
  442. package/src/plugins/builtin/crypto-etf-flows/model.ts +121 -0
  443. package/src/plugins/builtin/crypto-etf-flows/pane.tsx +193 -0
  444. package/src/plugins/builtin/debt-maturities/pane.tsx +4 -3
  445. package/src/plugins/builtin/debug/index.tsx +1 -0
  446. package/src/plugins/builtin/dividend-yield/index.tsx +1 -1
  447. package/src/plugins/builtin/docs/index.tsx +1 -1
  448. package/src/plugins/builtin/docs/pane.tsx +2 -2
  449. package/src/plugins/builtin/docs/targets.ts +1 -1
  450. package/src/plugins/builtin/doe/client.ts +5 -1
  451. package/src/plugins/builtin/doe/headless.ts +12 -6
  452. package/src/plugins/builtin/doe/model.ts +43 -6
  453. package/src/plugins/builtin/doe/pane.tsx +19 -12
  454. package/src/plugins/builtin/earnings/board-model.ts +13 -6
  455. package/src/plugins/builtin/earnings/board-table.ts +4 -1
  456. package/src/plugins/builtin/earnings/board.tsx +253 -50
  457. package/src/plugins/builtin/earnings/calendar-model.ts +188 -0
  458. package/src/plugins/builtin/earnings/calendar.tsx +338 -0
  459. package/src/plugins/builtin/earnings/client.ts +4 -3
  460. package/src/plugins/builtin/earnings/headless.ts +53 -15
  461. package/src/plugins/builtin/earnings/history-model.ts +53 -36
  462. package/src/plugins/builtin/earnings/index.tsx +15 -22
  463. package/src/plugins/builtin/earnings/model.ts +17 -12
  464. package/src/plugins/builtin/earnings/scope.ts +89 -0
  465. package/src/plugins/builtin/earnings-calls/calendar.tsx +310 -0
  466. package/src/plugins/builtin/earnings-calls/data.ts +146 -2
  467. package/src/plugins/builtin/earnings-calls/headless.ts +151 -9
  468. package/src/plugins/builtin/earnings-calls/index.tsx +3 -3
  469. package/src/plugins/builtin/earnings-calls/lock-note.ts +1 -1
  470. package/src/plugins/builtin/earnings-calls/pane.tsx +149 -31
  471. package/src/plugins/builtin/earnings-calls/upcoming.ts +195 -0
  472. package/src/plugins/builtin/earnings-ripple/pane.tsx +10 -5
  473. package/src/plugins/builtin/econ/calendar-model.ts +132 -20
  474. package/src/plugins/builtin/econ/detail-view.tsx +48 -10
  475. package/src/plugins/builtin/econ/fred-catalog.ts +23 -6
  476. package/src/plugins/builtin/econ/fred-series-map.ts +4 -0
  477. package/src/plugins/builtin/econ/index.tsx +112 -25
  478. package/src/plugins/builtin/econ/print-watch.ts +2 -1
  479. package/src/plugins/builtin/econ/types.ts +32 -1
  480. package/src/plugins/builtin/econ-statistics/client.ts +16 -3
  481. package/src/plugins/builtin/econ-statistics/defs.ts +4 -0
  482. package/src/plugins/builtin/econ-statistics/detail.tsx +2 -2
  483. package/src/plugins/builtin/econ-statistics/headless.ts +13 -2
  484. package/src/plugins/builtin/econ-statistics/index.tsx +3 -3
  485. package/src/plugins/builtin/econ-statistics/pane.tsx +2 -1
  486. package/src/plugins/builtin/econ-statistics/stats.ts +103 -0
  487. package/src/plugins/builtin/econ-statistics/view.ts +16 -1
  488. package/src/plugins/builtin/equity-screener/client.ts +21 -3
  489. package/src/plugins/builtin/equity-screener/headless.ts +77 -5
  490. package/src/plugins/builtin/equity-screener/live.ts +1 -1
  491. package/src/plugins/builtin/equity-screener/model.ts +34 -0
  492. package/src/plugins/builtin/equity-screener/pane.tsx +148 -106
  493. package/src/plugins/builtin/equity-screener/screen-check.ts +90 -0
  494. package/src/plugins/builtin/equity-screener/ticker-check.tsx +148 -0
  495. package/src/plugins/builtin/estimate-revisions/headless.ts +3 -1
  496. package/src/plugins/builtin/estimate-revisions/lock-note.ts +3 -3
  497. package/src/plugins/builtin/estimate-revisions/model.ts +8 -10
  498. package/src/plugins/builtin/exposure/headless.ts +51 -6
  499. package/src/plugins/builtin/exposure/index.tsx +28 -2
  500. package/src/plugins/builtin/exposure/model.ts +7 -0
  501. package/src/plugins/builtin/exposure/pane.tsx +16 -10
  502. package/src/plugins/builtin/fear-greed/index.tsx +1 -1
  503. package/src/plugins/builtin/filing-events/index.tsx +1 -1
  504. package/src/plugins/builtin/futures/model.ts +10 -9
  505. package/src/plugins/builtin/futures/returns.ts +8 -36
  506. package/src/plugins/builtin/futures/table.tsx +1 -1
  507. package/src/plugins/builtin/futures-curve/client.ts +40 -9
  508. package/src/plugins/builtin/futures-curve/headless.ts +39 -17
  509. package/src/plugins/builtin/futures-curve/model.ts +258 -69
  510. package/src/plugins/builtin/futures-curve/pane.tsx +46 -17
  511. package/src/plugins/builtin/fx-matrix/client.ts +15 -8
  512. package/src/plugins/builtin/fx-matrix/headless.ts +32 -14
  513. package/src/plugins/builtin/fx-matrix/index.tsx +13 -11
  514. package/src/plugins/builtin/fx-matrix/live-legs.ts +22 -0
  515. package/src/plugins/builtin/fx-matrix/settings.ts +2 -1
  516. package/src/plugins/builtin/gpu/board.tsx +4 -1
  517. package/src/plugins/builtin/gpu/changes.tsx +10 -10
  518. package/src/plugins/builtin/gpu/equities.tsx +4 -1
  519. package/src/plugins/builtin/gpu/headless.ts +9 -4
  520. package/src/plugins/builtin/gpu/history.tsx +4 -2
  521. package/src/plugins/builtin/gpu/pane.tsx +5 -3
  522. package/src/plugins/builtin/help/index.tsx +13 -3
  523. package/src/plugins/builtin/holders/beneficial-model.ts +8 -11
  524. package/src/plugins/builtin/holders/beneficial-report.ts +6 -5
  525. package/src/plugins/builtin/holders/beneficial-view.tsx +7 -3
  526. package/src/plugins/builtin/holders/client.ts +15 -2
  527. package/src/plugins/builtin/holders/format.ts +28 -17
  528. package/src/plugins/builtin/holders/headless.ts +48 -8
  529. package/src/plugins/builtin/holders/index-holders.ts +264 -0
  530. package/src/plugins/builtin/holders/pane.tsx +79 -15
  531. package/src/plugins/builtin/holders/report-rows.ts +35 -7
  532. package/src/plugins/builtin/holders/table-model.ts +2 -1
  533. package/src/plugins/builtin/holders/thirteenf-match.ts +3 -1
  534. package/src/plugins/builtin/holders/treemap.tsx +2 -2
  535. package/src/plugins/builtin/insider/base-values.ts +11 -7
  536. package/src/plugins/builtin/insider/client.ts +3 -0
  537. package/src/plugins/builtin/insider/headless.ts +20 -7
  538. package/src/plugins/builtin/insider/index.tsx +17 -8
  539. package/src/plugins/builtin/insider/issuer.ts +34 -4
  540. package/src/plugins/builtin/insider/signals-client.ts +3 -3
  541. package/src/plugins/builtin/insider/signals.tsx +1 -1
  542. package/src/plugins/builtin/insider/table-model.ts +35 -13
  543. package/src/plugins/builtin/insider/table.tsx +5 -2
  544. package/src/plugins/builtin/ipo-calendar/pane.tsx +7 -4
  545. package/src/plugins/builtin/iv-history/client.ts +20 -0
  546. package/src/plugins/builtin/iv-history/events.ts +145 -0
  547. package/src/plugins/builtin/iv-history/format.ts +3 -0
  548. package/src/plugins/builtin/iv-history/headless.ts +91 -7
  549. package/src/plugins/builtin/iv-history/index.tsx +1 -1
  550. package/src/plugins/builtin/iv-history/model.ts +13 -4
  551. package/src/plugins/builtin/iv-history/series.ts +3 -1
  552. package/src/plugins/builtin/jobs/lock-note.ts +1 -1
  553. package/src/plugins/builtin/jobs/model.ts +4 -15
  554. package/src/plugins/builtin/jobs/pane.tsx +7 -5
  555. package/src/plugins/builtin/jobs/share-bars.tsx +11 -5
  556. package/src/plugins/builtin/jodi/pane.tsx +14 -8
  557. package/src/plugins/builtin/layout-manager/index.tsx +1 -0
  558. package/src/plugins/builtin/macro-day/headless.ts +20 -7
  559. package/src/plugins/builtin/macro-day/index.tsx +3 -2
  560. package/src/plugins/builtin/macro-day/model.ts +29 -8
  561. package/src/plugins/builtin/macro-day/pane.tsx +46 -10
  562. package/src/plugins/builtin/macro-day/releases.ts +55 -13
  563. package/src/plugins/builtin/market-heatmap/data.ts +9 -2
  564. package/src/plugins/builtin/market-heatmap/evidence.ts +1 -1
  565. package/src/plugins/builtin/market-heatmap/headless.ts +9 -6
  566. package/src/plugins/builtin/market-heatmap/index.tsx +3 -3
  567. package/src/plugins/builtin/market-heatmap/model.ts +10 -7
  568. package/src/plugins/builtin/market-movers/client.ts +36 -21
  569. package/src/plugins/builtin/market-movers/headless.ts +8 -2
  570. package/src/plugins/builtin/market-movers/index.tsx +16 -10
  571. package/src/plugins/builtin/market-movers/screener.ts +33 -11
  572. package/src/plugins/builtin/market-movers/session-body.tsx +4 -2
  573. package/src/plugins/builtin/market-movers/session-table.ts +4 -2
  574. package/src/plugins/builtin/market-movers/table.ts +4 -1
  575. package/src/plugins/builtin/market-valuation/headless.ts +2 -0
  576. package/src/plugins/builtin/market-valuation/view.ts +5 -0
  577. package/src/plugins/builtin/members/headless.ts +6 -5
  578. package/src/plugins/builtin/members/pane.tsx +11 -4
  579. package/src/plugins/builtin/mna/client.ts +1 -0
  580. package/src/plugins/builtin/mna/detail.tsx +20 -32
  581. package/src/plugins/builtin/mna/distress/detail.tsx +16 -4
  582. package/src/plugins/builtin/mna/distress/model.ts +3 -2
  583. package/src/plugins/builtin/mna/distress/pane.tsx +7 -4
  584. package/src/plugins/builtin/mna/headless.ts +6 -13
  585. package/src/plugins/builtin/mna/model.ts +93 -15
  586. package/src/plugins/builtin/mna/pane.tsx +5 -4
  587. package/src/plugins/builtin/news/headless.ts +12 -6
  588. package/src/plugins/builtin/news/index.tsx +10 -1
  589. package/src/plugins/builtin/news/wire/index.tsx +3 -2
  590. package/src/plugins/builtin/news/wire/news/command-bar-search.ts +26 -10
  591. package/src/plugins/builtin/news/wire/news/query-presets.ts +6 -2
  592. package/src/plugins/builtin/news/wire/rss/cli.ts +3 -3
  593. package/src/plugins/builtin/notes/cli.ts +50 -15
  594. package/src/plugins/builtin/notes/export.ts +17 -6
  595. package/src/plugins/builtin/notes/files.ts +16 -5
  596. package/src/plugins/builtin/openfda/pane.tsx +1 -1
  597. package/src/plugins/builtin/options/carry.ts +2 -2
  598. package/src/plugins/builtin/options/enrichment-model.ts +10 -9
  599. package/src/plugins/builtin/options/index.tsx +1 -1
  600. package/src/plugins/builtin/options/model-spot.ts +70 -4
  601. package/src/plugins/builtin/options/view.tsx +51 -23
  602. package/src/plugins/builtin/options-calculator/headless.ts +46 -7
  603. package/src/plugins/builtin/options-calculator/pane.tsx +3 -2
  604. package/src/plugins/builtin/options-positioning/headless.ts +11 -3
  605. package/src/plugins/builtin/options-positioning/model.ts +24 -0
  606. package/src/plugins/builtin/options-positioning/pane.tsx +10 -12
  607. package/src/plugins/builtin/options-scenario/client.ts +142 -29
  608. package/src/plugins/builtin/options-scenario/collar.ts +8 -6
  609. package/src/plugins/builtin/options-scenario/csp-screen-headless.ts +127 -0
  610. package/src/plugins/builtin/options-scenario/csp-screen-pane.tsx +165 -0
  611. package/src/plugins/builtin/options-scenario/csp-screen.ts +258 -0
  612. package/src/plugins/builtin/options-scenario/csp.ts +101 -21
  613. package/src/plugins/builtin/options-scenario/headless.ts +49 -21
  614. package/src/plugins/builtin/options-scenario/hedge.ts +20 -14
  615. package/src/plugins/builtin/options-scenario/index.tsx +28 -3
  616. package/src/plugins/builtin/options-scenario/model.ts +13 -0
  617. package/src/plugins/builtin/options-scenario/pane.tsx +22 -10
  618. package/src/plugins/builtin/perps/equity-row.tsx +11 -3
  619. package/src/plugins/builtin/perps/freshness.ts +8 -5
  620. package/src/plugins/builtin/perps/headless.ts +3 -1
  621. package/src/plugins/builtin/perps/list-perpetuals.ts +25 -4
  622. package/src/plugins/builtin/perps/live-rows.ts +161 -0
  623. package/src/plugins/builtin/perps/markets-section.tsx +154 -0
  624. package/src/plugins/builtin/perps/pane.tsx +36 -17
  625. package/src/plugins/builtin/perps/venue-markets.ts +96 -0
  626. package/src/plugins/builtin/plugin-marketplace/index.tsx +2 -1
  627. package/src/plugins/builtin/plugin-marketplace/pane.tsx +145 -60
  628. package/src/plugins/builtin/portfolio-list/cli/bulk-symbols.ts +78 -27
  629. package/src/plugins/builtin/portfolio-list/cli/portfolio-command.ts +158 -141
  630. package/src/plugins/builtin/portfolio-list/cli/render.ts +49 -20
  631. package/src/plugins/builtin/portfolio-list/cli/shared.ts +3 -3
  632. package/src/plugins/builtin/portfolio-list/cli/watchlist-command.ts +29 -24
  633. package/src/plugins/builtin/portfolio-list/headless.ts +6 -3
  634. package/src/plugins/builtin/portfolio-list/income.ts +13 -2
  635. package/src/plugins/builtin/portfolio-list/index.tsx +9 -2
  636. package/src/plugins/builtin/portfolio-list/pane/index.tsx +21 -8
  637. package/src/plugins/builtin/portfolio-list/pane/purchase-date-fx.ts +46 -0
  638. package/src/plugins/builtin/portfolio-list/summary/live-accounts.ts +16 -9
  639. package/src/plugins/builtin/portfolio-list/summary/totals.ts +2 -15
  640. package/src/plugins/builtin/power/client.ts +6 -3
  641. package/src/plugins/builtin/power/evidence.ts +22 -7
  642. package/src/plugins/builtin/power/gas.tsx +5 -1
  643. package/src/plugins/builtin/power/pane.tsx +44 -32
  644. package/src/plugins/builtin/power/prices.tsx +10 -3
  645. package/src/plugins/builtin/research/analyst-headless.ts +25 -8
  646. package/src/plugins/builtin/research/analyst-model.ts +68 -3
  647. package/src/plugins/builtin/research/corporate-actions-pane.tsx +63 -14
  648. package/src/plugins/builtin/research/event-model.ts +3 -1
  649. package/src/plugins/builtin/research/event-sources.ts +12 -4
  650. package/src/plugins/builtin/research/index.tsx +2 -1
  651. package/src/plugins/builtin/research/relative-valuation-basis.ts +58 -0
  652. package/src/plugins/builtin/research/relative-valuation-columns.ts +31 -2
  653. package/src/plugins/builtin/research/relative-valuation-currency.ts +12 -5
  654. package/src/plugins/builtin/research/relative-valuation-headless.ts +84 -26
  655. package/src/plugins/builtin/research/relative-valuation-model.ts +88 -19
  656. package/src/plugins/builtin/research/relative-valuation-pane.tsx +76 -9
  657. package/src/plugins/builtin/research/relative-valuation-peers.ts +1 -1
  658. package/src/plugins/builtin/reverse-dcf/client.ts +2 -1
  659. package/src/plugins/builtin/reverse-dcf/model.ts +10 -5
  660. package/src/plugins/builtin/risk-factors/index.tsx +2 -2
  661. package/src/plugins/builtin/scanner/lock-note.ts +1 -1
  662. package/src/plugins/builtin/seasonality/client.ts +2 -1
  663. package/src/plugins/builtin/sec/forms.ts +13 -0
  664. package/src/plugins/builtin/sec/fund-abroad.ts +32 -0
  665. package/src/plugins/builtin/sec/fund-facts.ts +68 -8
  666. package/src/plugins/builtin/sec/headless.ts +85 -8
  667. package/src/plugins/builtin/sec/index.tsx +58 -12
  668. package/src/plugins/builtin/sectors/client.ts +6 -4
  669. package/src/plugins/builtin/sectors/sector-model.ts +11 -15
  670. package/src/plugins/builtin/series-inventory.ts +2 -0
  671. package/src/plugins/builtin/shared/broker-reconnect.ts +107 -22
  672. package/src/plugins/builtin/shared/cloud-resource.ts +15 -2
  673. package/src/plugins/builtin/shared/cloud-upgrade.ts +34 -6
  674. package/src/plugins/builtin/shared/earnings-calendar.ts +375 -0
  675. package/src/plugins/builtin/{earnings/estimate-basis.ts → shared/earnings-estimate-basis.ts} +1 -1
  676. package/src/plugins/builtin/shared/earnings-report.ts +3 -3
  677. package/src/plugins/builtin/shared/fx-rate-freshness.ts +23 -1
  678. package/src/plugins/builtin/shared/job-posting.ts +129 -0
  679. package/src/plugins/builtin/shared/pro-lock-note.ts +3 -3
  680. package/src/plugins/builtin/shared/report-freshness.ts +3 -0
  681. package/src/plugins/builtin/shared/research-trading.tsx +23 -0
  682. package/src/plugins/builtin/shared/series-cache.ts +2 -0
  683. package/src/plugins/builtin/shared/series-list-detail.tsx +3 -1
  684. package/src/plugins/builtin/shared/ticker-surface.ts +2 -1
  685. package/src/plugins/builtin/shared/volatility/options.ts +2 -1
  686. package/src/plugins/builtin/short-interest/client.ts +2 -0
  687. package/src/plugins/builtin/short-interest/headless.ts +41 -12
  688. package/src/plugins/builtin/short-interest/index.tsx +23 -1
  689. package/src/plugins/builtin/short-interest/model.ts +70 -19
  690. package/src/plugins/builtin/short-interest/pane.tsx +19 -2
  691. package/src/plugins/builtin/short-interest/publications-client.ts +82 -0
  692. package/src/plugins/builtin/short-interest/publications-headless.ts +29 -0
  693. package/src/plugins/builtin/short-interest/publications-model.ts +50 -0
  694. package/src/plugins/builtin/short-interest/publications-pane.tsx +66 -0
  695. package/src/plugins/builtin/short-interest/schedule.ts +35 -2
  696. package/src/plugins/builtin/short-interest/surface.tsx +11 -4
  697. package/src/plugins/builtin/short-interest/types.ts +9 -0
  698. package/src/plugins/builtin/short-interest/watch-client.ts +14 -8
  699. package/src/plugins/builtin/short-interest/watch-model.ts +12 -25
  700. package/src/plugins/builtin/short-interest/watch-pane.tsx +5 -1
  701. package/src/plugins/builtin/social-mentions/client.ts +2 -1
  702. package/src/plugins/builtin/supply-chain/flow.tsx +33 -9
  703. package/src/plugins/builtin/supply-chain/model.ts +51 -3
  704. package/src/plugins/builtin/supply-chain/pane.tsx +78 -39
  705. package/src/plugins/builtin/supply-chain/row-evidence.tsx +1 -1
  706. package/src/plugins/builtin/themes/headless.ts +8 -5
  707. package/src/plugins/builtin/themes/model.ts +14 -4
  708. package/src/plugins/builtin/themes/pane.tsx +24 -5
  709. package/src/plugins/builtin/thirteenf/headless.ts +5 -5
  710. package/src/plugins/builtin/thirteenf/signals.ts +3 -1
  711. package/src/plugins/builtin/ticker-detail/adr-pair/headless.ts +123 -0
  712. package/src/plugins/builtin/ticker-detail/adr-pair/model.ts +132 -0
  713. package/src/plugins/builtin/ticker-detail/adr-pair/tab.tsx +87 -0
  714. package/src/plugins/builtin/ticker-detail/data-panes/historical-prices.tsx +40 -26
  715. package/src/plugins/builtin/ticker-detail/data-panes/history-bars.ts +8 -4
  716. package/src/plugins/builtin/ticker-detail/data-panes/returns-history.ts +67 -3
  717. package/src/plugins/builtin/ticker-detail/data-panes/returns-model.ts +112 -5
  718. package/src/plugins/builtin/ticker-detail/data-panes/returns-pane.tsx +17 -2
  719. package/src/plugins/builtin/ticker-detail/financials/aggregation.ts +21 -7
  720. package/src/plugins/builtin/ticker-detail/financials/model.ts +36 -1
  721. package/src/plugins/builtin/ticker-detail/financials/offerings.ts +56 -0
  722. package/src/plugins/builtin/ticker-detail/financials/ratios.ts +62 -13
  723. package/src/plugins/builtin/ticker-detail/financials/tab.tsx +30 -4
  724. package/src/plugins/builtin/ticker-detail/headless-schema.ts +14 -2
  725. package/src/plugins/builtin/ticker-detail/headless.ts +148 -35
  726. package/src/plugins/builtin/ticker-detail/index.tsx +37 -5
  727. package/src/plugins/builtin/ticker-detail/overview/model.ts +65 -10
  728. package/src/plugins/builtin/ticker-detail/overview/pane.tsx +9 -1
  729. package/src/plugins/builtin/ticker-detail/overview-tab.tsx +68 -11
  730. package/src/plugins/builtin/ticker-detail/pane.tsx +11 -0
  731. package/src/plugins/builtin/ticker-detail/quote-footer.ts +8 -3
  732. package/src/plugins/builtin/ticker-detail/research-tabs.ts +11 -0
  733. package/src/plugins/builtin/vol-surface/client.ts +28 -7
  734. package/src/plugins/builtin/vol-surface/headless.ts +43 -15
  735. package/src/plugins/builtin/vol-surface/model.ts +34 -12
  736. package/src/plugins/builtin/vol-surface/pane.tsx +33 -13
  737. package/src/plugins/builtin/vol-surface/stored.ts +34 -3
  738. package/src/plugins/builtin/vol-surface/tables.ts +14 -0
  739. package/src/plugins/builtin/volatility/model.ts +5 -10
  740. package/src/plugins/builtin/world-venue-map/basemap-layer.tsx +4 -3
  741. package/src/plugins/builtin/world-venue-map/basemap.ts +3 -1
  742. package/src/plugins/builtin/world-venue-map/chokepoint-chart.ts +40 -0
  743. package/src/plugins/builtin/world-venue-map/evidence.ts +1 -1
  744. package/src/plugins/builtin/world-venue-map/geo-series.ts +90 -11
  745. package/src/plugins/builtin/world-venue-map/headless.ts +1 -1
  746. package/src/plugins/builtin/world-venue-map/index.ts +3 -26
  747. package/src/plugins/builtin/world-venue-map/layers.ts +1 -1
  748. package/src/plugins/builtin/world-venue-map/map.tsx +2 -1
  749. package/src/plugins/builtin/world-venue-map/pane.tsx +4 -2
  750. package/src/plugins/builtin/world-venue-map/venue-header.tsx +15 -4
  751. package/src/plugins/builtin/yield-curve/client.ts +25 -0
  752. package/src/plugins/builtin/yield-curve/curves.ts +7 -4
  753. package/src/plugins/builtin/yield-curve/headless.ts +38 -4
  754. package/src/plugins/builtin/yield-curve/history.ts +4 -3
  755. package/src/plugins/builtin/yield-curve/index.tsx +12 -6
  756. package/src/plugins/builtin/yield-curve/swaps-model.ts +93 -0
  757. package/src/plugins/builtin/yield-curve/swaps.tsx +99 -0
  758. package/src/plugins/bundle.ts +1 -1
  759. package/src/plugins/catalog-browser.ts +2 -1
  760. package/src/plugins/compat.ts +3 -3
  761. package/src/plugins/dependencies.ts +75 -14
  762. package/src/plugins/extracted-plugins.ts +132 -34
  763. package/src/plugins/host-link.ts +149 -34
  764. package/src/plugins/installer.ts +35 -10
  765. package/src/plugins/loader.ts +206 -38
  766. package/src/plugins/manager-node.ts +2 -2
  767. package/src/plugins/marketplace/deactivation.ts +22 -0
  768. package/src/plugins/marketplace/model.ts +2 -2
  769. package/src/plugins/marketplace/packs.ts +1 -1
  770. package/src/plugins/ownership.ts +1 -1
  771. package/src/plugins/peer-retry.ts +155 -0
  772. package/src/plugins/registry/contributions.ts +3 -1
  773. package/src/plugins/registry/index.ts +4 -3
  774. package/src/plugins/registry/plugin-state.ts +3 -0
  775. package/src/plugins/seed-notice.ts +20 -0
  776. package/src/plugins/shortcut-argument.ts +39 -0
  777. package/src/portfolio/allocation.ts +1 -1
  778. package/src/portfolio/collection-name.ts +31 -0
  779. package/src/portfolio/column-values.ts +10 -8
  780. package/src/portfolio/cost-fx.ts +296 -19
  781. package/src/portfolio/manual-lots.ts +75 -0
  782. package/src/portfolio/mutations.ts +60 -22
  783. package/src/portfolio/suffixed-listings.ts +209 -0
  784. package/src/portfolio/totals-currency.ts +24 -0
  785. package/src/public/__snapshots__/public-api.test.ts.snap +14 -0
  786. package/src/public/time-series.ts +11 -8
  787. package/src/remote/schema.ts +1 -1
  788. package/src/renderers/browser/config-host.ts +3 -0
  789. package/src/renderers/browser/main.tsx +23 -3
  790. package/src/renderers/dom/boot-frame-page.ts +187 -0
  791. package/src/renderers/dom/boot-frame.ts +237 -0
  792. package/src/renderers/dom/build-assets.ts +46 -8
  793. package/src/renderers/dom/desktop/controls.tsx +1 -1
  794. package/src/renderers/dom/desktop/query-bar.tsx +2 -0
  795. package/src/renderers/dom/dom-ui-host.tsx +4 -29
  796. package/src/renderers/dom/host/ascii-text.ts +16 -2
  797. package/src/renderers/dom/host/box.tsx +43 -2
  798. package/src/renderers/dom/host/chart-surface.tsx +2 -0
  799. package/src/renderers/dom/host/hls.chunk.ts +3 -0
  800. package/src/renderers/dom/host/image-surface.tsx +49 -0
  801. package/src/renderers/dom/host/media-surface.tsx +24 -18
  802. package/src/renderers/dom/host/mouse.ts +30 -0
  803. package/src/renderers/dom/host/size-observer.ts +1 -1
  804. package/src/renderers/dom/host/style.ts +1 -1
  805. package/src/renderers/dom/host/tabs.tsx +16 -5
  806. package/src/renderers/dom/host/top-surface.ts +127 -0
  807. package/src/renderers/dom/styles.css +115 -0
  808. package/src/renderers/dom/test-utils.tsx +2 -1
  809. package/src/renderers/electrobun/bun/application-menu/index.ts +3 -3
  810. package/src/renderers/electrobun/bun/core-capabilities.ts +9 -1
  811. package/src/renderers/electrobun/bun/desktop/backend-requests.ts +3 -0
  812. package/src/renderers/electrobun/bun/desktop/backend.ts +56 -3
  813. package/src/renderers/electrobun/bun/desktop/detached-windows.ts +1 -1
  814. package/src/renderers/electrobun/bun/desktop/host-requests.ts +9 -3
  815. package/src/renderers/electrobun/bun/desktop/initialization.ts +81 -18
  816. package/src/renderers/electrobun/bun/desktop/update.ts +210 -30
  817. package/src/renderers/electrobun/bun/external-plugins.ts +29 -7
  818. package/src/renderers/electrobun/bun/index.ts +11 -1
  819. package/src/renderers/electrobun/bun/window/boot-frame.ts +67 -0
  820. package/src/renderers/electrobun/bun/window/create.ts +4 -1
  821. package/src/renderers/electrobun/shared/boot-frame.ts +7 -0
  822. package/src/renderers/electrobun/shared/protocol.ts +6 -1
  823. package/src/renderers/electrobun/view/cli-pane-shot-entry.tsx +1 -1
  824. package/src/renderers/electrobun/view/config-host.ts +3 -0
  825. package/src/renderers/electrobun/view/fatal-screen.tsx +1 -1
  826. package/src/renderers/electrobun/view/main.tsx +30 -4
  827. package/src/renderers/electrobun/view/news-source.ts +9 -7
  828. package/src/renderers/electrobun/view/remote/asset-data-client.ts +9 -2
  829. package/src/renderers/electrobun/view/ui-host.tsx +1 -1
  830. package/src/renderers/opentui/browser-open.ts +88 -0
  831. package/src/renderers/opentui/host.tsx +5 -14
  832. package/src/renderers/opentui/image/loader.ts +3 -2
  833. package/src/renderers/opentui/native-smoke.ts +10 -1
  834. package/src/renderers/opentui/pane-image/index.ts +2 -1
  835. package/src/renderers/opentui/render-lib.ts +253 -0
  836. package/src/renderers/opentui/render-timing-smoke.ts +1 -1
  837. package/src/renderers/opentui/start.tsx +8 -1
  838. package/src/renderers/share/layout-view.tsx +2 -2
  839. package/src/renderers/share/main.tsx +4 -4
  840. package/src/renderers/share/view.tsx +1 -1
  841. package/src/series/resolve.ts +22 -6
  842. package/src/series/standalone.ts +30 -2
  843. package/src/series/types.ts +8 -1
  844. package/src/shares/api.ts +4 -1
  845. package/src/shares/pane.ts +1 -1
  846. package/src/sources/gloomberb-cloud/fred-series.ts +46 -1
  847. package/src/sources/gloomberb-cloud/index.ts +39 -16
  848. package/src/sources/gloomberb-cloud/news.ts +39 -0
  849. package/src/sources/gloomberb-cloud/normalizers.ts +14 -1
  850. package/src/sources/gloomberb-cloud/perpetuals.ts +49 -1
  851. package/src/sources/listing-symbols.ts +37 -0
  852. package/src/sources/provider-errors.ts +16 -2
  853. package/src/sources/provider-router/financial-routes.ts +21 -3
  854. package/src/sources/provider-router/financials.ts +15 -2
  855. package/src/sources/provider-router/history.ts +30 -8
  856. package/src/sources/provider-router/index.ts +16 -0
  857. package/src/sources/provider-router/primary.ts +1 -1
  858. package/src/state/app/bootstrap.ts +23 -0
  859. package/src/state/hooks/inline-tickers.ts +30 -5
  860. package/src/sync/controller.ts +1 -1
  861. package/src/sync/core-contributors.ts +46 -14
  862. package/src/team/collections-sync.ts +2 -1
  863. package/src/team/collections.ts +178 -17
  864. package/src/telemetry/crash-reports.ts +21 -4
  865. package/src/telemetry/update-failures-node.ts +59 -0
  866. package/src/telemetry/update-failures.ts +307 -0
  867. package/src/test-support/builtin-panes.ts +1 -1
  868. package/src/theme/colors.ts +3 -30
  869. package/src/theme/ui-tokens.ts +37 -1
  870. package/src/tickers/company-name-listing.ts +215 -36
  871. package/src/tickers/company-name.ts +43 -0
  872. package/src/tickers/index-roots.ts +47 -0
  873. package/src/tickers/instrument-label.ts +5 -1
  874. package/src/tickers/listing-fate.ts +30 -0
  875. package/src/tickers/metadata.ts +10 -0
  876. package/src/tickers/perpetual-listing.ts +5 -2
  877. package/src/tickers/search/home-listing.ts +75 -0
  878. package/src/tickers/search/index.ts +76 -27
  879. package/src/tickers/search/ranking.ts +54 -4
  880. package/src/tickers/search/upsert.ts +29 -0
  881. package/src/tickers/terminal-codes.ts +416 -40
  882. package/src/time-series/bar-aggregation.ts +243 -0
  883. package/src/time-series/base-series.ts +307 -0
  884. package/src/time-series/chart-bounds.ts +349 -0
  885. package/src/time-series/chart-seed.ts +142 -0
  886. package/src/time-series/economic.ts +5 -0
  887. package/src/time-series/fundamentals.ts +18 -3
  888. package/src/time-series/history-acquisition.ts +499 -0
  889. package/src/time-series/leverage.ts +100 -0
  890. package/src/time-series/market-resolution.ts +4 -2
  891. package/src/time-series/market.ts +2 -1
  892. package/src/time-series/price-comparison.ts +175 -30
  893. package/src/time-series/range.ts +9 -1
  894. package/src/time-series/resolution.ts +174 -16
  895. package/src/time-series/resolve-context.ts +157 -0
  896. package/src/time-series/resolve.ts +126 -1577
  897. package/src/time-series/series-name.ts +38 -0
  898. package/src/time-series/series-presentation.ts +208 -0
  899. package/src/time-series/spec.ts +11 -6
  900. package/src/time-series/studies.ts +109 -12
  901. package/src/time-series/tail-reconcile.ts +121 -0
  902. package/src/time-series/types.ts +29 -2
  903. package/src/time-series/use-chart-resolution.ts +4 -5
  904. package/src/types/broker.ts +10 -0
  905. package/src/types/config.ts +14 -0
  906. package/src/types/data-provider.ts +20 -0
  907. package/src/types/exchange-rate.ts +6 -0
  908. package/src/types/financials.ts +104 -7
  909. package/src/types/headless.ts +83 -6
  910. package/src/types/instrument.ts +3 -0
  911. package/src/types/issuer-listings.ts +28 -0
  912. package/src/types/plugin.ts +65 -8
  913. package/src/types/price-history.ts +2 -0
  914. package/src/types/ticker.ts +13 -0
  915. package/src/types/trading.ts +59 -1
  916. package/src/ui/ascii-font.ts +13 -1
  917. package/src/ui/host.tsx +6 -1
  918. package/src/updater/command-names.ts +175 -0
  919. package/src/updater/failure.ts +163 -0
  920. package/src/updater/index.ts +97 -28
  921. package/src/utils/calendar-date.ts +32 -15
  922. package/src/utils/cash-runway.ts +241 -0
  923. package/src/utils/central-banks.ts +42 -0
  924. package/src/utils/cli-output.ts +259 -80
  925. package/src/utils/contract-month.ts +16 -0
  926. package/src/utils/crypto-pair.ts +61 -3
  927. package/src/utils/currency-pair.ts +26 -0
  928. package/src/utils/currency-units.ts +29 -0
  929. package/src/utils/datetime-format.ts +10 -0
  930. package/src/utils/debug-log.ts +1 -1
  931. package/src/utils/decimal-comma.ts +39 -6
  932. package/src/utils/exchange-announcements.ts +71 -0
  933. package/src/utils/exchange-rate-snapshot.ts +10 -0
  934. package/src/utils/financial-statements.ts +83 -4
  935. package/src/utils/format.ts +34 -16
  936. package/src/utils/fundamentals.ts +150 -34
  937. package/src/utils/fx-market-hours.ts +10 -1
  938. package/src/utils/latest-financial-period.ts +8 -0
  939. package/src/utils/linux-libc.ts +54 -0
  940. package/src/utils/market-capitalization.ts +111 -15
  941. package/src/utils/max-drawdown.ts +64 -0
  942. package/src/utils/network-failure.ts +83 -0
  943. package/src/utils/option-expiry.ts +139 -7
  944. package/src/utils/price-earnings.ts +11 -5
  945. package/src/utils/price-history.ts +18 -8
  946. package/src/utils/price-window.ts +131 -0
  947. package/src/utils/release-date.ts +47 -0
  948. package/src/utils/sec.ts +71 -0
  949. package/src/utils/throttled-fetch.ts +11 -4
  950. package/src/utils/trailing-eps.ts +67 -0
  951. package/src/utils/typed-text.ts +21 -0
  952. package/src/utils/utc-time.ts +24 -1
  953. package/src/version.ts +6 -0
  954. package/src/cli/pane-functions/screenshot.ts +0 -2122
@@ -5,6 +5,7 @@ import { useThemeColors } from "../../../../theme/theme-context";
5
5
  import { usePaneInstance } from "../../../../state/app/context";
6
6
  import { useViewport } from "../../../../react/input";
7
7
  import { measurePerf } from "../../../../utils/perf-marks";
8
+ import { displayWidth } from "../../../../utils/format";
8
9
  import { useDoubleClickActivation } from "../../../use-double-click-activation";
9
10
  import { useScrollBoxScrollActivity } from "../../../table-view-shared";
10
11
  import { EmptyState } from "../../status";
@@ -31,6 +32,7 @@ import {
31
32
  cutColumnText,
32
33
  resolveDataTableColumnClips,
33
34
  resolveDataTableVisibleWindow,
35
+ resolveMoreColumnsHint,
34
36
  reuseDataTableColumnClips,
35
37
  type DataTableColumnClip,
36
38
  } from "./model";
@@ -378,6 +380,27 @@ export function OpenTuiDataTable<T, C extends DataTableColumn = DataTableColumn>
378
380
  () => tableColumnStarts(displayColumns, columnGap),
379
381
  [columnGap, displayColumns],
380
382
  );
383
+ // Columns out of view past the right edge: the header row ends in "more →" there, a press on it scrolls to
384
+ // them, and the rows leave its cells blank, so a narrow pane says it has more than it shows. The header's
385
+ // scroll box is as wide as the body's viewport (measuredViewportWidth), so the header row has a blank cell
386
+ // past it, over the body's vertical scrollbar; the hint is laid over the row, not inside the scroll box,
387
+ // and takes that cell first.
388
+ const besideHeader = Math.max(0, Math.min(1, (scrollRef.current?.width ?? 0) - measuredViewportWidth));
389
+ const moreColumns = horizontalScrollbarVisible ? resolveMoreColumnsHint({
390
+ columns: displayColumns.map((column) => ({
391
+ width: column.width,
392
+ align: column.align,
393
+ label: sortColumnId === column.id ? `${column.label}${column.label ? " " : ""}▲` : column.label,
394
+ })),
395
+ columnGap,
396
+ columnStarts,
397
+ frozenFirstColumn: freezeFirstColumn,
398
+ besideHeader,
399
+ horizontalPadding,
400
+ scrollLeft,
401
+ viewportWidth: measuredViewportWidth,
402
+ }) : null;
403
+ const moreColumnsReserve = moreColumns?.reserve ?? 0;
381
404
  // A scroll step that cuts the columns as the last one did keeps the same
382
405
  // array, so the memoized rows skip the render.
383
406
  const columnClipsRef = useRef<readonly (DataTableColumnClip | null)[] | null>(null);
@@ -387,12 +410,13 @@ export function OpenTuiDataTable<T, C extends DataTableColumn = DataTableColumn>
387
410
  columnStarts,
388
411
  frozenFirstColumn: freezeFirstColumn,
389
412
  horizontalPadding,
413
+ rightReserve: moreColumnsReserve,
390
414
  scrollLeft,
391
415
  // A table that cannot scroll sideways fits its own columns; one it cut could never be scrolled to.
392
416
  viewportWidth: showHorizontalScrollbar ? measuredViewportWidth : 0,
393
417
  widths: displayColumns.map((column) => column.width),
394
418
  })),
395
- [columnGap, columnStarts, displayColumns, freezeFirstColumn, horizontalPadding, measuredViewportWidth, scrollLeft, showHorizontalScrollbar],
419
+ [columnGap, columnStarts, displayColumns, freezeFirstColumn, horizontalPadding, measuredViewportWidth, moreColumnsReserve, scrollLeft, showHorizontalScrollbar],
396
420
  );
397
421
  const reportVisibleRange = useVisibleRangeEmitter({
398
422
  itemCount: items.length,
@@ -454,6 +478,17 @@ export function OpenTuiDataTable<T, C extends DataTableColumn = DataTableColumn>
454
478
  scrollRef: headerScrollRef,
455
479
  onHorizontalScroll: syncBodyScroll,
456
480
  });
481
+ // "more →" steps right as Shift+Right does: half the viewport.
482
+ const scrollToMoreColumns = useCallback(() => {
483
+ const body = scrollRef.current;
484
+ const viewportWidth = body?.viewport?.width ?? 0;
485
+ if (!body || viewportWidth <= 0) return;
486
+ const maxLeft = Math.max(0, (body.scrollWidth ?? 0) - viewportWidth);
487
+ body.scrollLeft = Math.min(maxLeft, (body.scrollLeft ?? 0) + Math.max(1, Math.floor(viewportWidth / 2)));
488
+ syncHeaderScroll();
489
+ setScrollLeft(body.scrollLeft ?? 0);
490
+ nativeRenderer.requestRender();
491
+ }, [nativeRenderer, scrollRef, syncHeaderScroll]);
457
492
  const handleBodySizeChange = useCallback(() => {
458
493
  measureContentWidth();
459
494
  setScrollVersion((current) => current + 1);
@@ -616,7 +651,9 @@ export function OpenTuiDataTable<T, C extends DataTableColumn = DataTableColumn>
616
651
  const hasNextLabel = columnIndex < displayColumns.length - 1
617
652
  && tableColumnLeadGap(displayColumns, columnIndex + 1, columnGap) === 0;
618
653
  const label = column.label + indicator;
619
- const labelText = " ".repeat(inset) + (clip
654
+ // A figure the right edge cuts is blank in every row (cutColumnText), so its label is too.
655
+ const figuresCut = clip !== null && column.align === "right" && clip.inset + clip.width < column.width;
656
+ const labelText = figuresCut ? " ".repeat(inset + Math.max(0, clip.width)) : " ".repeat(inset) + (clip
620
657
  // Cut on the right, the label's last cell is the edge.
621
658
  ? cutColumnText(label, column.align, column.width, clip, (text, width, cutRight) => (
622
659
  fitTableHeaderText(text, width, column.align, hasNextLabel && !cutRight)
@@ -650,6 +687,28 @@ export function OpenTuiDataTable<T, C extends DataTableColumn = DataTableColumn>
650
687
  })}
651
688
  </Box>
652
689
  </ScrollBox>
690
+ {moreColumns ? (
691
+ <Box
692
+ position="absolute"
693
+ top={0}
694
+ left={moreColumns.left}
695
+ width={displayWidth(moreColumns.text)}
696
+ height={1}
697
+ zIndex={2}
698
+ backgroundColor={colors.panel}
699
+ hoverBackgroundColor={hoverBg(colors)}
700
+ cursor="pointer"
701
+ onMouseDown={(event: any) => {
702
+ event.preventDefault?.();
703
+ event.stopPropagation?.();
704
+ focusPane();
705
+ onTableMouseDown?.(event);
706
+ scrollToMoreColumns();
707
+ }}
708
+ >
709
+ <Text fg={colors.textDim}>{moreColumns.text}</Text>
710
+ </Box>
711
+ ) : null}
653
712
 
654
713
  <ScrollBox
655
714
  id={bodyScrollId}
@@ -1,4 +1,5 @@
1
1
  import { displayWidth } from "../../../../utils/format";
2
+ import { tableColumnLeadGap } from "../../table-layout";
2
3
 
3
4
  /**
4
5
  * Where the viewport cuts a column: `inset` cells hidden on its left (past the
@@ -61,10 +62,113 @@ export function reuseDataTableColumnClips(
61
62
  return previous.length === next.length && next.every((clip, index) => sameClip(clip, previous[index] ?? null)) ? previous : next;
62
63
  }
63
64
 
65
+ /**
66
+ * What a table's header says at its right edge while columns are out of view
67
+ * past it, longest first: the longest that fits beside the last column shown
68
+ * whole is drawn. With that column against the edge, the arrow takes the
69
+ * blank its label ends in. The hint never hides a column: with no blank to
70
+ * take, the horizontal scrollbar is the only sign.
71
+ */
72
+ const MORE_COLUMNS_LABELS = ["more →", "more", "→"] as const;
73
+
74
+ export interface MoreColumnsHint {
75
+ /** The cells the hint draws: its label, after a blank unless it takes the last column's own. */
76
+ text: string;
77
+ /** Where `text` starts, from the viewport's left edge. */
78
+ left: number;
79
+ /** Cells at the body's right edge the rows leave blank under the hint (`resolveDataTableColumnClips`). */
80
+ reserve: number;
81
+ }
82
+
83
+ interface HintColumn {
84
+ width: number;
85
+ align?: string;
86
+ /** The header label as drawn, with its sort mark. */
87
+ label: string;
88
+ }
89
+
90
+ /**
91
+ * Whether a column is out of view past the body's right edge at this scroll.
92
+ * A column the edge cuts counts when it shows nothing to read: figures cut on
93
+ * the right are blank (`cutColumnText`), and text shows less than its label.
94
+ * Text cut after its label ends in an ellipsis instead.
95
+ */
96
+ function hasColumnsPastRightEdge(columns: readonly HintColumn[], starts: readonly number[], right: number): boolean {
97
+ return columns.some((column, index) => {
98
+ const start = starts[index] ?? 0;
99
+ if (start + column.width <= right) return false;
100
+ const shown = right - start;
101
+ return shown <= 0 || (column.align ?? "left") !== "left" || shown < displayWidth(column.label);
102
+ });
103
+ }
104
+
105
+ /**
106
+ * The "more →" hint at the header's right edge while columns are out of view
107
+ * past it, or null. The header's scroll box is as wide as the viewport, and
108
+ * `besideHeader` blank cells follow it on the header row (the cell over the
109
+ * body's vertical scrollbar); the hint, laid over the row, can reach them.
110
+ * The hint sits after a blank: a gap, cells past the last column shown whole,
111
+ * or that column's own trailing blank (a label shorter than its column keeps
112
+ * one, `fitTableHeaderText`), and only cut columns give it room. Never in a
113
+ * viewport too narrow to show a column beside it, or before it is measured.
114
+ */
115
+ export function resolveMoreColumnsHint({
116
+ columns,
117
+ columnGap,
118
+ columnStarts,
119
+ besideHeader = 0,
120
+ frozenFirstColumn = false,
121
+ horizontalPadding,
122
+ scrollLeft,
123
+ viewportWidth,
124
+ }: {
125
+ columns: readonly HintColumn[];
126
+ columnGap: number;
127
+ /** Where each column's content starts, from the first column (tableColumnStarts). */
128
+ columnStarts: readonly number[];
129
+ /** Blank cells right of the header's scroll box on the header row. */
130
+ besideHeader?: number;
131
+ frozenFirstColumn?: boolean;
132
+ horizontalPadding: number;
133
+ scrollLeft: number;
134
+ viewportWidth: number;
135
+ }): MoreColumnsHint | null {
136
+ const longest = displayWidth(MORE_COLUMNS_LABELS[0]) + 1;
137
+ if (columns.length === 0 || viewportWidth < longest * 2) return null;
138
+ const right = scrollLeft + viewportWidth;
139
+ const starts = columns.map((_, index) => horizontalPadding + (columnStarts[index] ?? 0));
140
+ if (!hasColumnsPastRightEdge(columns, starts, right)) return null;
141
+ // The last column drawn whole (a frozen first column rides along with the scroll), and whether its label
142
+ // ends in a blank of its own.
143
+ let lastEnd = scrollLeft;
144
+ let lastPadded = false;
145
+ columns.forEach((column, index) => {
146
+ const start = (starts[index] ?? 0) + (frozenFirstColumn && index === 0 ? scrollLeft : 0);
147
+ const end = start + column.width;
148
+ if (end > right || end <= lastEnd) return;
149
+ lastEnd = end;
150
+ const next = columns[index + 1];
151
+ lastPadded = !!next && tableColumnLeadGap(columns, index + 1, columnGap) === 0 && displayWidth(column.label) < column.width;
152
+ });
153
+ const headerRight = right + Math.max(0, besideHeader);
154
+ const place = (label: string) => {
155
+ const labelStart = headerRight - displayWidth(label);
156
+ // The rows stop where the blank before the label starts, unless that blank is the last column's own.
157
+ const rowsEnd = labelStart === lastEnd && lastPadded ? lastEnd : labelStart - 1;
158
+ return { text: ` ${label}`, left: labelStart - 1 - scrollLeft, reserve: Math.max(0, right - rowsEnd), fits: rowsEnd >= lastEnd };
159
+ };
160
+ const fitted = MORE_COLUMNS_LABELS.map(place).find((candidate) => candidate.fits);
161
+ if (fitted) return { text: fitted.text, left: fitted.left, reserve: fitted.reserve };
162
+ // The last column ends at the header's edge: the arrow takes its label's trailing blank, the rows keep it.
163
+ if (lastPadded && headerRight === lastEnd) return { text: MORE_COLUMNS_LABELS[2], left: lastEnd - 1 - scrollLeft, reserve: 0 };
164
+ return null;
165
+ }
166
+
64
167
  /**
65
168
  * Each column's clip at the current scroll, null for a column shown whole.
66
169
  * A frozen first column stays, and what slides under it counts as cut on the
67
- * left. Null for the whole table when every column is whole or nothing is
170
+ * left. `rightReserve` cells at the right edge show no column (under the
171
+ * "more →" hint, `resolveMoreColumnsHint`). Null for the whole table when every column is whole or nothing is
68
172
  * measured yet.
69
173
  */
70
174
  export function resolveDataTableColumnClips({
@@ -72,6 +176,7 @@ export function resolveDataTableColumnClips({
72
176
  columnStarts,
73
177
  frozenFirstColumn,
74
178
  horizontalPadding,
179
+ rightReserve = 0,
75
180
  scrollLeft,
76
181
  viewportWidth,
77
182
  widths,
@@ -81,13 +186,15 @@ export function resolveDataTableColumnClips({
81
186
  columnStarts: readonly number[];
82
187
  frozenFirstColumn: boolean;
83
188
  horizontalPadding: number;
189
+ /** Cells at the viewport's right edge that show no column. */
190
+ rightReserve?: number;
84
191
  scrollLeft: number;
85
192
  viewportWidth: number;
86
193
  /** Each column's drawn width. */
87
194
  widths: readonly number[];
88
195
  }): (DataTableColumnClip | null)[] | null {
89
196
  if (viewportWidth <= 0 || widths.length === 0) return null;
90
- const right = scrollLeft + viewportWidth;
197
+ const right = scrollLeft + viewportWidth - Math.max(0, rightReserve);
91
198
  const left = frozenFirstColumn ? scrollLeft + horizontalPadding + (widths[0] ?? 0) + columnGap : scrollLeft;
92
199
  let cut = false;
93
200
  const clips = widths.map((width, index): DataTableColumnClip | null => {
@@ -178,7 +178,7 @@ export interface DataTableProps<
178
178
  */
179
179
  exportCsv?: () => string;
180
180
  /**
181
- * A rendered-view report (`gloomberb fn`) reads every row, not only those
181
+ * A rendered-view report (`gloom fn`) reads every row, not only those
182
182
  * the viewport shows. For a bounded table a reader needs whole, such as an
183
183
  * option chain's strike window; leave it off for long or paged lists.
184
184
  */
@@ -5,6 +5,7 @@ import { blendForContrast, higherContrast } from "../../theme/color-utils";
5
5
  import { useThemeColors } from "../../theme/theme-context";
6
6
  import { Box, Text, TextAttributes, useUiCapabilities } from "../../ui";
7
7
  import { truncateToDisplayWidth } from "../../utils/format";
8
+ import { CountryFlagLead } from "./country-flag";
8
9
  import { usePaneLinkMenuEntry } from "./external-link";
9
10
  import { titleCase } from "./header-case";
10
11
  import { statToneColor, type StatTone } from "./stat-grid";
@@ -69,6 +70,8 @@ export interface KeyValueRowProps {
69
70
  * `PaneLinkMenu` the pane menu lists it as `link.label`, so the keyboard reaches what a click opens.
70
71
  */
71
72
  link?: { label: string; onOpen: () => void };
73
+ /** The country the value names (a code or a name): the desktop and the web lead the value with its flag. */
74
+ country?: string | null;
72
75
  }
73
76
 
74
77
  /**
@@ -120,7 +123,7 @@ export function KeyValueRow(props: KeyValueRowProps) {
120
123
  * width in characters, the value and detail taking the rest of the row and
121
124
  * clipped in CSS where they run out of it.
122
125
  */
123
- function NativeKeyValueRow({ label, value, detail, tone, color, width, labelWidth, emphasis = true, align = "left", link }: KeyValueRowProps) {
126
+ function NativeKeyValueRow({ label, value, detail, tone, color, width, labelWidth, emphasis = true, align = "left", link, country }: KeyValueRowProps) {
124
127
  const colors = useThemeColors();
125
128
  usePaneLinkMenuEntry(link ? `key-value:${label}:${value}` : null, link?.label ?? "", () => link?.onOpen());
126
129
  const target = link ? {
@@ -136,6 +139,7 @@ function NativeKeyValueRow({ label, value, detail, tone, color, width, labelWidt
136
139
  <Box width={width === undefined ? undefined : "100%"} flexDirection="row" overflow="hidden" data-gloom-ui="key-value-row" {...target}>
137
140
  {/* At least the label width, in characters; a longer label keeps every character and moves its value along. */}
138
141
  <Text fg={colors.textDim} style={{ ...NATIVE_CLIP_STYLE, flex: "0 0 auto", minWidth: `${labelChars}ch`, paddingRight: "1ch", boxSizing: "border-box" }}>{t(label)}</Text>
142
+ {country ? <CountryFlagLead value={country} /> : null}
139
143
  <Text
140
144
  fg={color ?? statToneColor(tone, colors) ?? colors.text}
141
145
  attributes={emphasis ? TextAttributes.BOLD : undefined}
@@ -36,8 +36,10 @@ export { FieldGrid, GridFieldView, fieldGridColumns, fieldGridRows } from "./fie
36
36
  export type { FieldGridProps, GridField } from "./field-grid";
37
37
  export { StatGrid, statGridColumns, statGridRows } from "./stat-grid";
38
38
  export { ColumnGrid, ColumnGridPair } from "./column-grid";
39
- export type { ColumnGridCell, ColumnGridColumn, ColumnGridPairProps, ColumnGridProps } from "./column-grid";
39
+ export type { ColumnGridCell, ColumnGridColumn, ColumnGridLink, ColumnGridPairProps, ColumnGridProps } from "./column-grid";
40
40
  export type { StatGridProps, StatItem } from "./stat-grid";
41
+ export { COUNTRY_FLAG_CELLS, CountryFlag, CountryFlagLead, withCountryFlag, withFlagRoom } from "./country-flag";
42
+ export type { CountryFlagProps } from "./country-flag";
41
43
  export { RatioBar } from "./ratio-bar";
42
44
  export type { RatioBarProps } from "./ratio-bar";
43
45
  export { RangeTrack } from "./range-track";
@@ -28,8 +28,17 @@ export interface LogoMarkProps {
28
28
  /** What the logo stands for, such as a broker. Only its initial is drawn; the label beside it names it. */
29
29
  name: string;
30
30
  size?: LogoMarkSize;
31
+ /**
32
+ * Draws the logo on a white plate. Company and coin logos are made for a
33
+ * light page: a black mark on a clear field (XRP's) would vanish on a dark
34
+ * theme, while a logo that fills its square covers the plate.
35
+ */
36
+ plate?: boolean;
31
37
  }
32
38
 
39
+ /** The page logos are drawn for, in every theme. */
40
+ const LOGO_PLATE = "#ffffff";
41
+
33
42
  function initialOf(name: string): string {
34
43
  const letter = [...name.trim()].find((character) => /[\p{L}\p{N}]/u.test(character));
35
44
  return letter ? letter.toLocaleUpperCase() : "?";
@@ -40,7 +49,7 @@ function initialOf(name: string): string {
40
49
  * the desktop and the web. Decoration: hidden from assistive technology, so
41
50
  * the label beside it stays the name. The terminal draws nothing.
42
51
  */
43
- export function LogoMark({ src, name, size = "row" }: LogoMarkProps) {
52
+ export function LogoMark({ src, name, size = "row", plate = false }: LogoMarkProps) {
44
53
  const desktop = useUiCapabilities().nativePaneChrome === true;
45
54
  const colors = useThemeColors();
46
55
  if (!desktop) return null;
@@ -52,7 +61,7 @@ export function LogoMark({ src, name, size = "row" }: LogoMarkProps) {
52
61
  objectFit="cover"
53
62
  aria-hidden="true"
54
63
  data-gloom-role="logo-mark"
55
- style={{ width: tile.side, height: tile.side, flexShrink: 0, borderRadius: tile.radius }}
64
+ style={{ width: tile.side, height: tile.side, flexShrink: 0, borderRadius: tile.radius, ...(plate ? { background: LOGO_PLATE } : {}) }}
56
65
  >
57
66
  <Box width="100%" height="100%" alignItems="center" justifyContent="center" backgroundColor={colors.border}>
58
67
  <Text fg={colors.textBright} attributes={TextAttributes.BOLD} style={LETTER_STYLE[size]}>
@@ -144,7 +144,7 @@ export interface QueryBarProps {
144
144
  leading?: ReactNode;
145
145
  /**
146
146
  * The date the data is as of (`as of 2026-10-09`), shown where `meta` is
147
- * when there is none. A `gloomberb shot` whose status line dates the data
147
+ * when there is none. A `gloom shot` whose status line dates the data
148
148
  * leaves it out, so the date is said once.
149
149
  */
150
150
  asOf?: string;
@@ -0,0 +1,79 @@
1
+ import { useCallback, useEffect, useState } from "react";
2
+
3
+ /**
4
+ * What the last action on one row of a list came to, kept for that row
5
+ * (docs/pane-conventions.md, "Row messages"): the row's status cell shows
6
+ * its short state, its detail the full reason. The footer and toasts stay
7
+ * out of it.
8
+ *
9
+ * A note stands until the caller replaces or clears it (the next action on
10
+ * the row), or, given `signature`, until the row's own status moves past what
11
+ * it was when the note first showed: a later state is newer news than the
12
+ * note. A note on a row that is not listed waits for it; whether a note
13
+ * belongs in a toast instead (its row has left the list) is the caller's call.
14
+ */
15
+ export interface RowNotes<Row, Note> {
16
+ /** The row's note while it stands, else null. */
17
+ noteFor(row: Row): Note | null;
18
+ /** Sets or clears one row's note, by the row's key. */
19
+ setNote(key: string, note: Note | null): void;
20
+ /** Clears every note: the list now shows other rows (another account, a reload). */
21
+ clearNotes(): void;
22
+ }
23
+
24
+ interface Kept<Note> {
25
+ note: Note;
26
+ /** The row's signature when the note first showed it. */
27
+ baseline?: string;
28
+ }
29
+
30
+ const NO_NOTES: ReadonlyMap<string, never> = new Map<string, never>();
31
+
32
+ export function useRowNotes<Row, Note>(rows: readonly Row[], options: {
33
+ key: (row: Row) => string;
34
+ /**
35
+ * The parts of a row a real change moves (its state, its message), never a
36
+ * timestamp a poll restamps on every read. Without it a note stands until
37
+ * it is replaced or cleared.
38
+ */
39
+ signature?: (row: Row) => string;
40
+ }): RowNotes<Row, Note> {
41
+ const { key, signature } = options;
42
+ const [notes, setNotes] = useState<ReadonlyMap<string, Kept<Note>>>(NO_NOTES);
43
+
44
+ const setNote = useCallback((rowKey: string, note: Note | null) => {
45
+ setNotes((current) => {
46
+ if (!note && !current.has(rowKey)) return current;
47
+ const next = new Map(current);
48
+ if (note) next.set(rowKey, { note });
49
+ else next.delete(rowKey);
50
+ return next;
51
+ });
52
+ }, []);
53
+ const clearNotes = useCallback(() => setNotes((current) => (current.size ? NO_NOTES : current)), []);
54
+
55
+ // A note takes its row as the list shows it once the note is up, and goes
56
+ // when that row moves on.
57
+ useEffect(() => {
58
+ if (!signature || notes.size === 0) return;
59
+ setNotes((current) => {
60
+ let next: Map<string, Kept<Note>> | null = null;
61
+ for (const [rowKey, kept] of current) {
62
+ const row = rows.find((entry) => key(entry) === rowKey);
63
+ if (!row) continue;
64
+ const now = signature(row);
65
+ if (kept.baseline === undefined) (next ??= new Map(current)).set(rowKey, { ...kept, baseline: now });
66
+ else if (kept.baseline !== now) (next ??= new Map(current)).delete(rowKey);
67
+ }
68
+ return next ?? current;
69
+ });
70
+ }, [key, notes, rows, signature]);
71
+
72
+ const noteFor = useCallback((row: Row): Note | null => {
73
+ const kept = notes.get(key(row));
74
+ if (!kept) return null;
75
+ return !signature || kept.baseline === undefined || kept.baseline === signature(row) ? kept.note : null;
76
+ }, [key, notes, signature]);
77
+
78
+ return { noteFor, setNote, clearNotes };
79
+ }
@@ -28,6 +28,13 @@ export interface StatItem {
28
28
  label: string;
29
29
  value: string;
30
30
  detail?: string;
31
+ /**
32
+ * Shorter forms of `detail`, longest first (an empty one shows none). The
33
+ * grid sizes its columns by the shortest, so a detail that grows with the
34
+ * data (a stamp outside regular hours) never takes a column from the band,
35
+ * and shows the longest form that fits the cell.
36
+ */
37
+ detailVariants?: readonly string[];
31
38
  tone?: StatTone;
32
39
  /** A domain colour (a price change, a series). Wins over `tone`. */
33
40
  color?: string;
@@ -55,9 +62,22 @@ function labelChars(items: StatItem[]): number {
55
62
  return Math.min(MAX_LABEL_CHARS, Math.max(4, ...items.map((item) => displayWidth(t(item.label)))));
56
63
  }
57
64
 
65
+ /** The form of the detail the columns are sized by: the shortest. */
66
+ function sizingDetail(item: StatItem): string | undefined {
67
+ return item.detailVariants?.length ? item.detailVariants[item.detailVariants.length - 1] : item.detail;
68
+ }
69
+
70
+ /** The longest form of a cell's detail that fits `room` cells, else its shortest. */
71
+ function fittingStatDetail(item: Pick<StatItem, "detail" | "detailVariants">, room: number): string | undefined {
72
+ if (!item.detail || !item.detailVariants?.length) return item.detail;
73
+ const forms = [item.detail, ...item.detailVariants];
74
+ return forms.find((form) => displayWidth(form) <= room) ?? forms[forms.length - 1];
75
+ }
76
+
58
77
  function naturalWidth(item: StatItem, labels: number): number {
59
78
  // A split bar takes the room the cell has left and is not counted here.
60
- const detail = item.detail ? displayWidth(item.detail) + 2 : 0;
79
+ const sized = sizingDetail(item);
80
+ const detail = sized ? displayWidth(sized) + 2 : 0;
61
81
  return labels + 1 + displayWidth(item.value) + detail + CELL_GAP;
62
82
  }
63
83
 
@@ -132,9 +152,14 @@ export function StatGrid({ items, width, columns: columnsProp }: StatGridProps)
132
152
  const barRoom = valueWidth - displayWidth(value) - 1;
133
153
  const barCells = !item.split ? 0 : nativePaneChrome ? SPLIT_BAR_CELLS : barRoom >= 4 ? Math.min(SPLIT_BAR_CELLS, barRoom) : 0;
134
154
  const detailWidth = valueWidth - displayWidth(value) - (barCells ? barCells + 1 : 0) - 2;
135
- const detail = !item.detail
155
+ // The desktop cell has no gap between cells: its label column, inset and gaps take the room
156
+ // (measured short, as a cell is wider than a character, so a form that fits is never clipped).
157
+ const shownDetail = fittingStatDetail(item, nativePaneChrome
158
+ ? width + (item.wide ? 0 : CELL_GAP) - labels - displayWidth(value) - (barCells ? barCells + 1 : 0) - 4
159
+ : detailWidth);
160
+ const detail = !shownDetail
136
161
  ? ""
137
- : nativePaneChrome ? item.detail : detailWidth > 1 ? truncateToDisplayWidth(item.detail, detailWidth) : "";
162
+ : nativePaneChrome ? shownDetail : detailWidth > 1 ? truncateToDisplayWidth(shownDetail, detailWidth) : "";
138
163
  return (
139
164
  <Box
140
165
  key={item.id ?? `${rowIndex}:${index}`}
@@ -334,7 +334,9 @@ export function PaneStatusBody({
334
334
  <EmptyStateBody
335
335
  status={status}
336
336
  title={status === "error" ? errorTitle ?? (subject ? unavailableText(subject) : error!) : emptyTitle ?? t("Nothing to show yet.")}
337
- message={status === "error" ? (errorTitle || subject ? error! : undefined) : emptyMessage}
337
+ message={status === "error"
338
+ ? ((errorTitle || subject) && error && error !== (errorTitle ?? unavailableText(subject!)) ? error : undefined)
339
+ : emptyMessage}
338
340
  actions={actions}
339
341
  retry={retry}
340
342
  feedback={feedback}
@@ -26,6 +26,10 @@ export function createAppServices({ config, plugins, externalPlugins }: AppServi
26
26
  name: "News",
27
27
  provider: {
28
28
  fetchNews: async (query) => (await newsService.load(query)).articles,
29
+ fetchNewsPage: async (query) => {
30
+ const { articles, error, nextCursor } = await newsService.load(query);
31
+ return { articles, error, nextCursor };
32
+ },
29
33
  getCachedNews: (query) => newsService.getQueryState(query).articles,
30
34
  },
31
35
  }),
@@ -1,4 +1,4 @@
1
- import { getDockLeafLayouts, getDockedPaneIds } from "../../../layout/pane-manager";
1
+ import { compactFloatingZ, getDockLeafLayouts, getDockedPaneIds } from "../../../layout/pane-manager";
2
2
  import { pinFollowingPane } from "../../../layout/pane-follow";
3
3
  import {
4
4
  cloneLayout,
@@ -509,7 +509,7 @@ export function moveHistoryIndex(
509
509
  return next;
510
510
  }
511
511
 
512
- /** If paneId is a floating pane, bump its zIndex to the top. */
512
+ /** If paneId is a floating pane, bump its zIndex to the top, renumbering a stack that would climb past the shell's overlays. */
513
513
  export function bringFloatingToFront(layout: LayoutConfig, paneId: string): LayoutConfig {
514
514
  const entryIndex = layout.floating.findIndex((e) => e.instanceId === paneId);
515
515
  const entry = entryIndex >= 0 ? layout.floating[entryIndex] : undefined;
@@ -519,9 +519,9 @@ export function bringFloatingToFront(layout: LayoutConfig, paneId: string): Layo
519
519
  if ((entry.zIndex ?? 50) === maxZ && entryIndex === topEqualIndex) return layout; // already on top
520
520
  return {
521
521
  ...layout,
522
- floating: layout.floating.map((e) =>
522
+ floating: compactFloatingZ(layout.floating.map((e) =>
523
523
  e.instanceId === paneId ? { ...e, zIndex: maxZ + 1 } : e,
524
- ),
524
+ )),
525
525
  };
526
526
  }
527
527
 
@@ -1,4 +1,6 @@
1
+ import type { QuoteIntradayBar } from "../types/financials";
1
2
  import { nextResponseSequence } from "./response-sequence";
3
+ import { servedFromSavedCopy } from "./saved-copies";
2
4
 
3
5
  /** A value's age belongs to its source, not to the consumer that last read it. */
4
6
  export interface CachedValue<T> {
@@ -13,6 +15,10 @@ export interface CachedValue<T> {
13
15
  asOf?: number;
14
16
  /** How far a delayed source runs behind the market, in minutes; 0 for a real-time one. */
15
17
  delayMinutes?: number;
18
+ /** Exchange rates: the pair's bar the rate is the close of, when it is not a print. */
19
+ intradayBar?: QuoteIntradayBar;
20
+ /** Exchange rates: why a stale rate stands, as the data service states it. */
21
+ staleReason?: string;
16
22
  refreshError?: unknown;
17
23
  }
18
24
 
@@ -95,7 +101,8 @@ export class CachedQuery<T> implements CachedQueryHandle<T> {
95
101
  return accepted;
96
102
  }, (error: unknown) => {
97
103
  const fallback = this.usable(cached) ?? this.usable(this.options.read(true));
98
- const retained = fallback ? { ...fallback, refreshError: error } : null;
104
+ // A command that shows it says it is the saved copy (`servedFromSavedCopy`).
105
+ const retained = fallback ? { ...fallback, value: servedFromSavedCopy(fallback.value, fallback.fetchedAt), refreshError: error } : null;
99
106
  if (generation === this.generation) this.publish({ result: retained, loading: false, error });
100
107
  if (retained) return retained;
101
108
  throw error;
@@ -1,5 +1,6 @@
1
1
  import { logFailure } from "../../utils/log-failure";
2
- import { CHART_RESOLUTIONS, TIME_RANGES, type ChartResolution, type TimeRange } from "../../time-series/range";
2
+ import { TIME_RANGES, type ChartResolution, type TimeRange } from "../../time-series/range";
3
+ import { isChartResolution } from "../../time-series/resolution";
3
4
  import type { LayoutConfig, PaneBinding } from "../../types/config";
4
5
  import type {
5
6
  ChartPanelSpec,
@@ -19,7 +20,6 @@ import {
19
20
  import { recordOrNull } from "../../utils/guards";
20
21
 
21
22
  const CHART_RANGES = new Set<TimeRange>(TIME_RANGES);
22
- const CHART_RESOLUTION_SET = new Set<ChartResolution>(CHART_RESOLUTIONS);
23
23
  const PRICE_RENDER_MODES = new Set<SeriesStyle>(["area", "line", "candles", "ohlc", "hlc"]);
24
24
  const LEGACY_INDICATOR_IDS = new Set<LegacyChartIndicatorId>([
25
25
  "volume",
@@ -90,7 +90,7 @@ function range(value: unknown, fallback: TimeRange): TimeRange {
90
90
  }
91
91
 
92
92
  function resolution(value: unknown, fallback: ChartResolution): ChartResolution {
93
- return CHART_RESOLUTION_SET.has(value as ChartResolution) ? value as ChartResolution : fallback;
93
+ return isChartResolution(value) ? value : fallback;
94
94
  }
95
95
 
96
96
  function makeSpec(
@@ -16,7 +16,7 @@ import { isAbsolute, join } from "path";
16
16
  * On Linux a new install follows the XDG Base Directory spec instead (#1267):
17
17
  * config.json in `$XDG_CONFIG_HOME/gloomberb`, the data directory, plugins
18
18
  * and the terminal media pid file in `$XDG_DATA_HOME/gloomberb`, the plugin
19
- * cache in `$XDG_CACHE_HOME/gloomberb`. An existing `~/.gloomberb` keeps
19
+ * and native caches in `$XDG_CACHE_HOME/gloomberb`. An existing `~/.gloomberb` keeps
20
20
  * winning, so no install moves. Once an XDG config.json exists it wins over
21
21
  * a `~/.gloomberb` created later (an older version, a stray `mkdir`), so the
22
22
  * choice cannot flip and leave the data behind.
@@ -41,6 +41,11 @@ export interface GloomberbDirs {
41
41
  plugins: string;
42
42
  /** Host-owned scratch space for plugins: bundles, update state. */
43
43
  pluginCache: string;
44
+ /**
45
+ * The standalone binary's render library, copied out of the binary when the
46
+ * temp folder cannot hold or run it (see renderers/opentui/render-lib).
47
+ */
48
+ nativeCache: string;
44
49
  }
45
50
 
46
51
  function getUserHome(env: NodeJS.ProcessEnv): string {
@@ -74,6 +79,7 @@ function singleFolder(kind: "override" | "home", home: string): GloomberbDirs {
74
79
  data: home,
75
80
  plugins: join(home, "plugins"),
76
81
  pluginCache: join(home, "plugin-cache"),
82
+ nativeCache: join(home, "native-cache"),
77
83
  };
78
84
  }
79
85
 
@@ -85,12 +91,14 @@ function xdgBase(env: NodeJS.ProcessEnv, variable: string, fallback: string): st
85
91
 
86
92
  function xdgFolders(env: NodeJS.ProcessEnv): GloomberbDirs {
87
93
  const data = join(xdgBase(env, "XDG_DATA_HOME", join(".local", "share")), XDG_FOLDER);
94
+ const cache = join(xdgBase(env, "XDG_CACHE_HOME", ".cache"), XDG_FOLDER);
88
95
  return {
89
96
  kind: "xdg",
90
97
  configFile: join(xdgBase(env, "XDG_CONFIG_HOME", ".config"), XDG_FOLDER, "config.json"),
91
98
  data,
92
99
  plugins: join(data, "plugins"),
93
- pluginCache: join(xdgBase(env, "XDG_CACHE_HOME", ".cache"), XDG_FOLDER, "plugin-cache"),
100
+ pluginCache: join(cache, "plugin-cache"),
101
+ nativeCache: join(cache, "native-cache"),
94
102
  };
95
103
  }
96
104