gloomberb 0.16.4 → 0.16.6

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 (852) hide show
  1. package/README.md +14 -91
  2. package/package.json +5 -1
  3. package/src/{plugins/builtin/cloud → account}/auth-form.tsx +9 -9
  4. package/src/{plugins/builtin/cloud → account}/auth-model.ts +4 -4
  5. package/src/account/billing.ts +57 -0
  6. package/src/{plugins/builtin/cloud → account}/device-signin-dialog.tsx +18 -12
  7. package/src/{plugins/builtin/cloud → account}/device-signin.ts +2 -2
  8. package/src/{plugins/builtin/cloud → account}/email-auth-attempt.ts +2 -2
  9. package/src/account/session.ts +16 -0
  10. package/src/{plugins/builtin/cloud → account}/upgrade-dialog.tsx +16 -15
  11. package/src/{plugins/builtin/cloud → account}/upgrade-personalization.ts +7 -7
  12. package/src/{plugins/builtin/cloud → account}/upgrade-tickers.ts +6 -6
  13. package/src/{plugins/builtin/cloud → account}/verification-panel.tsx +6 -6
  14. package/src/api-client/central-bank-rates.ts +6 -1
  15. package/src/api-client/chat.ts +26 -0
  16. package/src/api-client/credit-boards.ts +2 -0
  17. package/src/api-client/data.ts +73 -3
  18. package/src/api-client/earnings.ts +6 -0
  19. package/src/api-client/europe-energy.ts +106 -0
  20. package/src/api-client/futures-curve.ts +56 -0
  21. package/src/api-client/index.ts +13 -1
  22. package/src/api-client/market-discovery.ts +13 -1
  23. package/src/api-client/normalizers.ts +32 -0
  24. package/src/api-client/paths.ts +7 -0
  25. package/src/api-client/perps.ts +8 -0
  26. package/src/api-client/request.ts +9 -2
  27. package/src/api-client/research-activity.ts +15 -10
  28. package/src/api-client/socket.ts +29 -0
  29. package/src/api-client/themes.ts +22 -1
  30. package/src/api-client/types.ts +78 -2
  31. package/src/api-client/yield-curves.ts +8 -0
  32. package/src/app/global-shortcuts.ts +50 -2
  33. package/src/app/keybindings/actions.ts +12 -1
  34. package/src/app/pane-runtime/plugin-bindings.ts +2 -2
  35. package/src/app/pane-runtime/ticker-open-runtime.ts +16 -6
  36. package/src/app/runtime/desktop-deeplink.ts +10 -5
  37. package/src/app/runtime/startup.ts +1 -1
  38. package/src/app.tsx +6 -0
  39. package/src/architecture/core-builtin-allowlist.json +8 -26
  40. package/src/ask-gloom/pane-context.ts +114 -0
  41. package/src/ask-gloom/pane-request.ts +70 -0
  42. package/src/ask-gloom/pane-text.ts +201 -0
  43. package/src/brokers/signed-in/sign-in-dialog.tsx +11 -5
  44. package/src/capabilities/chart-series.ts +19 -2
  45. package/src/capabilities/factories.ts +1 -0
  46. package/src/cli/central-bank-events.ts +23 -0
  47. package/src/cli/command-options.ts +17 -5
  48. package/src/cli/commands/crypto-hints.ts +35 -2
  49. package/src/cli/commands/fred-series.ts +146 -0
  50. package/src/cli/commands/market.ts +501 -115
  51. package/src/cli/commands/news-hints.ts +62 -0
  52. package/src/cli/commands/news-search.ts +53 -0
  53. package/src/cli/commands/options-leaps.ts +5 -2
  54. package/src/cli/commands/overview.ts +132 -26
  55. package/src/cli/commands/remote.ts +2 -1
  56. package/src/cli/commands/search.ts +317 -13
  57. package/src/cli/commands/system.ts +55 -8
  58. package/src/cli/commands/ticker.ts +155 -18
  59. package/src/cli/context.ts +45 -14
  60. package/src/cli/desktop-pane-shot.ts +76 -7
  61. package/src/cli/earnings-calendar.ts +71 -0
  62. package/src/cli/errors.ts +7 -5
  63. package/src/cli/exit-codes.ts +8 -0
  64. package/src/cli/export-source.ts +58 -0
  65. package/src/cli/freshness.ts +18 -7
  66. package/src/cli/glossary.ts +483 -0
  67. package/src/cli/help.ts +10 -0
  68. package/src/cli/helpers.ts +2 -5
  69. package/src/cli/history-rows.ts +118 -7
  70. package/src/cli/index-roots.ts +7 -0
  71. package/src/cli/index.ts +29 -9
  72. package/src/cli/known-gaps.ts +84 -0
  73. package/src/cli/listing-arg.ts +551 -97
  74. package/src/cli/not-a-ticker.ts +24 -9
  75. package/src/cli/pane-functions/access-gate.ts +13 -2
  76. package/src/cli/pane-functions/capabilities.ts +4 -3
  77. package/src/cli/pane-functions/catalog.ts +214 -40
  78. package/src/cli/pane-functions/data.ts +42 -8
  79. package/src/cli/pane-functions/discovery.ts +1 -0
  80. package/src/cli/pane-functions/dom.ts +37 -8
  81. package/src/cli/pane-functions/freshness.ts +393 -49
  82. package/src/cli/pane-functions/function-help.ts +31 -15
  83. package/src/cli/pane-functions/headless.ts +98 -30
  84. package/src/cli/pane-functions/index.ts +101 -19
  85. package/src/cli/pane-functions/market-session.ts +22 -8
  86. package/src/cli/pane-functions/options.ts +71 -22
  87. package/src/cli/pane-functions/report-notices.ts +25 -7
  88. package/src/cli/pane-functions/report.ts +15 -8
  89. package/src/cli/pane-functions/resolver.ts +74 -19
  90. package/src/cli/pane-functions/screenshot.ts +250 -27
  91. package/src/cli/perpetual-contract.ts +60 -0
  92. package/src/cli/registry.ts +3 -1
  93. package/src/cli/report-tables.ts +26 -7
  94. package/src/cli/result.ts +45 -11
  95. package/src/cli/series-search.ts +111 -0
  96. package/src/cli/staged-tickers.ts +52 -0
  97. package/src/cli/symbol-args.ts +27 -0
  98. package/src/cli/symbol-list.ts +154 -0
  99. package/src/cli/symbol-rows.ts +154 -0
  100. package/src/cli/ticker-resolution.ts +311 -27
  101. package/src/cli/types.ts +5 -0
  102. package/src/components/chart/composite/axis-overlays.tsx +14 -3
  103. package/src/components/chart/composite/composite-chart.tsx +71 -11
  104. package/src/components/chart/composite/crosshair-readout.tsx +150 -0
  105. package/src/components/chart/composite/downsample.ts +1 -1
  106. package/src/components/chart/composite/format.ts +29 -0
  107. package/src/components/chart/composite/interactions.ts +9 -2
  108. package/src/components/chart/composite/legend.tsx +100 -33
  109. package/src/components/chart/composite/panel-bitmap.ts +70 -35
  110. package/src/components/chart/composite/panel-labels.ts +18 -17
  111. package/src/components/chart/composite/panel-series.ts +1 -0
  112. package/src/components/chart/composite/panel-surface.tsx +46 -21
  113. package/src/components/chart/composite/price-axis-labels.tsx +3 -1
  114. package/src/components/chart/composite/rasterizer.ts +50 -8
  115. package/src/components/chart/composite/scene.ts +2 -1
  116. package/src/components/chart/composite/time-scale.ts +26 -9
  117. package/src/components/chart/composite/types.ts +18 -0
  118. package/src/components/chart/composite/use-composite-viewport.ts +30 -2
  119. package/src/components/chart/native/raster/crosshair.ts +8 -3
  120. package/src/components/chart/native/raster/primitives.ts +85 -21
  121. package/src/components/chart/native/surface/manager.ts +33 -8
  122. package/src/components/chart/surface3d/chart.tsx +1 -1
  123. package/src/components/command-bar/action-runtime.ts +1 -1
  124. package/src/components/command-bar/commands/collection-list.ts +210 -0
  125. package/src/components/command-bar/commands/collection.ts +40 -1
  126. package/src/components/command-bar/commands/direct/index.ts +4 -0
  127. package/src/components/command-bar/commands/registry.ts +8 -0
  128. package/src/components/command-bar/panel/index.tsx +11 -3
  129. package/src/components/command-bar/panel/runtime.ts +3 -0
  130. package/src/components/command-bar/panel/types.ts +2 -0
  131. package/src/components/command-bar/routes/root/plugin-install.ts +4 -4
  132. package/src/components/command-bar/routes/root/provider-search.ts +4 -3
  133. package/src/components/command-bar/routes/ticker-search/results.ts +12 -11
  134. package/src/components/command-bar/routes/ticker-search/route.ts +4 -3
  135. package/src/components/command-bar/routing/actions.ts +1 -1
  136. package/src/components/command-bar/workflow/tickers.ts +42 -17
  137. package/src/components/layout/detached-pane-shell.tsx +68 -39
  138. package/src/components/layout/floating-pane.tsx +10 -1
  139. package/src/components/layout/header.tsx +25 -5
  140. package/src/components/layout/missing-pane.tsx +3 -3
  141. package/src/components/layout/pane/capture-stamp.ts +41 -0
  142. package/src/components/layout/pane/capture-status.ts +12 -0
  143. package/src/components/layout/pane/content.tsx +7 -13
  144. package/src/components/layout/pane/footer/index.tsx +6 -2
  145. package/src/components/layout/pane/footer/keyboard.ts +3 -0
  146. package/src/components/layout/pane/footer/model.ts +41 -1
  147. package/src/components/layout/pane/header.tsx +50 -1
  148. package/src/components/layout/pane/index.tsx +21 -3
  149. package/src/components/layout/pane/sidebar.tsx +88 -21
  150. package/src/components/layout/shell/active-drag.ts +21 -5
  151. package/src/components/layout/shell/cursor-occlusion.ts +2 -1
  152. package/src/components/layout/shell/drag/index.ts +39 -9
  153. package/src/components/layout/shell/drag/live.ts +61 -51
  154. package/src/components/layout/shell/drag/runtime.ts +54 -12
  155. package/src/components/layout/shell/index.tsx +84 -65
  156. package/src/components/layout/shell/menu.ts +14 -1
  157. package/src/components/layout/shell/native/pointer-runtime.ts +3 -1
  158. package/src/components/layout/shell/pane/actions.ts +32 -10
  159. package/src/components/layout/shell/pane/ask.ts +131 -0
  160. package/src/components/layout/shell/pane/capture.ts +162 -0
  161. package/src/components/layout/shell/pane/layers.tsx +218 -50
  162. package/src/components/layout/shell/pane/management-shortcuts.ts +46 -1
  163. package/src/components/layout/shell/shortcuts.ts +21 -4
  164. package/src/components/layout/shell/terminal-pointer-runtime.ts +24 -0
  165. package/src/components/markdown-text.tsx +62 -20
  166. package/src/components/metric-treemap/heat-surface.tsx +8 -1
  167. package/src/components/onboarding/account-step/form-panel.tsx +1 -1
  168. package/src/components/onboarding/account-step/index.tsx +1 -1
  169. package/src/components/onboarding/account-step/qr-panel.tsx +1 -1
  170. package/src/components/onboarding/account-step/signed-in-panel.tsx +1 -1
  171. package/src/components/onboarding/onboarding-keyboard.ts +1 -1
  172. package/src/components/onboarding/onboarding-wizard.tsx +2 -2
  173. package/src/components/onboarding/use-onboarding-upgrade.ts +3 -3
  174. package/src/components/onboarding/wizard-account.ts +2 -2
  175. package/src/components/pane-template-wizard.tsx +9 -1
  176. package/src/components/price-selector-dialog.tsx +11 -2
  177. package/src/components/reader/article-reader.tsx +642 -0
  178. package/src/components/reader/article-text.ts +527 -0
  179. package/src/components/sign-in-gate.tsx +3 -3
  180. package/src/components/ticker/list-table-view.tsx +43 -2
  181. package/src/components/ui/action-row.tsx +2 -1
  182. package/src/components/ui/button.tsx +7 -1
  183. package/src/components/ui/choice-dialog.tsx +6 -4
  184. package/src/components/ui/confirm-dialog.tsx +28 -18
  185. package/src/components/ui/data-table/index.tsx +18 -6
  186. package/src/components/ui/data-table/opentui/index.tsx +37 -6
  187. package/src/components/ui/data-table/types.ts +12 -0
  188. package/src/components/ui/dialog-actions.tsx +64 -0
  189. package/src/components/ui/display.tsx +17 -3
  190. package/src/components/ui/frame.tsx +35 -2
  191. package/src/components/ui/icon.tsx +6 -1
  192. package/src/components/ui/query-bar.tsx +10 -1
  193. package/src/components/ui/text-prompt-dialog.tsx +11 -9
  194. package/src/data/cached-query.ts +2 -0
  195. package/src/data/config/store/migrations.ts +7 -0
  196. package/src/data/config/store/normalize.ts +7 -2
  197. package/src/data/config/store/portfolio-as-of-column.ts +57 -0
  198. package/src/data/ticker-repository.ts +5 -0
  199. package/src/data/ticker-store.ts +15 -0
  200. package/src/docs/content.ts +215 -0
  201. package/src/docs/load.ts +139 -0
  202. package/src/docs/requests.ts +39 -0
  203. package/src/docs/snapshot.chunk.ts +8 -0
  204. package/src/docs/snapshot.json +7555 -0
  205. package/src/docs/topics.ts +216 -0
  206. package/src/i18n/es.ts +65 -5
  207. package/src/i18n/ja.ts +65 -5
  208. package/src/i18n/ko.ts +65 -5
  209. package/src/i18n/zh-cn.ts +65 -5
  210. package/src/i18n/zh-tw.ts +65 -5
  211. package/src/layout/desks.ts +1 -1
  212. package/src/layout/pane-manager/dock-tree.ts +18 -0
  213. package/src/layout/pane-manager/index.ts +1 -0
  214. package/src/layout-marketplace/gallery.tsx +1 -1
  215. package/src/market-data/coordinator/chart.ts +10 -4
  216. package/src/market-data/coordinator/index.ts +6 -3
  217. package/src/{plugins/builtin/futures/contracts.ts → market-data/futures-board.ts} +81 -28
  218. package/src/market-data/futures-contract.ts +151 -0
  219. package/src/market-data/hooks.tsx +10 -2
  220. package/src/market-data/market/format.ts +39 -21
  221. package/src/market-data/market/freshness.ts +84 -20
  222. package/src/market-data/market/session-close-note.ts +3 -2
  223. package/src/market-data/market/status.ts +19 -23
  224. package/src/market-data/published-apac-sessions.ts +23 -1
  225. package/src/market-data/quotes/contributions.ts +5 -0
  226. package/src/market-data/quotes/metadata.ts +19 -24
  227. package/src/market-data/quotes/resolution.ts +5 -0
  228. package/src/market-data/quotes/screener-live-quotes.ts +5 -4
  229. package/src/market-data/result-types.ts +2 -0
  230. package/src/notifications/app-notifier.ts +17 -1
  231. package/src/notifications/notification-log.ts +180 -0
  232. package/src/plugins/auto-update-node.ts +2 -2
  233. package/src/plugins/auto-update.ts +2 -2
  234. package/src/plugins/builtin/account-management/index.tsx +1 -0
  235. package/src/plugins/builtin/account-management/model.ts +1 -56
  236. package/src/plugins/builtin/account-management/pane.tsx +6 -4
  237. package/src/plugins/builtin/account-management/password-dialog.tsx +1 -1
  238. package/src/plugins/builtin/alerts/catalysts.ts +1 -1
  239. package/src/plugins/builtin/alerts/cli.ts +313 -47
  240. package/src/plugins/builtin/alerts/events-pane.tsx +45 -7
  241. package/src/plugins/builtin/alerts/events.ts +23 -2
  242. package/src/plugins/builtin/alerts/focus.ts +27 -0
  243. package/src/plugins/builtin/alerts/history-pane.tsx +7 -2
  244. package/src/plugins/builtin/alerts/history.ts +2 -0
  245. package/src/plugins/builtin/alerts/index.tsx +47 -11
  246. package/src/plugins/builtin/alerts/pane.tsx +27 -1
  247. package/src/plugins/builtin/alerts/research-builder.ts +8 -3
  248. package/src/plugins/builtin/alerts/research-rules.ts +18 -2
  249. package/src/plugins/builtin/alerts/scheduled-check.ts +122 -0
  250. package/src/plugins/builtin/alerts/scheduled-sources.ts +25 -0
  251. package/src/plugins/builtin/alerts/scheduled.ts +254 -0
  252. package/src/plugins/builtin/alerts/targets.ts +92 -0
  253. package/src/plugins/builtin/analytics/index.tsx +8 -3
  254. package/src/plugins/builtin/analytics/risk-headless.ts +60 -27
  255. package/src/plugins/builtin/analytics/risk-math.ts +91 -27
  256. package/src/plugins/builtin/analytics/risk-model.ts +35 -5
  257. package/src/plugins/builtin/analytics/risk-pane.tsx +15 -8
  258. package/src/plugins/builtin/attention/headless.ts +1 -1
  259. package/src/plugins/builtin/attention/index.tsx +2 -0
  260. package/src/plugins/builtin/attention/pane.tsx +3 -1
  261. package/src/plugins/builtin/attention/series.ts +26 -0
  262. package/src/plugins/builtin/awards/headless.ts +88 -18
  263. package/src/plugins/builtin/awards/index.tsx +2 -0
  264. package/src/plugins/builtin/awards/model.ts +41 -1
  265. package/src/plugins/builtin/awards/pane.tsx +22 -13
  266. package/src/plugins/builtin/awards/series.ts +29 -0
  267. package/src/plugins/builtin/backtest/headless.ts +2 -2
  268. package/src/plugins/builtin/bond-calculator/model.ts +2 -1
  269. package/src/plugins/builtin/broker-manager/index.tsx +1 -0
  270. package/src/plugins/builtin/catalysts/headless.ts +1 -1
  271. package/src/plugins/builtin/catalysts/pane.tsx +3 -1
  272. package/src/plugins/builtin/cds/client.ts +49 -12
  273. package/src/plugins/builtin/cds/headless.ts +119 -19
  274. package/src/plugins/builtin/cds/index.tsx +3 -1
  275. package/src/plugins/builtin/cds/model.ts +214 -32
  276. package/src/plugins/builtin/cds/pane.tsx +58 -14
  277. package/src/plugins/builtin/cds/series.ts +19 -0
  278. package/src/plugins/builtin/central-bank-rates/client.ts +4 -0
  279. package/src/plugins/builtin/central-bank-rates/headless.ts +46 -16
  280. package/src/plugins/builtin/central-bank-rates/index.tsx +3 -1
  281. package/src/plugins/builtin/central-bank-rates/model.ts +99 -0
  282. package/src/plugins/builtin/central-bank-rates/pane.tsx +1 -1
  283. package/src/plugins/builtin/central-bank-rates/series.ts +36 -0
  284. package/src/plugins/builtin/chart-composer/catalog-inventory.ts +193 -255
  285. package/src/plugins/builtin/chart-composer/data-catalog-pane.tsx +84 -46
  286. package/src/plugins/builtin/chart-composer/editor.tsx +5 -4
  287. package/src/plugins/builtin/chart-composer/field-series.ts +40 -0
  288. package/src/plugins/builtin/chart-composer/headless-schema.ts +1 -1
  289. package/src/plugins/builtin/chart-composer/headless.ts +70 -5
  290. package/src/plugins/builtin/chart-composer/index.tsx +15 -3
  291. package/src/plugins/builtin/chart-composer/pane.tsx +81 -38
  292. package/src/plugins/builtin/chart-composer/series-catalog.ts +58 -50
  293. package/src/plugins/builtin/chart-composer/series-expression.ts +18 -10
  294. package/src/plugins/builtin/chart-composer/use-series-catalog.ts +59 -3
  295. package/src/plugins/builtin/chart-composer/user-series.ts +84 -0
  296. package/src/plugins/builtin/chat/content/composer-runtime.ts +6 -1
  297. package/src/plugins/builtin/chat/content/composer.tsx +5 -1
  298. package/src/plugins/builtin/chat/content/footer.tsx +12 -0
  299. package/src/plugins/builtin/chat/content/index.tsx +89 -5
  300. package/src/plugins/builtin/chat/content/new-dm-dialog.tsx +10 -2
  301. package/src/plugins/builtin/chat/content/new-messages.tsx +89 -0
  302. package/src/plugins/builtin/chat/content/row-activity.ts +132 -0
  303. package/src/plugins/builtin/chat/content/scroll.ts +127 -27
  304. package/src/plugins/builtin/chat/content/shortcuts.ts +2 -2
  305. package/src/plugins/builtin/chat/content/transcript.tsx +145 -78
  306. package/src/plugins/builtin/chat/content/types.ts +1 -0
  307. package/src/plugins/builtin/chat/controller/fetch.ts +8 -2
  308. package/src/plugins/builtin/chat/controller/index.ts +123 -1
  309. package/src/plugins/builtin/chat/controller/message-loading.ts +3 -0
  310. package/src/plugins/builtin/chat/controller/messages.ts +7 -2
  311. package/src/plugins/builtin/chat/controller/realtime.ts +10 -1
  312. package/src/plugins/builtin/chat/controller/send.ts +61 -1
  313. package/src/plugins/builtin/chat/controller/state.ts +8 -0
  314. package/src/plugins/builtin/chat/ghost-user.ts +20 -0
  315. package/src/plugins/builtin/chat/index.tsx +23 -5
  316. package/src/plugins/builtin/chat/layout.ts +78 -5
  317. package/src/plugins/builtin/chat/message/ai-badge.tsx +18 -0
  318. package/src/plugins/builtin/chat/message/desktop.tsx +55 -6
  319. package/src/plugins/builtin/chat/message/header.tsx +16 -4
  320. package/src/plugins/builtin/chat/message/profile-popover.tsx +5 -1
  321. package/src/plugins/builtin/chat/message/reactions.tsx +210 -0
  322. package/src/plugins/builtin/chat/message/render-state.ts +18 -2
  323. package/src/plugins/builtin/chat/message/terminal.tsx +43 -4
  324. package/src/plugins/builtin/chat/message/types.ts +12 -0
  325. package/src/plugins/builtin/chat/reactions.ts +197 -0
  326. package/src/plugins/builtin/chat/share/flow.tsx +87 -0
  327. package/src/plugins/builtin/chat/share/targets.ts +27 -0
  328. package/src/plugins/builtin/chat/status-widget.tsx +6 -3
  329. package/src/plugins/builtin/chat/unread-inbox-pane.tsx +148 -27
  330. package/src/plugins/builtin/chat/unread-inbox.ts +22 -0
  331. package/src/plugins/builtin/cloud/askg/attached-pane.tsx +69 -0
  332. package/src/plugins/builtin/cloud/askg/controller.ts +111 -19
  333. package/src/plugins/builtin/cloud/askg/executor.ts +57 -3
  334. package/src/plugins/builtin/cloud/askg/manifest.ts +32 -7
  335. package/src/plugins/builtin/cloud/askg/model.ts +27 -8
  336. package/src/plugins/builtin/cloud/askg/pane-attachment.ts +94 -0
  337. package/src/plugins/builtin/cloud/askg/pane.tsx +141 -12
  338. package/src/plugins/builtin/cloud/askg/pending-question.ts +11 -0
  339. package/src/plugins/builtin/cloud/askg/protocol.ts +10 -1
  340. package/src/plugins/builtin/cloud/askg/tool-display.ts +3 -0
  341. package/src/plugins/builtin/cloud/askg/undo.ts +2 -0
  342. package/src/plugins/builtin/cloud/auth-actions.tsx +1 -1
  343. package/src/plugins/builtin/cloud/auth-commands.ts +1 -1
  344. package/src/plugins/builtin/cloud/auth-dialog.tsx +3 -3
  345. package/src/plugins/builtin/cloud/company-picker.tsx +1 -1
  346. package/src/plugins/builtin/cloud/mcp-connect/dialog.tsx +3 -0
  347. package/src/plugins/builtin/cloud/plugin.tsx +19 -2
  348. package/src/plugins/builtin/cloud/team/model.ts +5 -0
  349. package/src/plugins/builtin/cloud/team/module.tsx +1 -0
  350. package/src/plugins/builtin/cloud/team/store.ts +8 -3
  351. package/src/plugins/builtin/cloud/terminal-relay/engine.ts +77 -9
  352. package/src/plugins/builtin/cloud/terminal-relay/manifest.ts +6 -1
  353. package/src/plugins/builtin/cloud/terminal-relay/policy.ts +9 -0
  354. package/src/plugins/builtin/cloud/terminal-relay/prompts.tsx +35 -11
  355. package/src/plugins/builtin/cloud/thesis/exposure.ts +1 -1
  356. package/src/plugins/builtin/cloud/thesis/module.tsx +1 -0
  357. package/src/plugins/builtin/cloud/thesis/prompts.tsx +2 -1
  358. package/src/plugins/builtin/company-attention/app-rank.tsx +1 -1
  359. package/src/plugins/builtin/company-attention/headless.ts +21 -7
  360. package/src/plugins/builtin/company-attention/index.tsx +2 -0
  361. package/src/plugins/builtin/company-attention/model.ts +26 -7
  362. package/src/plugins/builtin/company-attention/pane.tsx +12 -9
  363. package/src/plugins/builtin/company-attention/series.ts +52 -0
  364. package/src/plugins/builtin/company-kpis/headless.ts +97 -10
  365. package/src/plugins/builtin/company-kpis/model.ts +24 -2
  366. package/src/plugins/builtin/company-kpis/pane.tsx +17 -16
  367. package/src/plugins/builtin/composite-plugins.ts +19 -13
  368. package/src/plugins/builtin/connections/index.ts +1 -0
  369. package/src/plugins/builtin/cot/headless.ts +1 -1
  370. package/src/plugins/builtin/cot/index.tsx +3 -1
  371. package/src/plugins/builtin/cot/model.ts +40 -11
  372. package/src/plugins/builtin/cot/series.ts +27 -0
  373. package/src/plugins/builtin/cpi/headless.ts +3 -3
  374. package/src/plugins/builtin/credit-boards/cdx-pane.tsx +10 -1
  375. package/src/plugins/builtin/credit-boards/client.ts +6 -2
  376. package/src/plugins/builtin/credit-boards/headless.ts +108 -31
  377. package/src/plugins/builtin/credit-boards/index.tsx +2 -0
  378. package/src/plugins/builtin/credit-boards/model.ts +11 -1
  379. package/src/plugins/builtin/credit-boards/series.ts +66 -0
  380. package/src/plugins/builtin/credit-conditions/client.ts +12 -9
  381. package/src/plugins/builtin/credit-conditions/headless.ts +13 -2
  382. package/src/plugins/builtin/credit-conditions/index.tsx +18 -9
  383. package/src/plugins/builtin/credit-conditions/model.ts +19 -11
  384. package/src/plugins/builtin/credit-conditions/series.ts +16 -0
  385. package/src/plugins/builtin/credit-documents/headless.ts +33 -3
  386. package/src/plugins/builtin/credit-documents/pane.tsx +3 -1
  387. package/src/plugins/builtin/crypto-board/headless.ts +2 -3
  388. package/src/plugins/builtin/crypto-board/index.tsx +2 -0
  389. package/src/plugins/builtin/crypto-board/model.ts +12 -0
  390. package/src/plugins/builtin/crypto-board/pane.tsx +19 -12
  391. package/src/plugins/builtin/crypto-board/series.ts +48 -0
  392. package/src/plugins/builtin/custom-view/live-quotes.ts +2 -2
  393. package/src/plugins/builtin/debt-maturities/headless.ts +17 -11
  394. package/src/plugins/builtin/debt-maturities/index.tsx +2 -0
  395. package/src/plugins/builtin/debt-maturities/series.ts +45 -0
  396. package/src/plugins/builtin/dividend-yield/client.ts +3 -0
  397. package/src/plugins/builtin/dividend-yield/headless.ts +7 -4
  398. package/src/plugins/builtin/dividend-yield/index.tsx +3 -1
  399. package/src/plugins/builtin/dividend-yield/pane.tsx +3 -1
  400. package/src/plugins/builtin/dividend-yield/series.ts +20 -0
  401. package/src/plugins/builtin/dividend-yield/types.ts +2 -0
  402. package/src/plugins/builtin/docs/blocks.tsx +181 -0
  403. package/src/plugins/builtin/docs/index.tsx +68 -0
  404. package/src/plugins/builtin/docs/pane.tsx +426 -0
  405. package/src/plugins/builtin/docs/targets.ts +72 -0
  406. package/src/plugins/builtin/docs/use-docs.ts +60 -0
  407. package/src/plugins/builtin/doe/headless.ts +12 -8
  408. package/src/plugins/builtin/doe/index.tsx +2 -0
  409. package/src/plugins/builtin/doe/series.ts +62 -0
  410. package/src/plugins/builtin/earnings/client.ts +3 -2
  411. package/src/plugins/builtin/earnings/format.ts +1 -5
  412. package/src/plugins/builtin/earnings/headless.ts +58 -6
  413. package/src/plugins/builtin/earnings/history-model.ts +15 -1
  414. package/src/plugins/builtin/earnings/history-table.ts +13 -2
  415. package/src/plugins/builtin/earnings/history.tsx +7 -3
  416. package/src/plugins/builtin/earnings/index.tsx +9 -0
  417. package/src/plugins/builtin/earnings-calls/headless.ts +28 -2
  418. package/src/plugins/builtin/earnings-calls/index.tsx +1 -1
  419. package/src/plugins/builtin/earnings-ripple/index.tsx +2 -0
  420. package/src/plugins/builtin/econ/fred-catalog.ts +198 -0
  421. package/src/plugins/builtin/econ/fred-series-map.ts +0 -46
  422. package/src/plugins/builtin/econ/index.tsx +2 -0
  423. package/src/plugins/builtin/econ-statistics/defs.ts +5 -0
  424. package/src/plugins/builtin/econ-statistics/headless.ts +19 -4
  425. package/src/plugins/builtin/econ-statistics/stats.ts +1 -0
  426. package/src/plugins/builtin/equity-screener/headless.ts +3 -3
  427. package/src/plugins/builtin/equity-screener/pane.tsx +4 -11
  428. package/src/plugins/builtin/estimate-revisions/headless.ts +3 -3
  429. package/src/plugins/builtin/exposure/drivers.ts +13 -0
  430. package/src/plugins/builtin/exposure/headless.ts +205 -13
  431. package/src/plugins/builtin/exposure/holdings.ts +1 -1
  432. package/src/plugins/builtin/exposure/index.tsx +1 -0
  433. package/src/plugins/builtin/exposure/model.ts +23 -3
  434. package/src/plugins/builtin/exposure/pane.tsx +14 -12
  435. package/src/plugins/builtin/fear-greed/index.tsx +18 -10
  436. package/src/plugins/builtin/fear-greed/series.ts +52 -0
  437. package/src/plugins/builtin/futures/index.tsx +43 -3
  438. package/src/plugins/builtin/futures/model.ts +1 -1
  439. package/src/plugins/builtin/futures/returns.ts +1 -1
  440. package/src/plugins/builtin/futures/series.ts +13 -0
  441. package/src/plugins/builtin/futures/table.tsx +1 -1
  442. package/src/plugins/builtin/futures/use-front-returns.ts +1 -1
  443. package/src/plugins/builtin/futures-curve/client.ts +12 -3
  444. package/src/plugins/builtin/futures-curve/headless.ts +71 -10
  445. package/src/plugins/builtin/futures-curve/index.tsx +1 -1
  446. package/src/plugins/builtin/futures-curve/model.ts +66 -11
  447. package/src/plugins/builtin/futures-curve/pane.tsx +52 -18
  448. package/src/plugins/builtin/fx-matrix/client.ts +63 -0
  449. package/src/plugins/builtin/fx-matrix/export.ts +2 -1
  450. package/src/plugins/builtin/fx-matrix/headless.ts +154 -0
  451. package/src/plugins/builtin/fx-matrix/index.tsx +4 -4
  452. package/src/plugins/builtin/gpu/board.tsx +13 -10
  453. package/src/plugins/builtin/gpu/changes.tsx +4 -4
  454. package/src/plugins/builtin/gpu/client.ts +19 -1
  455. package/src/plugins/builtin/gpu/equities.tsx +14 -10
  456. package/src/plugins/builtin/gpu/headless.ts +58 -27
  457. package/src/plugins/builtin/gpu/history.tsx +3 -3
  458. package/src/plugins/builtin/gpu/index.tsx +2 -0
  459. package/src/plugins/builtin/gpu/model.ts +101 -16
  460. package/src/plugins/builtin/gpu/pane.tsx +28 -12
  461. package/src/plugins/builtin/gpu/series.ts +38 -0
  462. package/src/plugins/builtin/help/function-card.tsx +25 -6
  463. package/src/plugins/builtin/help/function-index.ts +2 -0
  464. package/src/plugins/builtin/help/index.tsx +31 -9
  465. package/src/plugins/builtin/holders/beneficial-model.ts +90 -3
  466. package/src/plugins/builtin/holders/beneficial-report.ts +57 -5
  467. package/src/plugins/builtin/holders/beneficial-view.tsx +55 -11
  468. package/src/plugins/builtin/holders/client.ts +22 -3
  469. package/src/plugins/builtin/holders/format.ts +18 -3
  470. package/src/plugins/builtin/holders/headless.ts +36 -133
  471. package/src/plugins/builtin/holders/pane.tsx +11 -4
  472. package/src/plugins/builtin/holders/report-header.ts +40 -5
  473. package/src/plugins/builtin/holders/report-rows.ts +240 -0
  474. package/src/plugins/builtin/insider/client.ts +35 -20
  475. package/src/plugins/builtin/insider/headless.ts +41 -11
  476. package/src/plugins/builtin/insider/index.tsx +26 -9
  477. package/src/plugins/builtin/insider/insider-data.ts +10 -0
  478. package/src/plugins/builtin/insider/issuer.ts +49 -0
  479. package/src/plugins/builtin/insider/model.ts +3 -0
  480. package/src/plugins/builtin/ipo-calendar/headless.ts +1 -1
  481. package/src/plugins/builtin/iv-history/client.ts +20 -6
  482. package/src/plugins/builtin/iv-history/format.ts +9 -0
  483. package/src/plugins/builtin/iv-history/headless.ts +56 -21
  484. package/src/plugins/builtin/iv-history/index.tsx +2 -0
  485. package/src/plugins/builtin/iv-history/model.ts +143 -8
  486. package/src/plugins/builtin/iv-history/screen-pane.tsx +5 -9
  487. package/src/plugins/builtin/iv-history/series.ts +29 -0
  488. package/src/plugins/builtin/jobs/headless.ts +26 -3
  489. package/src/plugins/builtin/jobs/index.tsx +3 -1
  490. package/src/plugins/builtin/jobs/series.ts +19 -0
  491. package/src/plugins/builtin/kelly-sizer/index.tsx +2 -0
  492. package/src/plugins/builtin/kelly-sizer/pane.tsx +2 -1
  493. package/src/plugins/builtin/kelly-sizer/portfolio.ts +0 -39
  494. package/src/plugins/builtin/macro-day/client.ts +44 -3
  495. package/src/plugins/builtin/macro-day/headless.ts +13 -10
  496. package/src/plugins/builtin/macro-day/model.ts +56 -10
  497. package/src/plugins/builtin/macro-day/pane.tsx +30 -20
  498. package/src/plugins/builtin/market-heatmap/headless.ts +20 -5
  499. package/src/plugins/builtin/market-heatmap/index.tsx +6 -0
  500. package/src/plugins/builtin/market-heatmap/model.ts +19 -11
  501. package/src/plugins/builtin/market-heatmap/portfolio.ts +2 -2
  502. package/src/plugins/builtin/market-movers/client.ts +7 -5
  503. package/src/plugins/builtin/market-movers/index.tsx +3 -2
  504. package/src/plugins/builtin/market-movers/model.ts +30 -0
  505. package/src/plugins/builtin/market-movers/screener.ts +31 -0
  506. package/src/plugins/builtin/market-valuation/chart-series.ts +29 -69
  507. package/src/plugins/builtin/market-valuation/index.tsx +3 -3
  508. package/src/plugins/builtin/market-valuation/indicators.ts +0 -5
  509. package/src/plugins/builtin/members/headless.ts +8 -3
  510. package/src/plugins/builtin/members/model.ts +31 -3
  511. package/src/plugins/builtin/members/pane.tsx +6 -8
  512. package/src/plugins/builtin/mna/distress/headless.ts +4 -4
  513. package/src/plugins/builtin/mna/headless.ts +18 -6
  514. package/src/plugins/builtin/money-markets/headless.ts +5 -4
  515. package/src/plugins/builtin/money-markets/index.tsx +2 -0
  516. package/src/plugins/builtin/money-markets/series.ts +41 -0
  517. package/src/plugins/builtin/news/index.tsx +0 -2
  518. package/src/plugins/builtin/news/wire/news/detail-view.tsx +53 -104
  519. package/src/plugins/builtin/news/wire/news/footer.ts +2 -25
  520. package/src/plugins/builtin/news/wire/news/preset-pane.tsx +0 -2
  521. package/src/plugins/builtin/notes/cli.ts +12 -7
  522. package/src/plugins/builtin/notes/index.tsx +1 -0
  523. package/src/plugins/builtin/options/index.tsx +3 -0
  524. package/src/plugins/builtin/options/view.tsx +1 -1
  525. package/src/plugins/builtin/options-calculator/inputs.ts +2 -1
  526. package/src/plugins/builtin/options-positioning/client.ts +7 -3
  527. package/src/plugins/builtin/options-positioning/headless.ts +4 -3
  528. package/src/plugins/builtin/options-positioning/pane.tsx +2 -2
  529. package/src/plugins/builtin/options-scenario/client.ts +2 -1
  530. package/src/plugins/builtin/options-scenario/headless.ts +1 -0
  531. package/src/plugins/builtin/options-scenario/hedge.ts +2 -1
  532. package/src/plugins/builtin/perps/client.ts +90 -16
  533. package/src/plugins/builtin/perps/equity-row.tsx +52 -17
  534. package/src/plugins/builtin/perps/freshness.ts +66 -0
  535. package/src/plugins/builtin/perps/headless.ts +47 -32
  536. package/src/plugins/builtin/perps/index.tsx +23 -4
  537. package/src/plugins/builtin/perps/list-perpetuals.ts +118 -0
  538. package/src/plugins/builtin/perps/model.ts +20 -5
  539. package/src/plugins/builtin/perps/open-market.ts +15 -0
  540. package/src/plugins/builtin/perps/pane.tsx +76 -20
  541. package/src/plugins/builtin/perps/series.ts +76 -0
  542. package/src/plugins/builtin/plugin-marketplace/index.tsx +1 -1
  543. package/src/plugins/builtin/plugin-marketplace/pane.tsx +73 -67
  544. package/src/plugins/builtin/plugin-module.ts +3 -0
  545. package/src/plugins/builtin/portfolio-list/account-metrics.ts +1 -1
  546. package/src/plugins/builtin/portfolio-list/allocation.ts +5 -4
  547. package/src/plugins/builtin/portfolio-list/cell-version.ts +8 -1
  548. package/src/plugins/builtin/portfolio-list/cli/bulk-symbols.ts +161 -0
  549. package/src/plugins/builtin/portfolio-list/cli/import-13f.ts +109 -0
  550. package/src/plugins/builtin/portfolio-list/cli/portfolio-command.ts +384 -74
  551. package/src/plugins/builtin/portfolio-list/cli/render.ts +437 -71
  552. package/src/plugins/builtin/portfolio-list/cli/shared.ts +21 -4
  553. package/src/plugins/builtin/portfolio-list/cli/watchlist-command.ts +121 -47
  554. package/src/plugins/builtin/portfolio-list/column-values.ts +104 -26
  555. package/src/plugins/builtin/portfolio-list/grid.tsx +1 -1
  556. package/src/plugins/builtin/portfolio-list/headless.ts +84 -18
  557. package/src/plugins/builtin/portfolio-list/imported-from.ts +8 -0
  558. package/src/plugins/builtin/portfolio-list/index.tsx +5 -1
  559. package/src/plugins/builtin/portfolio-list/live-valuation.ts +6 -2
  560. package/src/plugins/builtin/portfolio-list/mutations.ts +2 -9
  561. package/src/plugins/builtin/portfolio-list/pane/data.ts +5 -1
  562. package/src/plugins/builtin/portfolio-list/pane/index.tsx +52 -9
  563. package/src/plugins/builtin/portfolio-list/quick-add/index.tsx +33 -11
  564. package/src/plugins/builtin/portfolio-list/quick-add/resolution.ts +21 -1
  565. package/src/plugins/builtin/portfolio-list/settings.ts +17 -0
  566. package/src/plugins/builtin/portfolio-list/summary/index.tsx +12 -0
  567. package/src/plugins/builtin/portfolio-list/summary/totals.ts +9 -4
  568. package/src/plugins/builtin/portfolio-list/table.tsx +37 -7
  569. package/src/plugins/builtin/power/client.ts +16 -0
  570. package/src/plugins/builtin/power/evidence.ts +63 -10
  571. package/src/plugins/builtin/power/headless.ts +77 -9
  572. package/src/plugins/builtin/power/index.tsx +28 -3
  573. package/src/plugins/builtin/power/model.ts +73 -2
  574. package/src/plugins/builtin/power/pane.tsx +37 -9
  575. package/src/plugins/builtin/power/prices-client.ts +139 -0
  576. package/src/plugins/builtin/power/prices-headless.ts +137 -0
  577. package/src/plugins/builtin/power/prices-model.ts +103 -0
  578. package/src/plugins/builtin/power/prices.tsx +179 -0
  579. package/src/plugins/builtin/rate-path/headless.ts +46 -18
  580. package/src/plugins/builtin/realized-vol/headless.ts +5 -0
  581. package/src/plugins/builtin/relative-rotation/headless.ts +3 -3
  582. package/src/plugins/builtin/research/corporate-actions-pane.tsx +5 -2
  583. package/src/plugins/builtin/research/event-model.ts +68 -24
  584. package/src/plugins/builtin/research/events-headless.ts +2 -1
  585. package/src/plugins/builtin/research/headless.ts +2 -1
  586. package/src/plugins/builtin/research/index.tsx +2 -0
  587. package/src/plugins/builtin/research-search/article.ts +65 -0
  588. package/src/plugins/builtin/research-search/document-view.tsx +33 -215
  589. package/src/plugins/builtin/research-search/model.ts +0 -9
  590. package/src/plugins/builtin/research-search/pane.tsx +41 -30
  591. package/src/plugins/builtin/research-search/snippet.ts +0 -29
  592. package/src/plugins/builtin/revenue-breakdown/headless.ts +18 -6
  593. package/src/plugins/builtin/seasonality/client.ts +15 -7
  594. package/src/plugins/builtin/seasonality/headless.ts +36 -12
  595. package/src/plugins/builtin/seasonality/index.tsx +2 -2
  596. package/src/plugins/builtin/seasonality/model.ts +119 -0
  597. package/src/plugins/builtin/seasonality/pane.tsx +108 -37
  598. package/src/plugins/builtin/sec/headless.ts +25 -3
  599. package/src/plugins/builtin/sec/index.tsx +2 -1
  600. package/src/plugins/builtin/series-inventory.ts +93 -0
  601. package/src/plugins/builtin/shared/cloud-denied.ts +15 -0
  602. package/src/plugins/builtin/shared/cloud-upgrade.ts +1 -1
  603. package/src/plugins/builtin/shared/command-tab.ts +30 -12
  604. package/src/plugins/builtin/shared/earnings-report.ts +55 -0
  605. package/src/plugins/builtin/shared/fred-points.ts +20 -0
  606. package/src/plugins/builtin/shared/free-preview.ts +47 -0
  607. package/src/plugins/builtin/shared/fx-rate-freshness.ts +101 -0
  608. package/src/plugins/builtin/shared/open-description.ts +29 -0
  609. package/src/plugins/builtin/shared/report-freshness.ts +12 -1
  610. package/src/plugins/builtin/shared/series-warning.ts +5 -0
  611. package/src/plugins/builtin/shared/volatility/options.ts +4 -1
  612. package/src/plugins/builtin/short-interest/headless.ts +1 -0
  613. package/src/plugins/builtin/short-interest/index.tsx +2 -0
  614. package/src/plugins/builtin/short-interest/series.ts +36 -0
  615. package/src/plugins/builtin/short-interest/watch-headless.ts +3 -2
  616. package/src/plugins/builtin/short-interest/watch-model.ts +9 -5
  617. package/src/plugins/builtin/short-volume/headless.ts +2 -1
  618. package/src/plugins/builtin/short-volume/index.tsx +2 -0
  619. package/src/plugins/builtin/short-volume/series.ts +23 -0
  620. package/src/plugins/builtin/social-mentions/headless.ts +1 -1
  621. package/src/plugins/builtin/social-mentions/index.tsx +2 -0
  622. package/src/plugins/builtin/social-mentions/series.ts +23 -0
  623. package/src/plugins/builtin/supply-chain/graph-pane.tsx +3 -2
  624. package/src/plugins/builtin/supply-chain/headless.ts +43 -11
  625. package/src/plugins/builtin/supply-chain/model.ts +13 -0
  626. package/src/plugins/builtin/supply-chain/pane.tsx +8 -6
  627. package/src/plugins/builtin/themes/headless.ts +74 -10
  628. package/src/plugins/builtin/themes/model.ts +71 -4
  629. package/src/plugins/builtin/themes/pane.tsx +22 -5
  630. package/src/plugins/builtin/thirteenf/api.ts +1 -0
  631. package/src/plugins/builtin/thirteenf/data.ts +6 -4
  632. package/src/plugins/builtin/thirteenf/headless.ts +217 -36
  633. package/src/plugins/builtin/thirteenf/model.ts +39 -1
  634. package/src/plugins/builtin/thirteenf/overlap.ts +75 -0
  635. package/src/plugins/builtin/thirteenf/pane.tsx +10 -1
  636. package/src/plugins/builtin/thirteenf/report-notes.ts +103 -1
  637. package/src/plugins/builtin/thirteenf/types.ts +2 -0
  638. package/src/plugins/builtin/ticker-detail/data-panes/returns-history.ts +114 -0
  639. package/src/plugins/builtin/ticker-detail/data-panes/returns-model.ts +57 -2
  640. package/src/plugins/builtin/ticker-detail/data-panes/returns-pane.tsx +19 -55
  641. package/src/plugins/builtin/ticker-detail/headless-schema.ts +30 -0
  642. package/src/plugins/builtin/ticker-detail/headless.ts +86 -0
  643. package/src/plugins/builtin/ticker-detail/index.tsx +26 -11
  644. package/src/plugins/builtin/ticker-detail/overview/components.tsx +1 -1
  645. package/src/plugins/builtin/ticker-detail/overview/futures-contract.ts +31 -0
  646. package/src/plugins/builtin/ticker-detail/overview/model.ts +3 -3
  647. package/src/plugins/builtin/ticker-detail/overview/pane.tsx +2 -1
  648. package/src/plugins/builtin/ticker-detail/overview-tab.tsx +49 -5
  649. package/src/plugins/builtin/ticker-detail/quote-monitor/index.tsx +13 -3
  650. package/src/plugins/builtin/time-sales/headless.ts +2 -1
  651. package/src/plugins/builtin/time-sales/index.tsx +2 -1
  652. package/src/plugins/builtin/treasury-auctions/headless.ts +16 -2
  653. package/src/plugins/builtin/treasury-auctions/index.tsx +1 -0
  654. package/src/plugins/builtin/treasury-auctions/model.ts +8 -0
  655. package/src/plugins/builtin/vol-surface/evidence.ts +7 -1
  656. package/src/plugins/builtin/vol-surface/headless.ts +51 -17
  657. package/src/plugins/builtin/vol-surface/heat-grid.tsx +113 -0
  658. package/src/plugins/builtin/vol-surface/model.ts +39 -6
  659. package/src/plugins/builtin/vol-surface/pane.tsx +14 -13
  660. package/src/plugins/builtin/vol-surface/stored.ts +63 -3
  661. package/src/plugins/builtin/vol-surface/surface.tsx +30 -2
  662. package/src/plugins/builtin/volatility/index.tsx +2 -0
  663. package/src/plugins/builtin/volatility/series.ts +84 -0
  664. package/src/plugins/builtin/world-venue-map/basemap-layer.tsx +6 -5
  665. package/src/plugins/builtin/world-venue-map/basemap.ts +6 -3
  666. package/src/plugins/builtin/world-venue-map/geo-draw.tsx +2 -1
  667. package/src/plugins/builtin/world-venue-map/geo-series.ts +26 -1
  668. package/src/plugins/builtin/world-venue-map/geo-svg.tsx +6 -6
  669. package/src/plugins/builtin/world-venue-map/headless.ts +4 -1
  670. package/src/plugins/builtin/world-venue-map/index.ts +2 -1
  671. package/src/plugins/builtin/world-venue-map/layered-pane.tsx +24 -13
  672. package/src/plugins/builtin/world-venue-map/layers.ts +29 -0
  673. package/src/plugins/builtin/world-venue-map/map.tsx +144 -13
  674. package/src/plugins/builtin/world-venue-map/model.ts +56 -19
  675. package/src/plugins/builtin/world-venue-map/pane.tsx +5 -2
  676. package/src/plugins/builtin/yield-curve/chart.ts +2 -2
  677. package/src/plugins/builtin/yield-curve/curves.ts +21 -8
  678. package/src/plugins/builtin/yield-curve/headless.ts +71 -18
  679. package/src/plugins/builtin/yield-curve/index.tsx +4 -2
  680. package/src/plugins/builtin/yield-curve/series.ts +86 -0
  681. package/src/plugins/catalog-browser.ts +2 -1
  682. package/src/plugins/installer.ts +2 -2
  683. package/src/plugins/loader.ts +15 -0
  684. package/src/plugins/manager-node.ts +1 -1
  685. package/src/plugins/{builtin/plugin-marketplace → marketplace}/feed.ts +2 -2
  686. package/src/plugins/{builtin/plugin-marketplace → marketplace}/model.ts +6 -6
  687. package/src/plugins/{builtin/plugin-marketplace → marketplace}/store.ts +1 -1
  688. package/src/plugins/registry/host-actions.ts +11 -0
  689. package/src/plugins/registry/index.ts +89 -4
  690. package/src/portfolio/collection-name.ts +31 -0
  691. package/src/{plugins/builtin/portfolio-list → portfolio}/position-metrics.ts +6 -6
  692. package/src/portfolio/position-value.ts +40 -0
  693. package/src/portfolio/valuation-basis.ts +79 -0
  694. package/src/public/__snapshots__/public-api.test.ts.snap +7 -0
  695. package/src/public/time-series.ts +17 -0
  696. package/src/react/auto-refresh.ts +13 -3
  697. package/src/react/input.ts +33 -1
  698. package/src/react/key-repeat.ts +86 -0
  699. package/src/remote/app-host.tsx +20 -4
  700. package/src/remote/confirm-change.tsx +85 -0
  701. package/src/remote/controller-utils.ts +8 -1
  702. package/src/remote/controller.ts +144 -7
  703. package/src/remote/pane-screenshot.ts +47 -0
  704. package/src/remote/schema.ts +65 -2
  705. package/src/remote/types.ts +30 -0
  706. package/src/remote/watchlist.ts +306 -0
  707. package/src/renderers/browser/main.tsx +4 -3
  708. package/src/renderers/browser/research-entry.ts +4 -2
  709. package/src/renderers/cloudflare/worker.ts +1 -1
  710. package/src/renderers/dom/data-table/frozen-column.ts +3 -1
  711. package/src/renderers/dom/data-table/index.tsx +33 -6
  712. package/src/renderers/dom/data-table/row.tsx +30 -1
  713. package/src/renderers/dom/desktop/control-styles.ts +63 -1
  714. package/src/renderers/dom/desktop/controls.tsx +30 -23
  715. package/src/renderers/dom/desktop/dialog-actions.tsx +170 -0
  716. package/src/renderers/dom/desktop/icons.tsx +16 -0
  717. package/src/renderers/dom/dom-ui-host.tsx +3 -0
  718. package/src/renderers/dom/host/block-glyph-canvas.tsx +6 -3
  719. package/src/renderers/dom/host/box.tsx +8 -0
  720. package/src/renderers/dom/host/chart-surface.tsx +33 -2
  721. package/src/renderers/dom/host/live-frame.ts +6 -2
  722. package/src/renderers/dom/host/overflow-fade.ts +14 -1
  723. package/src/renderers/dom/host/scroll-box.tsx +32 -0
  724. package/src/renderers/dom/host/size-observer.ts +41 -0
  725. package/src/renderers/dom/host/sticky-scroll.ts +128 -0
  726. package/src/renderers/dom/host/style.ts +1 -1
  727. package/src/renderers/dom/host/surface-3d.tsx +19 -7
  728. package/src/renderers/dom/host/surface-fit.ts +406 -0
  729. package/src/renderers/dom/host/text.tsx +1 -1
  730. package/src/renderers/dom/input-host.tsx +1 -0
  731. package/src/renderers/dom/styles.css +102 -5
  732. package/src/renderers/electrobun/bun/application-menu/click.ts +18 -0
  733. package/src/renderers/electrobun/bun/index.ts +3 -2
  734. package/src/renderers/electrobun/shared/protocol.ts +1 -1
  735. package/src/renderers/electrobun/view/cli-pane-shot-entry.tsx +29 -2
  736. package/src/renderers/electrobun/view/cli-pane-shot-frame.tsx +63 -20
  737. package/src/renderers/electrobun/view/cli-pane-shot-health.ts +10 -26
  738. package/src/renderers/electrobun/view/main.tsx +5 -3
  739. package/src/renderers/electrobun/view/remote/asset-data-client.ts +2 -0
  740. package/src/renderers/opentui/chart-surface.tsx +1 -0
  741. package/src/renderers/opentui/frame-capture.ts +33 -0
  742. package/src/renderers/opentui/host.tsx +10 -13
  743. package/src/renderers/opentui/pane-image/glyphs-license.txt +107 -0
  744. package/src/renderers/opentui/pane-image/glyphs.json +1 -0
  745. package/src/renderers/opentui/pane-image/index.ts +107 -0
  746. package/src/renderers/opentui/pane-image/raster.ts +428 -0
  747. package/src/renderers/opentui/start.tsx +3 -3
  748. package/src/renderers/opentui/test-utils.tsx +3 -0
  749. package/src/renderers/opentui/ui-host.tsx +29 -1
  750. package/src/series/capability.ts +75 -0
  751. package/src/series/csv.ts +160 -0
  752. package/src/series/files.ts +107 -0
  753. package/src/series/registry.ts +198 -0
  754. package/src/series/resolve.ts +108 -0
  755. package/src/series/standalone.ts +48 -0
  756. package/src/series/types.ts +153 -0
  757. package/src/series/validate.ts +171 -0
  758. package/src/shares/chat.ts +34 -0
  759. package/src/shares/dialog.tsx +295 -0
  760. package/src/shares/flow.tsx +56 -0
  761. package/src/shares/live.ts +14 -22
  762. package/src/shares/pane-image.ts +152 -0
  763. package/src/shares/personal-pane.ts +64 -0
  764. package/src/shares/portable-layout.ts +4 -2
  765. package/src/shares/prepare.ts +20 -0
  766. package/src/sources/gloomberb-cloud/index.ts +109 -10
  767. package/src/sources/gloomberb-cloud/normalizers.ts +3 -0
  768. package/src/sources/gloomberb-cloud/perpetuals.ts +249 -0
  769. package/src/sources/history-result.ts +1 -0
  770. package/src/sources/history-retention.ts +11 -0
  771. package/src/sources/listing-symbols.ts +4 -1
  772. package/src/sources/listing-target.ts +4 -0
  773. package/src/sources/provider-router/batches.ts +4 -1
  774. package/src/sources/provider-router/cache.ts +4 -2
  775. package/src/sources/provider-router/cached-routes.ts +1 -1
  776. package/src/sources/provider-router/financial-routes.ts +1 -0
  777. package/src/sources/provider-router/financials.ts +13 -0
  778. package/src/sources/provider-router/history.ts +43 -25
  779. package/src/sources/provider-router/index.ts +14 -0
  780. package/src/sources/provider-router/search.ts +1 -0
  781. package/src/state/hooks/inline-tickers.ts +49 -11
  782. package/src/sync/core-contributors.ts +1 -0
  783. package/src/test-support/shell-pane-keys.tsx +1 -0
  784. package/src/theme/theme-context.tsx +15 -1
  785. package/src/tickers/company-name.ts +75 -0
  786. package/src/tickers/instrument-kind.ts +34 -1
  787. package/src/tickers/listing-name.ts +34 -0
  788. package/src/tickers/listing-venues.ts +132 -0
  789. package/src/tickers/open-target.ts +13 -4
  790. package/src/tickers/perpetual-listing.ts +151 -0
  791. package/src/tickers/prediction-listing.ts +26 -0
  792. package/src/tickers/search/index.ts +72 -11
  793. package/src/tickers/search/ranking.ts +98 -20
  794. package/src/tickers/search/types.ts +7 -1
  795. package/src/tickers/ticker-changes.ts +213 -0
  796. package/src/tickers/us-listing.ts +34 -0
  797. package/src/time-series/economic.ts +2 -6
  798. package/src/time-series/hooks.ts +9 -0
  799. package/src/time-series/ice-credit.ts +39 -0
  800. package/src/time-series/resolve.ts +211 -29
  801. package/src/time-series/studies.ts +1 -0
  802. package/src/time-series/types.ts +12 -2
  803. package/src/time-series/use-chart-resolution.ts +32 -0
  804. package/src/types/config.ts +10 -2
  805. package/src/types/data-provider.ts +11 -0
  806. package/src/types/financials.ts +62 -1
  807. package/src/types/headless.ts +113 -0
  808. package/src/types/instrument.ts +4 -0
  809. package/src/types/plugin.ts +52 -2
  810. package/src/types/price-history.ts +7 -0
  811. package/src/types/ticker-changes.ts +26 -0
  812. package/src/types/ticker.ts +14 -0
  813. package/src/ui/context-menu.tsx +13 -1
  814. package/src/ui/host.tsx +57 -3
  815. package/src/ui/live-resize.ts +91 -0
  816. package/src/ui/live-stretch.ts +153 -0
  817. package/src/ui/measured-cells.ts +58 -0
  818. package/src/ui/sticky-scroll.ts +7 -0
  819. package/src/utils/basis-points.ts +17 -0
  820. package/src/utils/central-banks.ts +76 -0
  821. package/src/utils/cli-output.ts +131 -15
  822. package/src/utils/concurrency.ts +25 -0
  823. package/src/utils/crypto-pair.ts +20 -0
  824. package/src/utils/currency-pair.ts +19 -0
  825. package/src/utils/currency-units.ts +11 -0
  826. package/src/utils/datetime-format.ts +27 -6
  827. package/src/utils/decimal-comma.ts +19 -0
  828. package/src/utils/dom-screenshot-css.ts +265 -0
  829. package/src/utils/dom-screenshot-rasters.ts +276 -0
  830. package/src/utils/dom-screenshot.ts +439 -52
  831. package/src/utils/double-escape-close.ts +15 -1
  832. package/src/utils/exchange-rate-snapshot.ts +6 -2
  833. package/src/utils/exchanges.ts +143 -1
  834. package/src/utils/format.ts +35 -5
  835. package/src/utils/forward-dividend.ts +14 -0
  836. package/src/utils/fundamentals.ts +66 -0
  837. package/src/utils/futures-generic.ts +6 -12
  838. package/src/utils/fx-market-hours.ts +15 -5
  839. package/src/utils/fx-status.ts +6 -1
  840. package/src/utils/inline-content-tokenizer.ts +22 -3
  841. package/src/utils/market-capitalization.ts +8 -0
  842. package/src/utils/one-shot.ts +73 -0
  843. package/src/utils/options.ts +37 -8
  844. package/src/utils/price-history.ts +99 -42
  845. package/src/utils/sec-eps-basis.ts +24 -11
  846. package/src/utils/sec.ts +61 -7
  847. package/src/utils/utc-time.ts +63 -4
  848. package/src/plugins/builtin/fx-matrix/freshness.ts +0 -65
  849. /package/src/plugins/{builtin/plugin-marketplace → marketplace}/activation.ts +0 -0
  850. /package/src/plugins/{builtin/plugin-marketplace → marketplace}/ids.ts +0 -0
  851. /package/src/plugins/{builtin/plugin-marketplace → marketplace}/packs.ts +0 -0
  852. /package/src/{plugins/builtin/cloud → tickers}/starter-symbols.ts +0 -0
