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
@@ -2,6 +2,7 @@ import type {
2
2
  AnalystEstimateRecord,
3
3
  AnalystResearchData,
4
4
  CorporateActionsData,
5
+ EarningsDateStatus,
5
6
  FinancialStatement,
6
7
  TickerFinancials,
7
8
  } from "../../../types/financials";
@@ -13,6 +14,14 @@ import {
13
14
  formatPercentRaw,
14
15
  } from "../../../utils/format";
15
16
  import { computeTTM } from "../ticker-detail/financials/aggregation";
17
+ import {
18
+ earningsDateStatus,
19
+ earningsEpsBasis,
20
+ epsBasisName,
21
+ epsSurprise,
22
+ inFiscalMonth,
23
+ type EpsBasisName,
24
+ } from "../shared/earnings-report";
16
25
 
17
26
  export const CORPORATE_ACTION_COVERAGE = "Split-feed factors may include spinoff price adjustments. Merger terms, spinoff distributions, and security conversions are not covered.";
18
27
 
@@ -37,7 +46,11 @@ export interface EventRow {
37
46
  epsEstimate?: number;
38
47
  epsDifference?: number;
39
48
  surprisePercent?: number;
40
- epsBasis?: "provider-unspecified";
49
+ /** A reported figure's basis; the same quarter is named the same way in ERN. */
50
+ epsBasis?: EpsBasisName;
51
+ /** Analysts behind `epsEstimate`, when known. */
52
+ epsAnalysts?: number;
53
+ dateStatus?: EarningsDateStatus;
41
54
  providerId?: string;
42
55
  fetchedAt?: string;
43
56
  /** Keep the supplied ranges and comparison inputs available in detail/export. */
@@ -83,9 +96,9 @@ function sortedQuarterlyStatements(
83
96
 
84
97
  const MONTHS = ["Jan", "Feb", "Mar", "Apr", "May", "Jun", "Jul", "Aug", "Sep", "Oct", "Nov", "Dec"];
85
98
 
86
- /** The quarter by the month it ends in, e.g. "Jun 2026". */
87
- function quarterLabel(statement: FinancialStatement | undefined): string {
88
- const match = /^(\d{4})-(\d{2})/.exec(statement?.date ?? "");
99
+ /** The quarter by the month it ends in, e.g. "Jun 2026", from a date or a YYYY-MM period. */
100
+ function quarterLabel(date: string | undefined): string {
101
+ const match = /^(\d{4})-(\d{2})/.exec(date ?? "");
89
102
  const month = match ? MONTHS[Number(match[2]) - 1] : undefined;
90
103
  return match && month ? `${month} ${match[1]}` : "-";
91
104
  }
@@ -94,10 +107,14 @@ function statementForEarningsDate(
94
107
  quarterlyStatements: readonly FinancialStatement[],
95
108
  earning: CorporateActionsData["earnings"][number],
96
109
  ): FinancialStatement | undefined {
97
- // Announcement proximity cannot establish which quarter a result describes.
98
- // Vendor period aliases are usable only when the statement retains that identity.
99
- if (earning.dateType !== "fiscal-period-end") return undefined;
100
- const matches = quarterlyStatements.filter((statement) => statement.date === earning.date || statement.providerDate === earning.date);
110
+ // Announcement proximity cannot establish which quarter a result describes:
111
+ // only a stated fiscal quarter can. Vendor period aliases are usable only
112
+ // when the statement retains that identity.
113
+ const matches = earning.fiscalPeriod
114
+ ? quarterlyStatements.filter((statement) => inFiscalMonth(statement.date, earning.fiscalPeriod))
115
+ : earning.dateType === "fiscal-period-end"
116
+ ? quarterlyStatements.filter((statement) => statement.date === earning.date || statement.providerDate === earning.date)
117
+ : [];
101
118
  return matches.length === 1 ? matches[0] : undefined;
102
119
  }
103
120
 
@@ -156,13 +173,14 @@ function estimateValue(pair: EstimatePair): string {
156
173
 
157
174
  /**
158
175
  * The TTM row sits under the reported quarters, so its EPS sums those rows'
159
- * provider EPS (often adjusted) rather than statement GAAP EPS whenever the
160
- * four statement quarters each have a reported row.
176
+ * EPS (often adjusted) rather than statement GAAP EPS whenever the four
177
+ * statement quarters each have a reported row. Quarters with nothing to
178
+ * adjust read GAAP, so any adjusted quarter makes the sum adjusted.
161
179
  */
162
180
  function reportedTtmEps(
163
181
  latestFour: readonly FinancialStatement[],
164
182
  earnings: CorporateActionsData["earnings"],
165
- ): { eps: number; currency?: string } | null {
183
+ ): { eps: number; currency?: string; basis: EpsBasisName } | null {
166
184
  if (latestFour.length < 4) return null;
167
185
  const reported = earnings.filter((earning) => earning.epsActual != null);
168
186
  const quarters = latestFour.map((statement) => {
@@ -172,9 +190,13 @@ function reportedTtmEps(
172
190
  if (quarters.some((earning) => earning == null)) return null;
173
191
  const currencies = new Set(quarters.map((earning) => earning!.currency));
174
192
  if (currencies.size !== 1) return null;
175
- return { eps: quarters.reduce((sum, earning) => sum + earning!.epsActual!, 0), currency: quarters[0]!.currency };
193
+ const bases = quarters.map((earning) => epsBasisName(earningsEpsBasis(earning!.epsBasis)));
194
+ const basis = bases.includes("unknown") ? "unknown" : bases.includes("adjusted") ? "adjusted" : "GAAP";
195
+ return { eps: quarters.reduce((sum, earning) => sum + earning!.epsActual!, 0), currency: quarters[0]!.currency, basis };
176
196
  }
177
197
 
198
+ const BASIS_TEXT: Record<EpsBasisName, string> = { GAAP: "GAAP", adjusted: "adj", unknown: "basis unknown" };
199
+
178
200
  function ttmRow(
179
201
  quarterlyStatements: readonly FinancialStatement[],
180
202
  earnings: CorporateActionsData["earnings"],
@@ -191,7 +213,8 @@ function ttmRow(
191
213
  status: "TTM",
192
214
  period: "4 qtrs",
193
215
  // Statement EPS is not the sum of the (often adjusted) rows above it.
194
- detail: !reportedEps && ttm.eps != null ? "statement EPS" : "sum",
216
+ detail: !reportedEps && ttm.eps != null ? "statement EPS"
217
+ : reportedEps && reportedEps.basis !== "unknown" ? `${BASIS_TEXT[reportedEps.basis]} sum` : "sum",
195
218
  epsCurrency: reportedEps ? reportedEps.currency : ttm.currency ?? financialCurrency,
196
219
  revenueCurrency: ttm.currency ?? financialCurrency,
197
220
  annualEps: reportedEps ? reportedEps.eps : ttm.eps,
@@ -201,11 +224,17 @@ function ttmRow(
201
224
  };
202
225
  }
203
226
 
227
+ /** A reported row names its basis and beat; a pending one whether its date is announced and its analysts. */
204
228
  function earningsDetail(earning: CorporateActionsData["earnings"][number]): string {
205
- if (earning.epsActual == null) return "Pending";
229
+ if (earning.epsActual == null) {
230
+ const status = earningsDateStatus(earning.dateStatus);
231
+ const parts = [status === "reported" ? null : status, earning.epsAnalysts != null ? `${earning.epsAnalysts} analysts` : null];
232
+ return parts.filter(Boolean).join(", ") || "Pending";
233
+ }
234
+ const basis = BASIS_TEXT[epsBasisName(earningsEpsBasis(earning.epsBasis))];
206
235
  const detail = earning.difference == null
207
- ? "Reported"
208
- : `${earning.difference > 0 ? "+" : ""}${formatNumber(earning.difference, 2)} vs est`;
236
+ ? basis
237
+ : `${basis}, ${earning.difference > 0 ? "+" : ""}${formatNumber(earning.difference, 2)} vs est`;
209
238
  return earning.dateType === "fiscal-period-end" ? `Period end; ${detail}` : detail;
210
239
  }
211
240
 
@@ -237,12 +266,21 @@ function reportedPeriodTimes(
237
266
  quarterlyStatements: readonly FinancialStatement[],
238
267
  ): number[] {
239
268
  return earnings
240
- .filter((earning) => earning.epsActual != null && earning.dateType === "fiscal-period-end")
241
- .flatMap((earning) => [earning.date, statementForEarningsDate(quarterlyStatements, earning)?.date])
269
+ .filter((earning) => earning.epsActual != null && (earning.dateType === "fiscal-period-end" || earning.fiscalPeriod))
270
+ .flatMap((earning) => [
271
+ earning.fiscalPeriod ? fiscalMonthEnd(earning.fiscalPeriod) : earning.date,
272
+ statementForEarningsDate(quarterlyStatements, earning)?.date,
273
+ ])
242
274
  .map((date) => Date.parse(date ?? ""))
243
275
  .filter(Number.isFinite);
244
276
  }
245
277
 
278
+ /** The last day of a YYYY-MM fiscal quarter end month. */
279
+ function fiscalMonthEnd(period: string): string | undefined {
280
+ const match = /^(\d{4})-(\d{2})$/.exec(period);
281
+ return match ? new Date(Date.UTC(Number(match[1]), Number(match[2]), 0)).toISOString().slice(0, 10) : undefined;
282
+ }
283
+
246
284
  /**
247
285
  * An upstream snapshot can keep serving a reported quarter as "0q" until its trend rolls
248
286
  * (REF and ORCL in Sep 2026), so that consensus describes a past period.
@@ -283,12 +321,16 @@ export function buildEventRows(
283
321
  for (const [index, earning] of earnings.entries()) {
284
322
  // A pending announcement must never inherit the previous report's actuals.
285
323
  const statement = earning.epsActual == null ? undefined : statementForEarningsDate(quarterlyStatements, earning);
324
+ const surprise = epsSurprise(earning.epsActual, earning.epsEstimate);
325
+ const surprisePercent = earning.epsActual == null ? undefined
326
+ : surprise != null ? Math.round(surprise * 10_000) / 100 : earning.surprisePercent;
286
327
  rows.push({
287
328
  id: earningsIds[index]!,
288
- date: statement?.date ?? earning.date,
329
+ // An announcement keeps its date beside ERN's; a period-end row moves to its statement's.
330
+ date: earning.dateType === "fiscal-period-end" ? statement?.date ?? earning.date : earning.date,
289
331
  dateType: earning.dateType,
290
332
  status: "Earnings",
291
- period: statement ? quarterLabel(statement) : earning.time?.trim() || "-",
333
+ period: statement ? quarterLabel(statement.date) : earning.fiscalPeriod ? quarterLabel(earning.fiscalPeriod) : earning.time?.trim() || "-",
292
334
  detail: earningsDetail(earning),
293
335
  epsCurrency: earning.currency ?? (earning.epsActual == null ? feedCurrency : undefined),
294
336
  revenueCurrency: statement ? statement.currency ?? financials?.financialCurrency : undefined,
@@ -298,16 +340,18 @@ export function buildEventRows(
298
340
  epsActual: earning.epsActual,
299
341
  epsEstimate: earning.epsEstimate,
300
342
  epsDifference: earning.epsActual == null ? undefined : earning.difference,
301
- surprisePercent: earning.epsActual == null ? undefined : earning.surprisePercent,
302
- epsBasis: "provider-unspecified",
343
+ surprisePercent,
344
+ epsBasis: earning.epsActual == null ? undefined : epsBasisName(earningsEpsBasis(earning.epsBasis)),
345
+ epsAnalysts: earning.epsAnalysts,
346
+ dateStatus: earningsDateStatus(earning.dateStatus) ?? undefined,
303
347
  providerId: data?.providerId,
304
348
  fetchedAt: data?.fetchedAt,
305
349
  fiscalPeriodEnd: statement?.date,
306
350
  periodDateSource: statement?.dateSource,
307
351
  providerPeriodDate: earning.dateType === "fiscal-period-end" ? earning.date : undefined,
308
352
  dateEvidence: statement?.dateEvidence,
309
- value: earning.epsActual != null && earning.surprisePercent != null ? formatPercentRaw(earning.surprisePercent) : "-",
310
- tone: earning.epsActual == null || earning.surprisePercent == null ? "muted" : earning.surprisePercent >= 0 ? "positive" : "negative",
353
+ value: surprisePercent != null ? formatPercentRaw(surprisePercent) : "-",
354
+ tone: surprisePercent == null ? "muted" : surprisePercent >= 0 ? "positive" : "negative",
311
355
  });
312
356
  }
313
357
 
@@ -11,6 +11,7 @@ import type {
11
11
  import { buildEventRows, eventSourceNotice, CORPORATE_ACTION_COVERAGE } from "./event-model";
12
12
  import { EVENT_COLUMNS, loadEventSources } from "./event-sources";
13
13
  import { REPORTED_DATA } from "../shared/report-freshness";
14
+ import { EPS_BASIS_NOTE } from "../shared/earnings-report";
14
15
 
15
16
  interface EventHeadlessData {
16
17
  actions: CorporateActionsData | null;
@@ -69,7 +70,7 @@ export function createEventsHeadless(
69
70
  .map((row) => ({ ...row })),
70
71
  errors: errors.length > 0 ? errors : undefined,
71
72
  metadata: { symbol, currency: data.currency, coverage: data.actions?.coverage,
72
- coverageNote: CORPORATE_ACTION_COVERAGE,
73
+ coverageNote: CORPORATE_ACTION_COVERAGE, epsBasis: EPS_BASIS_NOTE,
73
74
  actionsFetchedAt: data.actions?.fetchedAt, estimatesFetchedAt: data.estimates?.fetchedAt,
74
75
  ...(notice ? { notice: notice.text } : {}),
75
76
  },
@@ -12,6 +12,7 @@ import type {
12
12
  import { buildEventRows, eventSourceNotice, type EventRow } from "./event-model";
13
13
  import { EVENT_COLUMNS, loadEventSources } from "./event-sources";
14
14
  import { REPORTED_DATA } from "../shared/report-freshness";
15
+ import { EPS_BASIS_NOTE } from "../shared/earnings-report";
15
16
 
16
17
  export interface EarningsEstimateSources {
17
18
  actions: CorporateActionsData | null;
@@ -81,7 +82,7 @@ function projectEarningsEstimatesHeadless(
81
82
  returned: rows.length,
82
83
  truncated: rows.length < matching.length,
83
84
  coverageNote: notice?.text,
84
- epsBasis: "Provider EPS and consensus may be adjusted; accounting basis is unspecified. TTM EPS sums the reported quarter rows when all four match a statement period; otherwise it comes from statements.",
85
+ epsBasis: `${EPS_BASIS_NOTE} TTM EPS sums the reported quarter rows when all four match a statement period; otherwise it is statement EPS.`,
85
86
  dateNote: "Fiscal period dates are not announcement dates. Revenue is attached only to an identified statement period.",
86
87
  unmatchedReportedPeriods,
87
88
  },
@@ -61,6 +61,8 @@ export const researchModule: PluginModule = {
61
61
  {
62
62
  id: "equity-diagnostic",
63
63
  reportFreshness: { status: "not-a-feed", basis: "analysis of filings" },
64
+ // Signed in, Free reads a preview and Pro the full report; signed out it shows the sign-in wall.
65
+ reportRequirements: ["Free Gloom sign-in"],
64
66
  name: "Equity Diagnostic",
65
67
  icon: "D",
66
68
  component: EquityDiagnosticView,
@@ -0,0 +1,65 @@
1
+ import type { CloudSearchDocument, CloudSearchHit } from "../../../api-client";
2
+ import {
3
+ articleGist,
4
+ listedTickers,
5
+ parseArticle,
6
+ type ArticleBlock,
7
+ } from "../../../components/reader/article-text";
8
+ import { formatDetailDate } from "../../../utils/datetime-format";
9
+ import { chunkAttribution, hitTypeLabel } from "./model";
10
+
11
+ export interface SearchArticle {
12
+ meta: string[];
13
+ tickers: string[];
14
+ lead: string | null;
15
+ facts: string[];
16
+ body: ArticleBlock[];
17
+ rawText: string;
18
+ /** The chunk the hit came from, as a section of the article; -1 when the document no longer has it. */
19
+ matchSection: number;
20
+ /** Where the reader opens: the match in a call or a filing, the top of a story. */
21
+ revealSection: number | null;
22
+ }
23
+
24
+ function kindLabel(document: CloudSearchDocument, hit: CloudSearchHit): string | null {
25
+ if (document.docType === "transcript") return "Earnings call";
26
+ if (document.docType === "filing") return hitTypeLabel(hit);
27
+ return null;
28
+ }
29
+
30
+ /**
31
+ * A search document as the reader lays it out. A news story is cleaned of
32
+ * page chrome and opens on its gist; a call keeps each speaker's turn under
33
+ * their name and a filing each part under its section, both as written, and
34
+ * both open where the search matched, as they always have.
35
+ */
36
+ export function searchArticle(document: CloudSearchDocument, hit: CloudSearchHit): SearchArticle {
37
+ const news = document.docType === "news";
38
+ const source = news ? document.chunks.find((chunk) => chunk.metadata?.source?.trim())?.metadata.source?.trim() ?? "" : "";
39
+ const blocks = parseArticle(
40
+ document.chunks.map((chunk) => ({
41
+ text: chunk.body ?? "",
42
+ heading: news ? undefined : chunkAttribution(document.docType, chunk.metadata) || undefined,
43
+ })),
44
+ { title: document.title, source, clean: news },
45
+ );
46
+ const rawText = document.chunks.map((chunk) => chunk.body ?? "").join("\n\n");
47
+ const gist = news
48
+ ? articleGist(blocks, { summary: document.chunks[0]?.metadata?.summary })
49
+ : { lead: null, facts: [], body: blocks };
50
+ const matchSection = document.chunks.findIndex((chunk) => chunk.chunkIndex === hit.chunkIndex);
51
+ const tickers = [
52
+ document.ticker,
53
+ ...(news ? listedTickers(rawText) : []),
54
+ ].filter((symbol): symbol is string => !!symbol?.trim());
55
+ return {
56
+ meta: [source, formatDetailDate(document.publishedAt || hit.publishedAt, ""), kindLabel(document, hit) ?? ""],
57
+ tickers: [...new Set(tickers)],
58
+ lead: gist.lead,
59
+ facts: gist.facts,
60
+ body: gist.body,
61
+ rawText,
62
+ matchSection,
63
+ revealSection: !news && matchSection > 0 ? matchSection : null,
64
+ };
65
+ }
@@ -1,173 +1,10 @@
1
- import { useEffect, useMemo, useRef } from "react";
2
- import type {
3
- CloudSearchDocType,
4
- CloudSearchDocument,
5
- CloudSearchDocumentChunk,
6
- CloudSearchHit,
7
- } from "../../../api-client";
1
+ import { useMemo } from "react";
2
+ import type { CloudSearchDocument, CloudSearchHit } from "../../../api-client";
8
3
  import { Button, PaneStatusBody } from "../../../components";
4
+ import { ArticleReader } from "../../../components/reader/article-reader";
9
5
  import { openUrl } from "../../../components/ui/external-link";
10
- import { useShortcut } from "../../../react/input";
11
- import { colors } from "../../../theme/colors";
12
- import {
13
- Box,
14
- ScrollBox,
15
- StyledText,
16
- Text,
17
- TextAttributes,
18
- useUiCapabilities,
19
- type ScrollBoxRenderable,
20
- } from "../../../ui";
21
- import { scrollByLines } from "../../../state/pane-scroll-registry";
22
- import { isPlainKey } from "../../../utils/keyboard";
23
- import { wrapTextLines } from "../../../utils/text-wrap";
24
- import { chunkAttribution, documentBodyWidth } from "./model";
25
- import { highlightTerms, snippetMatchTerms, type SnippetSegment } from "./snippet";
26
- import { SnippetText } from "./snippet-text";
27
-
28
- interface DocumentLine {
29
- key: string;
30
- kind: "attribution" | "body";
31
- text: string;
32
- segments?: SnippetSegment[];
33
- /** Part of the chunk the hit came from. */
34
- active: boolean;
35
- }
36
-
37
- interface DocumentLayout {
38
- lines: DocumentLine[];
39
- matchLine: number | null;
40
- }
41
-
42
- function buildLayout(
43
- document: CloudSearchDocument,
44
- hit: CloudSearchHit,
45
- width: number,
46
- ): DocumentLayout {
47
- const terms = snippetMatchTerms(hit.snippet);
48
- const lines: DocumentLine[] = [];
49
- let matchLine: number | null = null;
50
-
51
- for (const chunk of document.chunks) {
52
- const active = chunk.chunkIndex === hit.chunkIndex;
53
- if (active && matchLine === null) matchLine = lines.length;
54
-
55
- const attribution = chunkAttribution(document.docType, chunk.metadata);
56
- if (attribution) {
57
- lines.push({
58
- key: `${chunk.id}:attribution`,
59
- kind: "attribution",
60
- text: attribution,
61
- active,
62
- });
63
- }
64
- const bodyLines = wrapTextLines(chunk.body ?? "", width);
65
- for (const [index, line] of bodyLines.entries()) {
66
- lines.push({
67
- key: `${chunk.id}:${index}`,
68
- kind: "body",
69
- text: line,
70
- // Only the chunk that matched carries term highlights; marking every
71
- // occurrence in a long filing would leave nothing standing out.
72
- segments: active && terms.length > 0 ? highlightTerms(line, terms) : undefined,
73
- active,
74
- });
75
- }
76
- lines.push({ key: `${chunk.id}:gap`, kind: "body", text: "", active: false });
77
- }
78
-
79
- return { lines, matchLine };
80
- }
81
-
82
- const WRAPPED_BODY_STYLE = { display: "block" };
83
-
84
- function segmentsToStyledText(segments: readonly SnippetSegment[], color: string): StyledText {
85
- return new StyledText(segments.map((segment) => ({
86
- text: segment.text,
87
- fg: segment.marked ? colors.warning : color,
88
- attributes: segment.marked ? TextAttributes.BOLD : TextAttributes.NONE,
89
- })));
90
- }
91
-
92
- function AttributionText({ text, active }: { text: string; active: boolean }) {
93
- return (
94
- <Text
95
- fg={active ? colors.textBright : colors.textDim}
96
- attributes={TextAttributes.BOLD}
97
- >
98
- {text}
99
- </Text>
100
- );
101
- }
102
-
103
- /**
104
- * One chunk as a single paragraph the host wraps for itself. The desktop lays
105
- * boxes out on the cell grid but draws glyphs on a narrower advance, so a line
106
- * pre-wrapped to a cell count stops roughly a tenth of the pane short of the
107
- * right edge there. Only the terminal, whose cell is the glyph, can pre-wrap.
108
- */
109
- function DocumentChunkView({
110
- chunk,
111
- docType,
112
- terms,
113
- active,
114
- }: {
115
- chunk: CloudSearchDocumentChunk;
116
- docType: CloudSearchDocType;
117
- terms: readonly string[];
118
- active: boolean;
119
- }) {
120
- const attribution = chunkAttribution(docType, chunk.metadata);
121
- const body = chunk.body ?? "";
122
- const color = active ? colors.textBright : colors.text;
123
- const highlighted = active && terms.length > 0;
124
-
125
- return (
126
- <Box
127
- flexDirection="column"
128
- width="100%"
129
- paddingBottom={1}
130
- backgroundColor={active ? colors.panel : undefined}
131
- >
132
- {attribution ? <AttributionText text={attribution} active={active} /> : null}
133
- {highlighted ? (
134
- <Text
135
- wrapText
136
- width="100%"
137
- style={WRAPPED_BODY_STYLE}
138
- content={segmentsToStyledText(highlightTerms(body, terms), color)}
139
- />
140
- ) : (
141
- <Text fg={color} wrapText width="100%" style={WRAPPED_BODY_STYLE}>{body}</Text>
142
- )}
143
- </Box>
144
- );
145
- }
146
-
147
- function DocumentLineView({ line }: { line: DocumentLine }) {
148
- const background = line.active ? colors.panel : undefined;
149
- if (line.kind === "attribution") {
150
- return (
151
- <Box height={1} backgroundColor={background}>
152
- <AttributionText text={line.text} active={line.active} />
153
- </Box>
154
- );
155
- }
156
- if (line.segments) {
157
- return (
158
- <SnippetText
159
- segments={line.segments}
160
- color={colors.textBright}
161
- backgroundColor={background}
162
- />
163
- );
164
- }
165
- return (
166
- <Box height={1} backgroundColor={background}>
167
- <Text fg={line.active ? colors.textBright : colors.text}>{line.text}</Text>
168
- </Box>
169
- );
170
- }
6
+ import { searchArticle } from "./article";
7
+ import { snippetMatchTerms } from "./snippet";
171
8
 
172
9
  export function SearchDocumentView({
173
10
  hit,
@@ -175,45 +12,24 @@ export function SearchDocumentView({
175
12
  loading,
176
13
  error,
177
14
  width,
15
+ height,
178
16
  focused = false,
17
+ onNext,
18
+ onPrevious,
179
19
  }: {
180
20
  hit: CloudSearchHit;
181
21
  document: CloudSearchDocument | null;
182
22
  loading: boolean;
183
23
  error: string | null;
184
24
  width: number;
185
- /** j and k scroll a line, as in every other reader. */
25
+ height: number;
186
26
  focused?: boolean;
27
+ /** The next or previous hit in the results, or null at either end. */
28
+ onNext?: (() => void) | null;
29
+ onPrevious?: (() => void) | null;
187
30
  }) {
188
- const scrollRef = useRef<ScrollBoxRenderable | null>(null);
189
- const { nativePaneChrome } = useUiCapabilities();
190
- const bodyWidth = documentBodyWidth(width);
31
+ const article = useMemo(() => (document ? searchArticle(document, hit) : null), [document, hit]);
191
32
  const terms = useMemo(() => snippetMatchTerms(hit.snippet), [hit.snippet]);
192
- const layout = useMemo(
193
- () => (document ? buildLayout(document, hit, bodyWidth) : null),
194
- [bodyWidth, document, hit],
195
- );
196
-
197
- // Land the reader on the chunk that matched, with a little context above it.
198
- // The host wraps the same text into its own number of lines, so aim by the
199
- // share of the document above the match rather than by the counted line.
200
- useEffect(() => {
201
- const scrollBox = scrollRef.current;
202
- if (!scrollBox || layout?.matchLine == null) return;
203
- const target = nativePaneChrome && layout.lines.length > 0
204
- ? Math.round((layout.matchLine / layout.lines.length) * scrollBox.scrollHeight)
205
- : layout.matchLine;
206
- scrollBox.scrollTo(Math.max(0, target - 2));
207
- }, [layout, nativePaneChrome]);
208
-
209
- useShortcut((event) => {
210
- if (event.defaultPrevented || event.targetEditable) return;
211
- const delta = isPlainKey(event, "j") ? 1 : isPlainKey(event, "k") ? -1 : 0;
212
- if (!delta) return;
213
- event.preventDefault();
214
- event.stopPropagation();
215
- if (scrollRef.current) scrollByLines(scrollRef.current, delta);
216
- }, { enabled: focused && !!layout });
217
33
 
218
34
  if (loading && !document) {
219
35
  return (
@@ -232,25 +48,27 @@ export function SearchDocumentView({
232
48
  />
233
49
  );
234
50
  }
235
- if (!document || !layout) return null;
51
+ if (!document || !article) return null;
236
52
 
237
53
  return (
238
- // Only the left inset lives here: the scrollbar already holds the column on
239
- // the right, and padding on both sides would push the text under it.
240
- <ScrollBox ref={scrollRef} scrollY flexGrow={1} paddingLeft={1}>
241
- <Box flexDirection="column" width={nativePaneChrome ? "100%" : bodyWidth}>
242
- {nativePaneChrome
243
- ? document.chunks.map((chunk) => (
244
- <DocumentChunkView
245
- key={chunk.id}
246
- chunk={chunk}
247
- docType={document.docType}
248
- terms={terms}
249
- active={chunk.chunkIndex === hit.chunkIndex}
250
- />
251
- ))
252
- : layout.lines.map((line) => <DocumentLineView key={line.key} line={line} />)}
253
- </Box>
254
- </ScrollBox>
54
+ <ArticleReader
55
+ articleKey={`${document.docType}:${document.sourceId}`}
56
+ title={document.title || hit.title}
57
+ meta={article.meta}
58
+ tickers={article.tickers}
59
+ lead={article.lead}
60
+ facts={article.facts}
61
+ body={article.body}
62
+ rawText={article.rawText}
63
+ // Only the section that matched carries the terms; marking every
64
+ // occurrence in a long filing would leave nothing standing out.
65
+ highlight={article.matchSection >= 0 && terms.length > 0 ? { section: article.matchSection, terms } : null}
66
+ revealSection={article.revealSection}
67
+ focused={focused}
68
+ width={width}
69
+ height={height}
70
+ onNext={onNext}
71
+ onPrevious={onPrevious}
72
+ />
255
73
  );
256
74
  }
@@ -221,15 +221,6 @@ export function chunkAttribution(
221
221
  return metadata.source?.trim() || "";
222
222
  }
223
223
 
224
- /**
225
- * Columns a wrapped paragraph gets in the document view. The scroll box keeps
226
- * one column of text inset on the left, and its vertical scrollbar sits in the
227
- * last column of the pane, so those are the only two the body cannot use.
228
- */
229
- export function documentBodyWidth(width: number): number {
230
- return Math.max(20, Math.floor(width) - 2);
231
- }
232
-
233
224
  type SearchColumnId = "ticker" | "type" | "date" | "title" | "match";
234
225
 
235
226
  export interface SearchColumn extends DataTableColumn {