@@ -1,17 +1,29 @@
1
+ import type { EarningsTiming } from "../../../api-client/earnings";
1
2
  import type { PricePoint } from "../../../types/financials";
2
3
  import { zonedDateTimeParts } from "../../../utils/zoned-date-time";
3
- import { MACRO_EVENT_KINDS, type MacroEventKind, type MacroRelease } from "./releases";
4
+ import { MACRO_EVENT_KINDS, MACRO_EVENT_LABELS, type MacroEventKind, type MacroRelease } from "./releases";
4
5
 
5
6
  const DAY_MS = 86_400_000;
6
7
  /** Longest calendar gap between two closes that is still one session apart: Thursday to Monday over a Friday holiday. */
7
8
  const MAX_SESSION_GAP_DAYS = 4;
8
9
 
10
+ /** One of the ticker's own earnings reports, reduced to what dates its reaction. */
11
+ export interface MacroDayEarningsReport {
12
+ /** Report date, New York. */
13
+ date: string;
14
+ timing: EarningsTiming | null;
15
+ /** The session the earnings history measures the report's move on, once the report is priced. */
16
+ reactionSession?: string | null;
17
+ }
18
+
9
19
  export interface MacroDayEvent {
10
20
  kind: MacroEventKind;
11
21
  /** Release day, New York date. */
12
22
  date: string;
13
23
  /** The session whose close carries the reaction: the release day, or the next session when the market was shut. */
14
24
  session: string;
25
+ /** The session is also the reaction session of the ticker's own earnings report: the move is the report's, not the release's. */
26
+ earnings: boolean;
15
27
  /** Close before the release to the session's close. */
16
28
  move: number;
17
29
  /** |move| over the normal day's average |move|. */
@@ -32,15 +44,22 @@ export interface MacroDayModel {
32
44
  symbol: string;
33
45
  /** Newest first. */
34
46
  events: MacroDayEvent[];
47
+ /** Without the earnings days. */
35
48
  byKind: Record<MacroEventKind, MacroDayStats>;
36
- /** Every release day of the three kinds together; a day with two releases counts once. */
49
+ /** Every release day of the three kinds together, without the earnings days; a day with two releases counts once. */
37
50
  allEvents: MacroDayStats;
38
- /** Sessions with no release of the three kinds. */
51
+ /** Release days that are the ticker's earnings reaction, which no other figure counts; a day with two releases counts once. */
52
+ earnings: MacroDayStats;
53
+ /** Sessions with no release of the three kinds, and none of the earnings days among them. */
39
54
  normal: MacroDayStats;
40
55
  start: string | null;
41
56
  asOf: string | null;
42
57
  }
43
58
 
59
+ /** The release's name, with the earnings marker on a day that is the ticker's own report reaction. */
60
+ export const macroDayEventLabel = (event: Pick<MacroDayEvent, "kind" | "earnings">) =>
61
+ event.earnings ? `${MACRO_EVENT_LABELS[event.kind]} (earnings)` : MACRO_EVENT_LABELS[event.kind];
62
+
44
63
  /** Daily labels at UTC midnight name that date; any other stamp reads in New York. */
45
64
  function sessionDate(time: number): string {
46
65
  if (time % DAY_MS === 0) return new Date(time).toISOString().slice(0, 10);
@@ -59,6 +78,27 @@ function stats(moves: number[], normalAbs: number | null): MacroDayStats {
59
78
  multiple: normalAbs ? meanAbs / normalAbs : null };
60
79
  }
61
80
 
81
+ /**
82
+ * The sessions whose close carries a report's reaction, on the history's own
83
+ * calendar. A priced report names its session in the earnings history. Any
84
+ * other reads as the earnings history reads it: before the open and during
85
+ * the session react the same day, after the close the next session. A report
86
+ * with no time on record may have reacted on either, so both count.
87
+ */
88
+ function earningsReactionSessions(reports: readonly MacroDayEarningsReport[], sessions: readonly string[]): Set<string> {
89
+ const reacted = new Set<string>();
90
+ for (const report of reports) {
91
+ if (report.reactionSession) { reacted.add(report.reactionSession); continue; }
92
+ const sameDay = report.timing === "bmo" || report.timing === "dmh";
93
+ const afterClose = report.timing === "amc";
94
+ const same = sessions.find((date) => date >= report.date);
95
+ const next = sessions.find((date) => date > report.date);
96
+ if (!afterClose && same) reacted.add(same);
97
+ if (!sameDay && next) reacted.add(next);
98
+ }
99
+ return reacted;
100
+ }
101
+
62
102
  /**
63
103
  * Close to close on the release day: 8:30 ET releases land before the open
64
104
  * and 14:00 FOMC statements before the close, so the release day's close
@@ -66,7 +106,9 @@ function stats(moves: number[], normalAbs: number | null): MacroDayStats {
66
106
  * is read on the next session, from the close before the release. A release
67
107
  * whose close-to-close would span a gap in the history is left out rather
68
108
  * than read across it. A lone missing bar on the release day itself cannot
69
- * be told from a holiday and is read on the next session.
109
+ * be told from a holiday and is read on the next session. A release whose
110
+ * session is also the reaction to the ticker's own earnings is kept, marked,
111
+ * and counted in neither the release figures nor the normal days.
70
112
  */
71
113
  export function projectMacroDays(history: readonly PricePoint[], options: {
72
114
  symbol: string;
@@ -74,6 +116,8 @@ export function projectMacroDays(history: readonly PricePoint[], options: {
74
116
  releases: readonly MacroRelease[];
75
117
  /** The release list's last covered day. */
76
118
  coveredThrough: string;
119
+ /** The ticker's own earnings reports; none when they could not be read. */
120
+ earnings?: readonly MacroDayEarningsReport[];
77
121
  }): MacroDayModel {
78
122
  const { coveredThrough } = options;
79
123
  const byDate = new Map<string, number>();
@@ -86,7 +130,7 @@ export function projectMacroDays(history: readonly PricePoint[], options: {
86
130
  const last = sessions.at(-1) ?? null;
87
131
  const empty = (): MacroDayStats => stats([], null);
88
132
  if (!last) return { symbol: options.symbol, events: [], byKind: { cpi: empty(), jobs: empty(), fomc: empty() },
89
- allEvents: empty(), normal: empty(), start: null, asOf: null };
133
+ allEvents: empty(), earnings: empty(), normal: empty(), start: null, asOf: null };
90
134
 
91
135
  // Sessions after the published lists end may be unlisted release days, so they are left out of both sides.
92
136
  const end = last < coveredThrough ? last : coveredThrough;
@@ -105,7 +149,7 @@ export function projectMacroDays(history: readonly PricePoint[], options: {
105
149
  }
106
150
 
107
151
  const reactionSessions = new Set<string>();
108
- const found: Omit<MacroDayEvent, "multiple">[] = [];
152
+ const found: Omit<MacroDayEvent, "multiple" | "earnings">[] = [];
109
153
  for (const release of options.releases) {
110
154
  if (release.date <= start || release.date > end || !isWeekday(release.date)) continue;
111
155
  const at = sessions.findIndex((date) => date >= release.date);
@@ -120,12 +164,14 @@ export function projectMacroDays(history: readonly PricePoint[], options: {
120
164
  const normalMoves = [...moves].filter(([date]) => !reactionSessions.has(date)).map(([, move]) => move);
121
165
  const normal = stats(normalMoves, null);
122
166
  const normalAbs = normal.meanAbs;
123
- const events = found.map((event) => ({ ...event, multiple: normalAbs ? Math.abs(event.move) / normalAbs : null }))
167
+ const reacted = earningsReactionSessions(options.earnings ?? [], sessions);
168
+ const events = found.map((event) => ({ ...event, earnings: reacted.has(event.session), multiple: normalAbs ? Math.abs(event.move) / normalAbs : null }))
124
169
  .sort((left, right) => right.date.localeCompare(left.date) || left.kind.localeCompare(right.kind));
125
170
  const byKind = Object.fromEntries(MACRO_EVENT_KINDS.map((kind) =>
126
- [kind, stats(events.filter((event) => event.kind === kind).map((event) => event.move), normalAbs)])) as Record<MacroEventKind, MacroDayStats>;
127
- const allEvents = stats([...reactionSessions].map((session) => moves.get(session)!), normalAbs);
128
- return { symbol: options.symbol, events, byKind, allEvents, normal, start, asOf: end };
171
+ [kind, stats(events.filter((event) => event.kind === kind && !event.earnings).map((event) => event.move), normalAbs)])) as Record<MacroEventKind, MacroDayStats>;
172
+ const sessionMoves = (flagged: boolean) => [...reactionSessions].filter((session) => reacted.has(session) === flagged).map((session) => moves.get(session)!);
173
+ return { symbol: options.symbol, events, byKind, allEvents: stats(sessionMoves(false), normalAbs), earnings: stats(sessionMoves(true), normalAbs),
174
+ normal, start, asOf: end };
129
175
  }
130
176
 
131
177
  /**
@@ -9,8 +9,8 @@ import { useAutoRefresh } from "../../../react/auto-refresh";
9
9
  import { useThemeColors } from "../../../theme/theme-context";
10
10
  import type { PaneProps } from "../../../types/plugin";
11
11
  import { Box } from "../../../ui";
12
- import { loadMacroDayHistory, loadMacroReleases } from "./client";
13
- import { projectMacroDays, type MacroDayEvent, type MacroDayModel } from "./model";
12
+ import { loadMacroDayEarnings, loadMacroDayHistory, loadMacroReleases, macroDayEarningsNotice } from "./client";
13
+ import { macroDayEventLabel, projectMacroDays, type MacroDayEvent, type MacroDayModel } from "./model";
14
14
  import { MACRO_EVENT_KINDS, MACRO_EVENT_LABELS, staleMacroReleasesNotice, type MacroEventKind } from "./releases";
15
15
 
16
16
  export const LOOKBACK_OPTIONS = [{ value: "1", label: "1Y" }, { value: "2", label: "2Y" }, { value: "3", label: "3Y" }, { value: "5", label: "5Y" }];
@@ -23,14 +23,22 @@ function pct(value: number | null | undefined, signed = true): string {
23
23
  }
24
24
  const times = (value: number | null | undefined) => value == null ? "--" : `${value.toFixed(1)}x`;
25
25
 
26
- const COLUMNS: DataTableColumn[] = [
27
- { id: "date", label: "Date", width: 19, align: "left" },
28
- { id: "release", label: "Release", width: 8, align: "left" },
26
+ const EARNINGS_MARK = "earnings";
27
+ const DATE: DataTableColumn = { id: "date", label: "Date", width: 19, align: "left" };
28
+ const MOVE: DataTableColumn[] = [
29
29
  { id: "move", label: "Move", width: 9, align: "right" },
30
30
  { id: "multiple", label: "vs Normal", width: 10, align: "right" },
31
31
  ];
32
- /** One release selected: every row would repeat its name. */
33
- const ONE_RELEASE_COLUMNS = COLUMNS.filter((column) => column.id !== "release");
32
+
33
+ /**
34
+ * With every release listed, the release's name, widened to take the earnings marker where a row has one. With one
35
+ * selected, a column only for the marker: every row would repeat the name.
36
+ */
37
+ function columnsFor(release: string, rows: readonly MacroDayEvent[]): DataTableColumn[] {
38
+ const marked = rows.some((event) => event.earnings);
39
+ if (release === "all") return [DATE, { id: "release", label: "Release", width: marked ? 15 : 8, align: "left" }, ...MOVE];
40
+ return marked ? [DATE, { id: "release", label: "Note", width: EARNINGS_MARK.length, align: "left" }, ...MOVE] : [DATE, ...MOVE];
41
+ }
34
42
 
35
43
  function figures(model: MacroDayModel, release: string): StatItem[] {
36
44
  const normal: StatItem = { id: "normal", label: "Normal day", value: pct(model.normal.meanAbs, false), detail: "avg |move|" };
@@ -39,7 +47,8 @@ function figures(model: MacroDayModel, release: string): StatItem[] {
39
47
  const stats = model.byKind[kind];
40
48
  return { id: kind, label: `${MACRO_EVENT_LABELS[kind]} day`, value: pct(stats.meanAbs, false),
41
49
  detail: stats.count ? `${times(stats.multiple)} normal` : undefined };
42
- }), normal];
50
+ }), ...(model.earnings.count ? [{ id: "earnings", label: "Earnings day", value: pct(model.earnings.meanAbs, false),
51
+ detail: `${times(model.earnings.multiple)} normal` }] : []), normal];
43
52
  }
44
53
  const stats = model.byKind[release as MacroEventKind];
45
54
  const tone = (value: number | null) => value == null ? undefined : value >= 0 ? "positive" as const : "negative" as const;
@@ -64,12 +73,10 @@ export function MacroDayPane({ width, height, focused }: PaneProps) {
64
73
  const loader = useCallback(async (force: boolean) => {
65
74
  controller.current?.abort();
66
75
  controller.current = new AbortController();
67
- const [snapshot, releases] = await Promise.all([
68
- loadMacroDayHistory({ instrument: instrument!, forceRefresh: force, signal: controller.current.signal }),
69
- loadMacroReleases({ force }),
70
- ]);
76
+ const request = { instrument: instrument!, forceRefresh: force, signal: controller.current.signal };
77
+ const [snapshot, releases, earnings] = await Promise.all([loadMacroDayHistory(request), loadMacroReleases({ force }), loadMacroDayEarnings(request)]);
71
78
  if (!snapshot.history.length && snapshot.error) throw new Error(snapshot.error);
72
- return { ...snapshot, releases };
79
+ return { ...snapshot, releases, earnings };
73
80
  }, [instrumentKey]);
74
81
  const history = useAsyncResource(instrument ? loader : null);
75
82
  useEffect(() => () => controller.current?.abort(), [loader]);
@@ -77,26 +84,29 @@ export function MacroDayPane({ width, height, focused }: PaneProps) {
77
84
  usePaneRefreshKey(() => { void history.reload(); }, { focused });
78
85
 
79
86
  const model = useMemo(() => history.data ? projectMacroDays(history.data.history, { symbol: symbol ?? "", lookbackYears: Number(lookback) || 5,
80
- releases: history.data.releases.releases, coveredThrough: history.data.releases.coveredThrough }) : null, [history.data, lookback, symbol]);
87
+ releases: history.data.releases.releases, coveredThrough: history.data.releases.coveredThrough, earnings: history.data.earnings.reports }) : null,
88
+ [history.data, lookback, symbol]);
81
89
  const releasesNotice = history.data ? staleMacroReleasesNotice(history.data.releases) : null;
90
+ const earningsNotice = history.data ? macroDayEarningsNotice(history.data.earnings) : null;
82
91
  const rows = useMemo(() => model ? model.events.filter((event) => release === "all" || event.kind === release) : [], [model, release]);
83
92
  const stats = useMemo(() => model?.events.length ? figures(model, release) : [], [model, release]);
93
+ const columns = useMemo(() => columnsFor(release, rows), [release, rows]);
84
94
 
85
95
  usePaneNoticeFooter({ registrationId: "macro-day-notices", focused,
86
- notices: [...new Set([identityError, history.error, history.data?.error, releasesNotice].filter((value): value is string => !!value))] });
96
+ notices: [...new Set([identityError, history.error, history.data?.error, releasesNotice, earningsNotice].filter((value): value is string => !!value))] });
87
97
  usePaneFooter("macro-day", () => ({ info: [
88
98
  ...(history.loading ? [{ id: "loading", parts: [{ text: "loading history", tone: "muted" as const }] }] : []),
89
- ...(history.data?.stale ? [{ id: "stale", parts: [{ text: "stale history", tone: "warning" as const }] }] : []),
99
+ ...(history.data?.stale || history.data?.earnings.stale ? [{ id: "stale", parts: [{ text: "stale history", tone: "warning" as const }] }] : []),
90
100
  ...(model?.asOf ? [{ id: "date", parts: [{ text: `daily closes ${model.start} to ${model.asOf}`, tone: "muted" as const }] }] : []),
91
- ] }), [history.loading, history.data?.stale, model?.start, model?.asOf]);
101
+ ] }), [history.loading, history.data?.stale, history.data?.earnings.stale, model?.start, model?.asOf]);
92
102
 
93
103
  const renderCell = useCallback((event: MacroDayEvent, column: DataTableColumn): DataTableCell => {
94
104
  if (column.id === "date") return { text: event.session === event.date ? event.date : `${event.date} → ${event.session.slice(5)}`, value: event.date };
95
- if (column.id === "release") return { text: MACRO_EVENT_LABELS[event.kind] };
105
+ if (column.id === "release") return { text: release === "all" ? macroDayEventLabel(event) : event.earnings ? EARNINGS_MARK : "" };
96
106
  if (column.id === "move") return { text: pct(event.move), value: event.move * 100,
97
107
  color: event.move > 0 ? colors.positive : event.move < 0 ? colors.negative : undefined };
98
108
  return { text: times(event.multiple), value: event.multiple };
99
- }, [colors]);
109
+ }, [colors, release]);
100
110
 
101
111
  const contentHeight = Math.max(4, height - 1 - statGridRows(stats, width));
102
112
  const key = (event: MacroDayEvent) => `${event.kind}:${event.date}`;
@@ -110,7 +120,7 @@ export function MacroDayPane({ width, height, focused }: PaneProps) {
110
120
  error={!model ? history.error ?? identityError ?? null : null} empty={!!model && !model.events.length}>
111
121
  {model ? <>
112
122
  <StatGrid items={stats} width={width} />
113
- <DataTableView<MacroDayEvent> focused={focused} columns={release === "all" ? COLUMNS : ONE_RELEASE_COLUMNS} items={rows} rootWidth={width} rootHeight={contentHeight}
123
+ <DataTableView<MacroDayEvent> focused={focused} columns={columns} items={rows} rootWidth={width} rootHeight={contentHeight}
114
124
  getItemKey={key} emptyStateTitle="No release days." sortColumnId={null} sortDirection="desc" selectedTextOverridesCellColor
115
125
  selection={{ kind: "id", selectedId: selectedRow, getId: key, onChange: (id) => setSelectedRow(id) }}
116
126
  getExportMetadata={() => [["symbol", model.symbol], ["from", model.start ?? ""], ["to", model.asOf ?? ""],
@@ -1,6 +1,6 @@
1
1
  import type { HeadlessPaneColumn, HeadlessPaneDefinition } from "../../../types/plugin";
2
2
  import { formatCompact, formatPercentRaw } from "../../../utils/format";
3
- import { MARKET_HEATMAP_REQUEST_COUNT, MARKET_HEATMAP_UNIVERSES, fetchMarketHeatmap, type MarketHeatmapUniverseId } from "./data";
3
+ import { MARKET_HEATMAP_REQUEST_COUNT, MARKET_HEATMAP_UNIVERSES, fetchMarketHeatmap, type MarketHeatmapBoard, type MarketHeatmapUniverseId } from "./data";
4
4
  import { heatmapMove, summarizeHeatmapGroups, type HeatmapGroupBy, type HeatmapGroupSummary } from "./model";
5
5
 
6
6
  /**
@@ -39,6 +39,20 @@ function noMoveNotice(symbols: readonly string[], names: number): string {
39
39
  return `${symbols.length} of ${names} names have no move yet and count toward size only: ${shown}${rest}.`;
40
40
  }
41
41
 
42
+ /**
43
+ * When the board's figures are from, and whose sessions they follow: outside
44
+ * the regular session the tiles are the completed session's, so the board is
45
+ * as of that session's close (its date, from a server that does not send the
46
+ * close), not when the snapshot was put together; while it trades, the
47
+ * snapshot time.
48
+ */
49
+ function boardObservation(board: Pick<MarketHeatmapBoard, "fetchedAt" | "regularSessionDate" | "regularSessionClosedAt">) {
50
+ const closedAt = board.regularSessionDate ? board.regularSessionClosedAt : null;
51
+ const asOf = typeof closedAt === "number" && closedAt > 0 ? new Date(closedAt).toISOString()
52
+ : board.regularSessionDate || new Date(board.fetchedAt).toISOString();
53
+ return { asOf, sessionExchange: "NYSE" };
54
+ }
55
+
42
56
  function projectRow(summary: HeatmapGroupSummary, groupBy: HeatmapGroupBy, whole = false) {
43
57
  return {
44
58
  group: whole ? "All" : summary.group ?? (summary.sector ? "No industry" : groupBy === "industry" ? "Unclassified" : "No sector"),
@@ -86,12 +100,13 @@ export const marketHeatmapHeadless: HeadlessPaneDefinition<"rows"> = {
86
100
  aliases: ["HM", "heatmap"],
87
101
  dataRequirements: ["Gloom Cloud market heatmap snapshot"],
88
102
  limitations: [
89
- "The snapshot the pane starts from, refreshed about once a minute; the pane's live-streamed colors are not in the report",
90
- "Moves are weighted by market cap (net assets for ETFs), not by the pane's square-root tile area",
103
+ "The snapshot the pane starts from, refreshed about once a minute; the pane's live-streamed colors are not in the report.",
104
+ "Moves are weighted by market cap (net assets for ETFs), not by the pane's square-root tile area.",
91
105
  ],
92
106
  },
93
107
  // A board snapshot refreshed on a schedule, not a feed; the pane streams on top of it, the report does not.
94
- freshness: { status: "delayed" },
108
+ // A completed session it names only by its date is a US trading day.
109
+ freshness: { status: "delayed", tradingDayMarket: "US" },
95
110
  describe: (args) => {
96
111
  const universe = MARKET_HEATMAP_UNIVERSES.find((entry) => entry.id === args.options.universe)?.label ?? "US Stocks";
97
112
  return args.options.universe === "us-etf" ? `Market Heatmap | ${universe}` : `Market Heatmap | ${universe} by ${String(args.options.group)}`;
@@ -117,7 +132,7 @@ export const marketHeatmapHeadless: HeadlessPaneDefinition<"rows"> = {
117
132
  metadata: {
118
133
  universe,
119
134
  groupBy: flat ? null : groupBy,
120
- asOf: new Date(result.fetchedAt).toISOString(),
135
+ ...boardObservation(result),
121
136
  stale: result.stale === true,
122
137
  session: result.session ?? null,
123
138
  regularSessionDate: result.regularSessionDate ?? null,
@@ -743,6 +743,12 @@ export const marketHeatmapPlugin: GloomPlugin = {
743
743
  name: "Market Heatmap",
744
744
  icon: "H",
745
745
  component: MarketHeatmapPane,
746
+ // Portfolio tiles disclose position values; watchlist and market tiles do not.
747
+ personalData: ({ settings, paneState }) => (
748
+ settings.universe === PORTFOLIO_HEATMAP_TAB
749
+ && paneState[HEATMAP_COLLECTION_KIND_STATE_KEY] === "portfolio"
750
+ ? "holdings" : null
751
+ ),
746
752
  headless: marketHeatmapHeadless,
747
753
  defaultPosition: "right",
748
754
  defaultMode: "floating",
@@ -77,18 +77,24 @@ const twoDigits = (value: number) => String(value).padStart(2, "0");
77
77
  /** A New York calendar day ("2026-10-09") as the footer names it: "Oct 9". */
78
78
  const dayLabel = (day: string) => formatShortDate(day, { year: false, utc: true, fallback: day });
79
79
 
80
+ const isTimestamp = (value: number | null | undefined): value is number =>
81
+ typeof value === "number" && Number.isFinite(value) && value > 0;
82
+
80
83
  /**
81
84
  * What a market board covers and when it is from, for the footer: how many of
82
85
  * the largest names it holds, the completed regular session it shows outside
83
- * that session, when the server put the snapshot together, in New York time,
84
- * dated when that day is not the session's (or, while the session trades,
85
- * today's), and when this client last checked, which is a separate figure.
86
- * A footer narrower than `maxWidth` loses the check first, then the snapshot,
87
- * then the session; after a failed refresh (`failed`) the age of the last good
88
- * check outlasts the snapshot. Null when not even the count fits.
86
+ * that session, the time its figures are as of, in New York time, dated when
87
+ * that day is not the session's (or, while the session trades, today's), and
88
+ * when this client last checked, which is a separate figure. A board of a
89
+ * completed session is as of that session's close (`regularSessionClosedAt`);
90
+ * otherwise, or from a server that does not say, the time is when the server
91
+ * put the snapshot together. A footer narrower than `maxWidth` loses the check
92
+ * first, then that time, then the session; after a failed refresh (`failed`)
93
+ * the age of the last good check outlasts the time. Null when not even the
94
+ * count fits.
89
95
  */
90
96
  export function heatmapBoardCaption(
91
- board: { topCount: number; fetchedAt: number; regularSessionDate?: string | null },
97
+ board: { topCount: number; fetchedAt: number; regularSessionDate?: string | null; regularSessionClosedAt?: number | null },
92
98
  { now, checked = null, failed = false, maxWidth = Number.POSITIVE_INFINITY }:
93
99
  { now: number; checked?: string | null; failed?: boolean; maxWidth?: number },
94
100
  ): string | null {
@@ -96,11 +102,13 @@ export function heatmapBoardCaption(
96
102
  // Display order; `rank` is the order they give way in, highest first.
97
103
  const parts: Array<{ text: string; rank: number }> = [{ text: `top ${board.topCount}`, rank: 0 }];
98
104
  if (sessionDate) parts.push({ text: `${dayLabel(sessionDate)} session`, rank: 1 });
99
- if (Number.isFinite(board.fetchedAt) && board.fetchedAt > 0) {
100
- const { hour, minute } = zonedDateTimeParts(board.fetchedAt, NEW_YORK);
105
+ const closedAt = sessionDate && isTimestamp(board.regularSessionClosedAt) ? board.regularSessionClosedAt : null;
106
+ const time = closedAt ?? (isTimestamp(board.fetchedAt) ? board.fetchedAt : null);
107
+ if (time != null) {
108
+ const { hour, minute } = zonedDateTimeParts(time, NEW_YORK);
101
109
  const clock = `${twoDigits(hour)}:${twoDigits(minute)} ET`;
102
- const day = zonedDateKey(board.fetchedAt, NEW_YORK);
103
- const text = `snapshot ${day === (sessionDate ?? zonedDateKey(now, NEW_YORK)) ? clock : `${dayLabel(day)} ${clock}`}`;
110
+ const day = zonedDateKey(time, NEW_YORK);
111
+ const text = `${closedAt != null ? "as of" : "snapshot"} ${day === (sessionDate ?? zonedDateKey(now, NEW_YORK)) ? clock : `${dayLabel(day)} ${clock}`}`;
104
112
  parts.push({ text, rank: failed ? 3 : 2 });
105
113
  }
106
114
  if (checked) parts.push({ text: `checked ${checked}`, rank: failed ? 2 : 3 });
@@ -5,7 +5,7 @@ import type { ColumnConfig } from "../../../types/config";
5
5
  import type { TickerFinancials } from "../../../types/financials";
6
6
  import {
7
7
  getRegularSessionMoveDisplay,
8
- getSessionMoveDisplay,
8
+ getTradedSessionMoveDisplay,
9
9
  type ActiveQuoteDisplay,
10
10
  type ExtendedSession,
11
11
  } from "../../../market-data/market/status";
@@ -227,7 +227,7 @@ export function buildPortfolioHeatmapAssets({
227
227
  // Colored like the market boards: an open extended session's move, else the regular session's.
228
228
  const display: (ActiveQuoteDisplay & { session?: ExtendedSession }) | null = regularSession
229
229
  ? getRegularSessionMoveDisplay(quote)
230
- : getSessionMoveDisplay(quote);
230
+ : getTradedSessionMoveDisplay(quote);
231
231
  const price = display != null && Number.isFinite(display.price) ? display.price : null;
232
232
  const size = positiveNumber(getSortValue(sizeColumn, ticker, snapshot, context));
233
233
  const hasChange = display?.changePercent != null && Number.isFinite(display.changePercent);
@@ -5,18 +5,19 @@ import type {
5
5
  CloudSessionMoversSide,
6
6
  } from "../../../api-client/market-movers";
7
7
  import type { DataProvider } from "../../../types/data-provider";
8
- import { CATEGORY_MAP, screenerQuoteFromQuote, type ScreenerTabId } from "./model";
8
+ import { CATEGORY_MAP, moverRegularSession, screenerQuoteFromQuote, type MoverQuote, type ScreenerTabId } from "./model";
9
9
  import {
10
10
  fetchPreferredMarketMovers,
11
11
  fetchTrending,
12
12
  type MarketMoversResult,
13
13
  type PreferredMoversOptions,
14
- type ScreenerQuote,
15
14
  type TrendingSymbol,
16
15
  } from "./screener";
17
16
 
18
17
  export interface MarketMoverTabResult extends MarketMoversResult {
19
18
  tab: ScreenerTabId;
19
+ /** In the list's order; Last and Chg% the regular session, as `ticker` reads them. */
20
+ quotes: MoverQuote[];
20
21
  }
21
22
 
22
23
  export interface MarketMoverTabDependencies {
@@ -36,9 +37,9 @@ const defaultDependencies: MarketMoverTabDependencies = {
36
37
  async function hydrateTrending(
37
38
  trending: readonly TrendingSymbol[],
38
39
  provider: DataProvider | null,
39
- ): Promise<ScreenerQuote[]> {
40
+ ): Promise<MoverQuote[]> {
40
41
  const symbols = trending.slice(0, 25).map(({ symbol }) => symbol);
41
- const bySymbol = new Map<string, ScreenerQuote>();
42
+ const bySymbol = new Map<string, MoverQuote>();
42
43
  if (!provider) return [];
43
44
  if (provider.getQuotesBatch) {
44
45
  const results = await provider.getQuotesBatch(
@@ -79,7 +80,8 @@ export async function loadMarketMoverTab(
79
80
  };
80
81
  }
81
82
  const result = await dependencies.fetchPreferred(CATEGORY_MAP[tab], 25, options);
82
- return { ...result, tab };
83
+ // Ranked by the live print first, so reading each row's regular session keeps its place.
84
+ return { ...result, quotes: result.quotes.map(moverRegularSession), tab };
83
85
  }
84
86
 
85
87
  /** The server refused the list for the account's plan. */
@@ -34,6 +34,7 @@ import {
34
34
  type MarketMoverColumn,
35
35
  type MarketMoverRow,
36
36
  type MarketMoverSortPreference,
37
+ type MoverQuote,
37
38
  type ScreenerTabId,
38
39
  type TabId,
39
40
  } from "./model";
@@ -58,7 +59,7 @@ import {
58
59
  /** Stable identity: a fresh literal here would reload the board every render. */
59
60
  const NO_SAVED_SELECTION: string[] = [];
60
61
  const SESSION_CHECK_MS = 30_000;
61
- const NO_QUOTES: ScreenerQuote[] = [];
62
+ const NO_QUOTES: MoverQuote[] = [];
62
63
  const moverKey = (row: Pick<ScreenerQuote, "symbol" | "exchange">) => publicTickerKey(row.symbol, row.exchange);
63
64
 
64
65
  /** What is trading in New York, re-read every half minute so the pane follows 04:00, 09:30 and 16:00. */
@@ -154,7 +155,7 @@ function ScreenerMoversBody({ activeTab, focused, width, summaryQuotes, liveStre
154
155
  }) {
155
156
  const dataProvider = useAssetData();
156
157
  const { pinTicker } = usePluginTickerActions();
157
- const [quotes, setQuotes] = useState<ScreenerQuote[]>([]);
158
+ const [quotes, setQuotes] = useState<MoverQuote[]>([]);
158
159
  const [loadedTab, setLoadedTab] = useState<TabId | null>(null);
159
160
  const visibleQuotes = loadedTab === activeTab ? quotes : NO_QUOTES;
160
161
  // The first load starts before the effect runs; an empty board is not "no data".
@@ -184,6 +184,36 @@ function moverExtended(quote: Quote): ExtendedSessionDisplay | null {
184
184
  return extended && isFiniteNumber(extended.price) ? extended : null;
185
185
  }
186
186
 
187
+ /**
188
+ * A listed row as `ticker` reads its quote: Last and Chg% are the regular
189
+ * session's close and move, and a pre-market or after-hours print is its
190
+ * `extended`, measured from that close. The list ranked it by its live print
191
+ * first, so its place stays. A row without its quote's sessions (an older
192
+ * server) reads as it came.
193
+ */
194
+ export function moverRegularSession({ sessions, ...row }: ScreenerQuote): MoverQuote {
195
+ if (!sessions || row.price == null) return row;
196
+ const quote: Quote = {
197
+ symbol: row.symbol,
198
+ price: row.price,
199
+ change: row.change ?? Number.NaN,
200
+ changePercent: row.changePercent ?? Number.NaN,
201
+ previousClose: row.previousClose,
202
+ currency: row.currency,
203
+ lastUpdated: row.lastUpdated ?? Number.NaN,
204
+ listingExchangeName: row.exchange || undefined,
205
+ ...sessions,
206
+ };
207
+ const headline = getRegularSessionDisplay(quote)!;
208
+ return {
209
+ ...row,
210
+ price: screenerNumber(headline.price),
211
+ change: screenerNumber(headline.change),
212
+ changePercent: screenerNumber(headline.changePercent),
213
+ extended: moverExtended(quote),
214
+ };
215
+ }
216
+
187
217
  /**
188
218
  * A trending row from its quote: Last and Chg% are the regular session, as
189
219
  * `ticker` reads it, and a pre-market or after-hours print rides beside them.
@@ -8,7 +8,9 @@ import type {
8
8
  CloudMarketScreenerCategory,
9
9
  CloudMarketScreenerItem,
10
10
  CloudMarketScreenerPayload,
11
+ CloudMoverSessionFields,
11
12
  } from "../../../api-client/types";
13
+ import type { MarketState } from "../../../types/financials";
12
14
  import { hasProAccess } from "../../../api-client/plan-access";
13
15
 
14
16
  const CACHE_KIND = "market-screener";
@@ -184,6 +186,32 @@ export function convertScreenerPriceUnit(value: number | undefined, from: string
184
186
  ? value / source.divisor * target.divisor : undefined;
185
187
  }
186
188
 
189
+ const MARKET_STATES = new Set<string>(["PRE", "REGULAR", "POST", "PREPRE", "POSTPOST", "CLOSED"] satisfies MarketState[]);
190
+ const SESSION_NUMBERS = [
191
+ "regularClose", "regularChange", "regularChangePercent",
192
+ "preMarketPrice", "preMarketChange", "preMarketChangePercent",
193
+ "postMarketPrice", "postMarketChange", "postMarketChangePercent",
194
+ ] as const;
195
+ const isSessionDate = (value: unknown): value is string => typeof value === "string" && /^\d{4}-\d{2}-\d{2}$/.test(value);
196
+
197
+ /**
198
+ * A row's quote sessions as the server sends them beside its live print, or
199
+ * undefined when it sends none (an older server), so the row reads as it came.
200
+ */
201
+ function parseScreenerSessions(row: Record<string, unknown>): CloudMoverSessionFields | undefined {
202
+ if (typeof row.marketState !== "string" || !MARKET_STATES.has(row.marketState)) return undefined;
203
+ const sessions: CloudMoverSessionFields = { marketState: row.marketState as MarketState };
204
+ if (isSessionDate(row.changeSessionDate)) sessions.changeSessionDate = row.changeSessionDate;
205
+ for (const key of SESSION_NUMBERS) {
206
+ const value = screenerNumber(row[key]);
207
+ if (value != null) sessions[key] = value;
208
+ }
209
+ if (sessions.regularClose != null && isSessionDate(row.regularCloseSessionDate)) {
210
+ sessions.regularCloseSessionDate = row.regularCloseSessionDate;
211
+ }
212
+ return sessions;
213
+ }
214
+
187
215
  /** Validate numeric fields at the API boundary so absent values stay unavailable. */
188
216
  export function parseScreenerResponse(data: unknown): ScreenerQuote[] {
189
217
  if (!data || typeof data !== "object" || !("quotes" in data) || !Array.isArray(data.quotes)) {
@@ -202,6 +230,7 @@ export function parseScreenerResponse(data: unknown): ScreenerQuote[] {
202
230
  dayHigh: screenerNumber(q.dayHigh) ?? undefined, dayLow: screenerNumber(q.dayLow) ?? undefined,
203
231
  previousClose: screenerNumber(q.previousClose) ?? undefined, exchange: typeof q.exchange === "string" ? q.exchange : "",
204
232
  lastUpdated: typeof q.lastUpdated === "number" && Number.isFinite(q.lastUpdated) && q.lastUpdated > 0 ? q.lastUpdated : undefined,
233
+ sessions: parseScreenerSessions(q),
205
234
  }];
206
235
  });
207
236
  }
@@ -274,6 +303,8 @@ function mergeCloudScreenerItem(
274
303
  dayLow: screenerNumber(item.dayLow) ?? metadataPrice(metadata?.dayLow),
275
304
  exchange: item.exchange || metadata?.exchange || "",
276
305
  lastUpdated: item.lastUpdated,
306
+ previousClose: screenerNumber(item.previousClose) ?? undefined,
307
+ sessions: parseScreenerSessions(item as unknown as Record<string, unknown>),
277
308
  };
278
309
  }
279
310