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,71 +1,355 @@
1
1
  import type { DataProvider } from "../types/data-provider";
2
+ import type { Quote } from "../types/financials";
2
3
  import type { TickerRecord } from "../types/ticker";
3
- import type { TickerRepository } from "../data/ticker-repository";
4
- import { resolveTickerSearch, upsertTickerFromSearchResult } from "../tickers/search";
5
- import { canonicalExchange } from "../utils/exchanges";
6
- import { resolveCliListing } from "./listing-arg";
4
+ import type { AppTickerRepositoryPort } from "../core/app-service-ports";
5
+ import { connectionHealth, GLOOM_CLOUD_HTTP_CONNECTION_ID } from "../core/connection-health";
6
+ import { mapWithConcurrency } from "../utils/concurrency";
7
+ import {
8
+ AmbiguousContractError,
9
+ AmbiguousTickerError,
10
+ resolveTickerSearch,
11
+ upsertTickerFromSearchResult,
12
+ type ResolvedTickerSearch,
13
+ } from "../tickers/search";
14
+ import { canonicalExchange, parsePublicTickerKey } from "../utils/exchanges";
15
+ import {
16
+ chosenListingNote,
17
+ ListingArgError,
18
+ listingChoiceNote,
19
+ listingReadNotes,
20
+ listingVenues,
21
+ noLongerTradingNote,
22
+ notTradedMessage,
23
+ quoteBareListing,
24
+ resolveCliListing,
25
+ savedListingName,
26
+ tradingListing,
27
+ type CliListing,
28
+ type ListingDeps,
29
+ } from "./listing-arg";
30
+ import {
31
+ describeTickerChange,
32
+ startTickerChangeLookup,
33
+ tickerChangeLine,
34
+ type CurrentListing,
35
+ type TickerChange,
36
+ type TickerChangeLookup,
37
+ } from "../tickers/ticker-changes";
38
+ import { coinElsewhereNote, savedListingCoinNote } from "./commands/crypto-hints";
7
39
 
8
40
  /** The saved ticker for a symbol (`SAN:EPA`, or `SAN` with `--exchange EPA`), saving it from search first if needed. */
9
41
  export async function resolveTickerForCli(
10
42
  symbol: string,
11
- store: TickerRepository,
43
+ store: AppTickerRepositoryPort,
12
44
  dataProvider: DataProvider,
13
45
  exchange?: string,
14
46
  ): Promise<TickerRecord> {
47
+ return (await resolveCliTicker(symbol, store, dataProvider, exchange)).ticker;
48
+ }
49
+
50
+ export interface CliTicker {
51
+ ticker: TickerRecord;
52
+ /**
53
+ * What to say beside it: the venue a bare symbol went to when it has several
54
+ * ("IEO -> BATS (other listings: IEX, BMV)"), and a listing that stopped trading.
55
+ */
56
+ notes: string[];
57
+ /** Of those, the one saying the listing stopped trading; null while it trades. */
58
+ ended: string | null;
59
+ /** The symbol changed (FB became META); when its company left it, the line leads `notes`. */
60
+ change: TickerChange | null;
61
+ /**
62
+ * A bare coin ticker (ETH) read as a listing that is not the coin, such as a
63
+ * fund named for it: "ETH is Grayscale Ethereum Mini Trust ETF, not ethereum.
64
+ * For ethereum use ETH-USD." It is also the last of `notes`.
65
+ */
66
+ coinNote: string | null;
67
+ }
68
+
69
+ export interface CliTickerOptions {
70
+ /** The command that takes one listing, for the choices a failure names: `gloomberb watchlist add Growth 2222:JPX`. */
71
+ retry?: (key: string) => string;
72
+ /** `--exchange` only fills in the symbols that name no exchange of their own, as for a list of symbols. */
73
+ ownExchangeWins?: boolean;
74
+ /** Look up whether the symbol changed (FB became META); a long list skips it. True by default. */
75
+ changes?: boolean;
76
+ /**
77
+ * Ask a listing already saved for its quote and save the name the quote
78
+ * gives, as `quote` and `portfolio show` name it; a long list skips it. True by default.
79
+ */
80
+ refreshName?: boolean;
81
+ /**
82
+ * A bare symbol several listings carry, and no quote settles, fails with the
83
+ * choice instead of going to the first listing that has a quote, for a caller
84
+ * that asks which listing is meant (the command bar's single add does).
85
+ */
86
+ askWhenAmbiguous?: boolean;
87
+ }
88
+
89
+ /**
90
+ * A bare coin ticker several companies list, none of them the coin (SOL): the
91
+ * listings to choose from in `details`, and where the coin is in `hint`, which
92
+ * is also the last line of `details`.
93
+ */
94
+ export class CoinListingError extends ListingArgError {
95
+ constructor(message: string, details: string, readonly hint: string) {
96
+ super(message, `${details}\n${hint}`);
97
+ this.name = "CoinListingError";
98
+ }
99
+ }
100
+
101
+ /** Search found no listing for the symbol: the message says so, or why (no longer trading, not on that exchange). */
102
+ export class TickerNotFoundError extends ListingArgError {
103
+ constructor(message: string) {
104
+ super(message);
105
+ this.name = "TickerNotFoundError";
106
+ }
107
+ }
108
+
109
+ /**
110
+ * `resolveTickerForCli`, saying which listing a bare symbol went to. A bare
111
+ * symbol goes where `quote` reads it: the listing its own quote is on, else,
112
+ * when no quote settles it, the first of its listings with a quote
113
+ * (`quoteBareListing`); a code several companies list asks which. A symbol
114
+ * search no longer lists, whose quote stopped long ago, is no longer trading,
115
+ * and a named exchange the symbol is not on says where it is. Those failures
116
+ * are `ListingArgError`s, with any choices in `details`.
117
+ */
118
+ export async function resolveCliTicker(
119
+ symbol: string,
120
+ store: AppTickerRepositoryPort,
121
+ dataProvider: DataProvider,
122
+ exchange?: string,
123
+ options: CliTickerOptions = {},
124
+ ): Promise<CliTicker> {
15
125
  if (!symbol.trim()) {
16
126
  throw new Error("Ticker symbol is required.");
17
127
  }
18
- const listing = await resolveCliListing(symbol, exchange, { store, dataProvider });
19
- if (listing.saved) return listing.saved;
20
- const normalized = listing.key;
128
+ const deps: ListingDeps = { store, dataProvider };
129
+ const listing = await resolveCliListing(symbol, exchange, deps, { ownExchangeWins: options.ownExchangeWins });
130
+ const read = listingReadNotes(listing);
131
+ // Looked up beside the search, so saying FB is now META costs no wait.
132
+ const changes = options.changes === false ? null : startTickerChangeLookup(dataProvider, listing.symbol, listing.exchange);
133
+ // A saved listing names what lists there; the issuer that left, if it is that one, is its old line.
134
+ if (listing.saved) {
135
+ const saved = options.refreshName === false ? listing.saved : (await nameFromListingQuote(listing.saved, store, dataProvider, null)).ticker;
136
+ return withChange(listing, changes, { ticker: saved, notes: read, ended: null }, { name: saved.metadata.name });
137
+ }
21
138
 
22
139
  const localTickers = new Map(
23
140
  (await store.loadAllTickers()).map((ticker) => [ticker.metadata.ticker.toUpperCase(), ticker] as const),
24
141
  );
25
- const resolved = await resolveTickerSearch({
26
- query: normalized,
27
- activeTicker: null,
28
- tickers: localTickers,
29
- dataProvider,
30
- });
142
+ const search = (query: string) => resolveTickerSearch({ query, activeTicker: null, tickers: localTickers, dataProvider });
143
+ let resolved: ResolvedTickerSearch | null;
144
+ let bareNote: string | null = null;
145
+ let bareQuote: Quote | null = null;
146
+ try {
147
+ resolved = await search(listing.key);
148
+ } catch (error) {
149
+ if (!(error instanceof AmbiguousTickerError) || error instanceof AmbiguousContractError || listing.exchange || options.askWhenAmbiguous) throw error;
150
+ // No quote of the bare symbol settles which listing it is: the one `quote` reads instead.
151
+ const bare = await quoteBareListing(listing, deps, { command: "quote", noun: "quote", retry: options.retry ?? null });
152
+ if (!bare) throw error;
153
+ if (bare.kind === "missing") {
154
+ const hint = coinElsewhereNote(listing.symbol, error.listings.map((key) => ({ key, name: error.listingNames[key] ?? "" })));
155
+ throw hint ? new CoinListingError(bare.message, bare.details, hint) : new ListingArgError(bare.message, bare.details);
156
+ }
157
+ resolved = await search(bare.listing.key);
158
+ bareNote = bare.note;
159
+ bareQuote = bare.quote;
160
+ }
31
161
 
32
162
  if (!resolved) {
33
- throw new Error(`No ticker match found for "${normalized}".`);
163
+ const message = await missingListingMessage(listing, deps);
164
+ const change = describeTickerChange(listing.symbol, await changes?.settle() ?? null, null);
165
+ const line = tickerChangeLine(change);
166
+ throw new TickerNotFoundError(line ? `${message} ${line}.` : message);
34
167
  }
35
-
36
168
  if (resolved.kind === "local") {
37
- return resolved.ticker;
169
+ const local = options.refreshName === false ? resolved.ticker : (await nameFromListingQuote(resolved.ticker, store, dataProvider, bareQuote)).ticker;
170
+ return withChange(listing, changes, { ticker: local, notes: [...read, ...bareNote ? [bareNote] : []], ended: null }, {
171
+ name: local.metadata.name,
172
+ });
38
173
  }
39
174
 
40
175
  const { ticker, created } = await upsertTickerFromSearchResult(store, resolved.result);
41
- return created ? nameFromListingQuote(ticker, store, dataProvider) : ticker;
176
+ const named = created ? await nameFromListingQuote(ticker, store, dataProvider, bareQuote) : { ticker, quote: bareQuote };
177
+ const saved = savedListingName(named.ticker);
178
+ const others = resolved.otherListings?.map((key) => parsePublicTickerKey(key).exchange ?? key) ?? [];
179
+ // Several companies' listings name the company it went to and theirs; one company's name its other venues.
180
+ const venueNote = bareNote ?? (others.length > 0 && saved.exchange
181
+ ? listingChoiceNote(listing.symbol, saved, await listingVenues(listing.symbol, deps).catch(() => []))
182
+ ?? chosenListingNote(listing.symbol, saved.exchange, others)
183
+ : null);
184
+ const ended = named.quote ? noLongerTradingNote(saved.label, named.quote) : null;
185
+ // Search listed it, so something trades there; its quote says whether that is the issuer that left.
186
+ const current = named.quote ? tradingListing(named.quote) : { name: named.ticker.metadata.name };
187
+ return withChange(listing, changes, {
188
+ ticker: named.ticker,
189
+ notes: [...read, venueNote, ended].filter((note): note is string => !!note),
190
+ ended,
191
+ }, current);
192
+ }
193
+
194
+ /**
195
+ * The resolution with the symbol's change, when it has one, and the coin note
196
+ * for a bare coin ticker on a listing that is not the coin: a company that left
197
+ * the symbol leads the notes, the coin note ends them. A named exchange (ETH:ARCA,
198
+ * --exchange) asked for that listing on purpose and gets no coin note, as in `quote`.
199
+ */
200
+ async function withChange(
201
+ listing: Pick<CliListing, "symbol" | "exchange">,
202
+ lookup: TickerChangeLookup | null,
203
+ resolved: Omit<CliTicker, "change" | "coinNote">,
204
+ current: CurrentListing | null | undefined,
205
+ ): Promise<CliTicker> {
206
+ const change = describeTickerChange(listing.symbol, await lookup?.settle() ?? null, current);
207
+ const line = tickerChangeLine(change);
208
+ const coinNote = listing.exchange ? null : savedListingCoinNote(listing.symbol, resolved.ticker);
209
+ return { ...resolved, notes: [...line ? [line] : [], ...resolved.notes, ...coinNote ? [coinNote] : []], change, coinNote };
210
+ }
211
+
212
+ /**
213
+ * Why search found no listing: a named exchange the symbol is not on names
214
+ * the ones it is; a symbol search no longer lists, whose quote stopped long
215
+ * ago, is no longer trading (TWTR).
216
+ */
217
+ async function missingListingMessage(listing: CliListing, deps: ListingDeps): Promise<string> {
218
+ const notTraded = await notTradedMessage(listing, deps);
219
+ if (notTraded) return notTraded;
220
+ const quote = await deps.dataProvider.getQuote(listing.request.symbol, listing.request.exchange).catch(() => null);
221
+ const ended = quote ? noLongerTradingNote(listing.key, quote) : null;
222
+ return ended ? `${ended}.` : `No ticker match found for "${listing.key}".`;
42
223
  }
43
224
 
44
225
  /**
45
226
  * Search catalogues can file a listing under another company's name, such as
46
227
  * BAE Systems' London line (BA:LSE) under Boeing. The listing's own
47
228
  * quote names the security it prices, which is the name the ticker command
48
- * shows, so a record created here takes it.
229
+ * shows, so a record created here takes it. The quote comes back with it,
230
+ * when it is that listing's.
49
231
  */
50
232
  async function nameFromListingQuote(
51
233
  ticker: TickerRecord,
52
- store: TickerRepository,
234
+ store: AppTickerRepositoryPort,
53
235
  dataProvider: DataProvider,
54
- ): Promise<TickerRecord> {
236
+ known: Quote | null,
237
+ ): Promise<{ ticker: TickerRecord; quote: Quote | null }> {
55
238
  const { metadata } = ticker;
56
239
  try {
57
- const quote = await dataProvider.getQuote(metadata.ticker, metadata.exchange);
240
+ const quote = known ?? await dataProvider.getQuote(metadata.ticker, metadata.exchange);
58
241
  const name = quote.name?.trim();
59
242
  // A quote that names no listing may be another venue's line served from cache.
60
243
  const quoteExchange = canonicalExchange(quote.listingExchangeName || quote.exchangeName);
61
- if (!name || name === metadata.name || !quoteExchange || quoteExchange !== canonicalExchange(metadata.exchange)) {
62
- return ticker;
63
- }
244
+ if (!quoteExchange || quoteExchange !== canonicalExchange(metadata.exchange)) return { ticker, quote: null };
245
+ if (!name || name === metadata.name) return { ticker, quote };
64
246
  const named: TickerRecord = { ...ticker, metadata: { ...metadata, name } };
65
247
  await store.saveTicker(named);
66
- return named;
248
+ return { ticker: named, quote };
67
249
  } catch {
68
250
  // Without a quote the catalogue name stands.
69
- return ticker;
251
+ return { ticker, quote: null };
252
+ }
253
+ }
254
+
255
+ export type CliTickerResolution =
256
+ | ({ input: string; error?: undefined } & CliTicker)
257
+ | { input: string; ticker?: undefined; error: Error };
258
+
259
+ /** Symbols looked up at once. Each is a catalogue search and a quote, so this bounds the requests in flight. */
260
+ const RESOLVE_CONCURRENCY = 8;
261
+ /** Lists of at most this many symbols say which changed; a longer one is a portfolio, not a lookup. */
262
+ const MAX_CHANGE_LOOKUPS = 10;
263
+ /** Symbols looked up again at once after requests failed, gently, as the service may be limiting the rate. */
264
+ const RETRY_CONCURRENCY = 4;
265
+ /** The data service's market requests (search, quotes), as connection health names them. */
266
+ const MARKET_OPERATION = /^(?:GET|POST) \/market\//;
267
+ /**
268
+ * Waits before each new look at the symbols that failed while requests were
269
+ * failing. The first outlasts the five seconds the router keeps an empty
270
+ * search answer; the service's rate limit is a minute's window.
271
+ */
272
+ const RETRY_WAITS_MS = [6_000, 15_000, 30_000];
273
+
274
+ /**
275
+ * Counts the data service's market requests that fail while it watches. A
276
+ * lookup reads a refused search (rate limited, offline) as no match, and a
277
+ * refused quote as a listing it cannot settle, so a symbol looked up while
278
+ * one failed may be there after all.
279
+ */
280
+ function watchFailedRequests(): { count: () => number; stop: () => void } {
281
+ const dispose = connectionHealth.hasSource(GLOOM_CLOUD_HTTP_CONNECTION_ID)
282
+ ? null
283
+ : connectionHealth.registerSource({ id: GLOOM_CLOUD_HTTP_CONNECTION_ID, name: "Gloom Cloud HTTP", kind: "api" });
284
+ const failures = new Set<string>();
285
+ const unsubscribe = connectionHealth.subscribe(() => {
286
+ const failure = connectionHealth.getSnapshot().sources.find((source) => source.id === GLOOM_CLOUD_HTTP_CONNECTION_ID)?.lastError;
287
+ if (failure && MARKET_OPERATION.test(failure.operation)) failures.add(`${failure.at}|${failure.latencyMs}|${failure.error ?? ""}`);
288
+ });
289
+ return { count: () => failures.size, stop: () => { unsubscribe(); dispose?.(); } };
290
+ }
291
+
292
+ function lookUpTickers(
293
+ symbols: readonly string[],
294
+ concurrency: number,
295
+ resolve: (symbol: string) => Promise<CliTicker>,
296
+ ): Promise<CliTickerResolution[]> {
297
+ return mapWithConcurrency(symbols, concurrency, async (input): Promise<CliTickerResolution> => {
298
+ try {
299
+ return { input, ...await resolve(input) };
300
+ } catch (error) {
301
+ return { input, error: error instanceof Error ? error : new Error(String(error)) };
302
+ }
303
+ });
304
+ }
305
+
306
+ /**
307
+ * `resolveCliTicker` for a list of symbols, several at a time; a symbol that
308
+ * fails gives its error without failing the rest. `--exchange` names the
309
+ * venue of the symbols that do not name their own. "Not found" means search
310
+ * found no listing: while the service refuses requests, the symbols that
311
+ * failed are looked up again after a pause, and any it still did not answer
312
+ * for say so.
313
+ */
314
+ export async function resolveTickersForCli(
315
+ symbols: readonly string[],
316
+ store: AppTickerRepositoryPort,
317
+ dataProvider: DataProvider,
318
+ exchange?: string,
319
+ {
320
+ retry,
321
+ askWhenAmbiguous,
322
+ onRetry,
323
+ retryWaitsMs = RETRY_WAITS_MS,
324
+ }: Pick<CliTickerOptions, "retry" | "askWhenAmbiguous"> & {
325
+ /** Told before each new look, with how many symbols and how long it waits first. */
326
+ onRetry?: (count: number, waitMs: number) => void;
327
+ retryWaitsMs?: readonly number[];
328
+ } = {},
329
+ ): Promise<CliTickerResolution[]> {
330
+ // A short list is a lookup: it says which symbols changed and refreshes saved names. A long one is a portfolio.
331
+ const changes = symbols.length <= MAX_CHANGE_LOOKUPS;
332
+ const resolve = (symbol: string) => resolveCliTicker(symbol, store, dataProvider, exchange, { retry, askWhenAmbiguous, ownExchangeWins: true, changes, refreshName: changes });
333
+ const failedRequests = watchFailedRequests();
334
+ try {
335
+ let lookups = await lookUpTickers(symbols, RESOLVE_CONCURRENCY, resolve);
336
+ let failing = failedRequests.count() > 0;
337
+ for (const waitMs of retryWaitsMs) {
338
+ const failed = lookups.filter((entry) => entry.error).map((entry) => entry.input);
339
+ if (!failing || failed.length === 0) break;
340
+ onRetry?.(failed.length, waitMs);
341
+ await new Promise((resolveWait) => setTimeout(resolveWait, waitMs));
342
+ const before = failedRequests.count();
343
+ const again = new Map((await lookUpTickers(failed, RETRY_CONCURRENCY, resolve)).map((entry) => [entry.input, entry] as const));
344
+ lookups = lookups.map((entry) => again.get(entry.input) ?? entry);
345
+ failing = failedRequests.count() > before;
346
+ }
347
+ if (!failing) return lookups;
348
+ // Still refused after the last wait: a failure may only be the refusal, so none is called not found.
349
+ return lookups.map((entry) => entry.error
350
+ ? { input: entry.input, error: new Error(`Could not look up ${entry.input}: Gloom Cloud did not answer. Try again in a minute.`) }
351
+ : entry);
352
+ } finally {
353
+ failedRequests.stop();
70
354
  }
71
355
  }
package/src/cli/types.ts CHANGED
@@ -3,6 +3,7 @@ import { AppPersistence } from "../data/app-persistence";
3
3
  import { TickerRepository } from "../data/ticker-repository";
4
4
  import { AssetDataRouter } from "../sources/provider-router";
5
5
  import type { AppServices } from "../core/app-services";
6
+ import type { CapabilityInvoker } from "../capabilities/types";
6
7
 
7
8
  export type ConfigContext = {
8
9
  config: AppConfig;
@@ -13,6 +14,8 @@ export type ConfigContext = {
13
14
 
14
15
  export type MarketContext = ConfigContext & {
15
16
  dataProvider: AssetDataRouter;
17
+ /** Charts catalog series in a report run without the plugin runtime. */
18
+ seriesCapabilities?: CapabilityInvoker;
16
19
  /** `--refresh`: prefetched data bypasses the local cache. */
17
20
  refresh?: boolean;
18
21
  };
@@ -20,6 +23,8 @@ export type MarketContext = ConfigContext & {
20
23
  export type CliServicesContext = {
21
24
  config: AppConfig;
22
25
  dataDir: string;
26
+ /** This command created the data folder: the profile had never been used. */
27
+ createdDataDir?: boolean;
23
28
  services: AppServices;
24
29
  dataProvider: AssetDataRouter;
25
30
  persistence: AppPersistence;
@@ -215,19 +215,25 @@ export function StaticXAxisLabels({
215
215
  flexDirection="row"
216
216
  position="relative"
217
217
  overflow="hidden"
218
+ // Desktop: the width the gutters beside it leave, so labels placed in
219
+ // percentages follow a resize that draws the chart at a new size
220
+ // between renders.
221
+ style={isDesktop ? { flex: "1 1 0px", width: "auto", minWidth: 0 } : undefined}
218
222
  data-gloom-role="chart-time-axis"
219
223
  data-gloom-label={(visiblePositionedLabels.length > 0
220
224
  ? visiblePositionedLabels.map((entry) => entry.label)
221
225
  : visibleLabels).join(" ")}
222
226
  >
223
227
  {visiblePositionedLabels.length > 0 && (isDesktop || visibleLabels.length === 0) ? (
224
- <Box position="absolute" left={0} top={0} width={width} height={1}>
228
+ <Box position="absolute" left={0} top={0} width={width} height={1} style={isDesktop ? { width: "100%" } : undefined}>
225
229
  {positionedPlacements.map(({ entry, index, edgeStyle }) => {
226
230
  return (
227
231
  <Text
228
232
  key={`${entry.label}:${entry.ratio}:${index}`}
229
233
  fg={color}
230
234
  selectable={false}
235
+ // The label against the right edge, which a floating pane's resize grip may cover.
236
+ data-gloom-edge={"right" in edgeStyle ? "end" : undefined}
231
237
  style={{
232
238
  position: "absolute",
233
239
  top: 0,
@@ -244,7 +250,12 @@ export function StaticXAxisLabels({
244
250
  ) : (
245
251
  <Box width={width} height={1} flexDirection="row">
246
252
  {visibleLabels.map((label, index) => (
247
- <Box key={`${label}:${index}`} width={segmentWidths[index]} overflow="hidden">
253
+ <Box
254
+ key={`${label}:${index}`}
255
+ width={segmentWidths[index]}
256
+ overflow="hidden"
257
+ data-gloom-edge={index === visibleLabels.length - 1 && visibleLabels.length > 1 ? "end-segment" : undefined}
258
+ >
248
259
  <Text fg={color}>{flowText[index]}</Text>
249
260
  </Box>
250
261
  ))}
@@ -331,7 +342,7 @@ export function StaticXMarkerOverlay({
331
342
 
332
343
  if (nativePaneChrome) {
333
344
  return (
334
- <Box position="absolute" left={0} top={0} width={width} height={height}>
345
+ <Box position="absolute" left={0} top={0} width={width} height={height} style={{ width: "100%", height: "100%" }}>
335
346
  {visibleMarkers.map((marker) => (
336
347
  <Box
337
348
  key={marker.id}
@@ -7,8 +7,10 @@ import { isVerticalWheelDirection } from "./panel-gestures";
7
7
  import { type ChartToolSpan, CHART_DRAWING_COLORS, isDrawingTool, type ChartDrawing } from "./tools";
8
8
  import { ChartDrawingStore, NO_DRAWINGS } from "./drawing-store";
9
9
  import { CompositeLegend } from "./legend";
10
+ import { CompositeCrosshairReadout } from "./crosshair-readout";
10
11
  import { ChartToolbar, CHART_TOOLBAR_WIDTH } from "./toolbar";
11
- import { AsciiText, Box, ChartSurface, Text, useUiCapabilities } from "../../../ui";
12
+ import { AsciiText, Box, ChartSurface, Text, useUiCapabilities, type BoxRenderable } from "../../../ui";
13
+ import { useLiveStretch } from "../../../ui/live-stretch";
12
14
  import { useOptionalPaneInstanceId } from "../../../state/app/context";
13
15
  import { useThemeColors, useThemeId } from "../../../theme/theme-context";
14
16
  import { themedSeriesColor, themeSeriesColors } from "../../../theme/series-colors";
@@ -16,12 +18,13 @@ import { assignSeriesLineCues } from "./series-cues";
16
18
  import { chartSurfaceBackground, usePaneSurface } from "../../layout/pane/surface";
17
19
  import { CHART_WATERMARK_ROLE } from "../../../utils/screenshot-watermark";
18
20
  import type { ResolvedSeries } from "../../../time-series/types";
21
+ import { isIntradayResolution } from "../../../time-series/resolution";
19
22
  import { downsampleCompositeChartScene } from "./downsample";
20
23
  import { reuseResolvedSeriesList } from "./panel-series";
21
24
  import { consumeChartMouseEvent, type ChartMouseEvent } from "../core/pointer";
22
25
  import { useShowChartTextFallback } from "../native/use-chart-text-fallback";
23
26
  import { StaticXAxisLabels, StaticXMarkerLabels, StaticXMarkerOverlay } from "./axis-overlays";
24
- import { formatCompositeTimeAxisDate } from "./format";
27
+ import { formatCompositeCursorAxisDate } from "./format";
25
28
  import { resolveCompositeWheelPan, resolveCompositeWheelZoom } from "./interactions";
26
29
  import { COMPOSITE_RIGHT_OFFSET_RATIO } from "./time-scale";
27
30
  import {
@@ -59,6 +62,15 @@ function chartWatermarkScale(plotWidthPx: number, plotHeightPx: number): number
59
62
 
60
63
  const NO_X_MARKERS: readonly CompositeChartXMarker[] = [];
61
64
 
65
+ /**
66
+ * Desktop: the rows below the plot span the chart's box and their labels the
67
+ * width the gutters leave, so when a resize draws the box at a new size
68
+ * between renders, or CSS sizes it to the box it sits in (`useLiveStretch`),
69
+ * they follow it by CSS. Otherwise they are the size the cells give them.
70
+ */
71
+ const DESKTOP_FULL_ROW = { width: "100%" } as const;
72
+ const DESKTOP_PLOT_COLUMN = { flex: "1 1 0px", width: "auto", minWidth: 0 } as const;
73
+
62
74
  /** Default-palette series in the theme's own palette, where it has one; the same list otherwise. */
63
75
  function useThemedSeriesList(list: ResolvedSeries[], themeId: string): ResolvedSeries[];
64
76
  function useThemedSeriesList(list: ResolvedSeries[] | undefined, themeId: string): ResolvedSeries[] | undefined;
@@ -416,10 +428,23 @@ function ThemedCompositeChart({
416
428
  ? buildCompositeViewportTimeAxisLayout(effectiveViewport, plotWidth)
417
429
  : null;
418
430
 
431
+ // On the desktop the chart takes the box it sits in (a fraction of a cell
432
+ // past its cells) and follows a resize by CSS where the boxes above it do;
433
+ // elsewhere, while a resize has the pane ahead of this size, the chart's
434
+ // box takes the size it will render at, the plot takes what the gutters
435
+ // leave, and its bitmap stretches with it until the chart renders there.
436
+ const rootRef = useRef<BoxRenderable | null>(null);
437
+ useLiveStretch(rootRef, totalWidth, totalHeight);
438
+ // Overlays over the plot keep the gutters around it rather than its size.
439
+ const plotInsetStyle = isDesktopWeb
440
+ ? { width: "auto", height: "auto", right: `calc(${rightPadding} * var(--cell-w))`, bottom: `calc(${timeAxisRows + xMarkerRows} * var(--cell-h))` }
441
+ : undefined;
442
+
419
443
  if (!scene) {
420
444
  const emptyPlotHeight = Math.max(0, totalHeight - legendRows - timeAxisRows - xMarkerRows);
421
445
  return (
422
446
  <Box
447
+ ref={rootRef}
423
448
  flexDirection="column"
424
449
  width={totalWidth}
425
450
  height={totalHeight}
@@ -443,11 +468,17 @@ function ThemedCompositeChart({
443
468
  />
444
469
  ) : null}
445
470
  {emptyPlotHeight > 0 ? (
446
- <Box flexDirection="row" width={totalWidth} height={emptyPlotHeight}>
471
+ <Box
472
+ flexDirection="row"
473
+ width={totalWidth}
474
+ height={emptyPlotHeight}
475
+ style={isDesktopWeb ? { width: "100%", flex: "1 1 0px", height: "auto", minHeight: 0 } : undefined}
476
+ >
447
477
  {leftPadding > 0 ? <Box width={leftPadding} /> : null}
448
478
  <ChartSurface
449
479
  width={plotWidth}
450
480
  height={emptyPlotHeight}
481
+ style={isDesktopWeb ? { ...DESKTOP_PLOT_COLUMN, height: "auto", alignSelf: "stretch" } : undefined}
451
482
  alignItems="center"
452
483
  justifyContent="center"
453
484
  onMouseScroll={interactive && navigable && navigationFrame ? handleEmptyMouseScroll : undefined}
@@ -462,7 +493,7 @@ function ThemedCompositeChart({
462
493
  </Box>
463
494
  ) : null}
464
495
  {emptyTimeAxisLayout ? (
465
- <Box flexDirection="row" width={totalWidth} height={1}>
496
+ <Box flexDirection="row" width={totalWidth} height={1} style={isDesktopWeb ? DESKTOP_FULL_ROW : undefined}>
466
497
  {leftPadding > 0 ? <Box width={leftPadding} /> : null}
467
498
  <StaticXAxisLabels
468
499
  labels={[emptyTimeAxisLayout.text]}
@@ -477,6 +508,15 @@ function ThemedCompositeChart({
477
508
  );
478
509
  }
479
510
 
511
+ const showToolbar = interactive && navigable && plotWidth > CHART_TOOLBAR_WIDTH + 4;
512
+ // On the desktop and the web the crosshair carries every series' value
513
+ // beside it, and the legend keeps the latest ones. The terminal's legend
514
+ // reads out the cursor, as the cell plot has no room for a box over it.
515
+ const showReadout = isDesktopWeb && interactive && showLegend && !xAxis && scene.cursorDate !== null;
516
+ // Bars shorter than a day carry a time of day the cursor reads out.
517
+ const intradayBars = scene.timeZone !== undefined || visibleSeries.some((entry) => (
518
+ !!entry.historyResolution && isIntradayResolution(entry.historyResolution)
519
+ ));
480
520
  const timeAxisCursorColumn = scene.cursorXRatio === null
481
521
  ? null
482
522
  : scene.cursorXRatio * Math.max(plotWidth - 1, 0);
@@ -486,23 +526,25 @@ function ThemedCompositeChart({
486
526
  const timeAxisCursorLabel = xAxis?.formatCursor && scene.cursorXRatio !== null
487
527
  ? xAxis.formatCursor(scene.cursorXRatio)
488
528
  : scene.cursorDate
489
- ? formatCompositeTimeAxisDate(scene.cursorDate, scene.startTime, scene.endTime, scene.timeZone)
529
+ ? formatCompositeCursorAxisDate(scene.cursorDate, scene.startTime, scene.endTime, scene.timeZone, intradayBars)
490
530
  : null;
491
531
  // The crosshair labels the moving end, so the axis only adds the anchor.
492
532
  const timeAxisMarkers = toolSpan
493
533
  ? [{
494
534
  ratio: toolSpan.startXRatio,
495
- label: formatCompositeTimeAxisDate(
535
+ label: formatCompositeCursorAxisDate(
496
536
  new Date(toolSpan.startTime),
497
537
  scene.startTime,
498
538
  scene.endTime,
499
539
  scene.timeZone,
540
+ intradayBars,
500
541
  ),
501
542
  color: toolSpan.color,
502
543
  }]
503
544
  : undefined;
504
545
  return (
505
546
  <Box
547
+ ref={rootRef}
506
548
  flexDirection="column"
507
549
  width={totalWidth}
508
550
  height={totalHeight}
@@ -510,10 +552,13 @@ function ThemedCompositeChart({
510
552
  // The tool overlay anchors here; without it the desktop pins it to the page.
511
553
  position="relative"
512
554
  data-gloom-role="composite-chart"
555
+ // Where the view and the loaded bars start and end, in epoch ms, for checks that move it.
556
+ data-gloom-view={effectiveViewport ? `${effectiveViewport.start.getTime()}:${effectiveViewport.end.getTime()}` : undefined}
557
+ data-gloom-data={navigationFrame ? `${navigationFrame.dataStart}:${navigationFrame.dataEnd}` : undefined}
513
558
  >
514
559
  {showLegend ? (
515
560
  <CompositeLegend
516
- scene={scene}
561
+ scene={showReadout ? baseScene : scene}
517
562
  series={visibleLegendSeries}
518
563
  visibleSeriesIds={visibleSeriesIds}
519
564
  lineCues={lineCues}
@@ -529,7 +574,21 @@ function ThemedCompositeChart({
529
574
  keyboardIndex={legendKeyboardIndex}
530
575
  />
531
576
  ) : null}
532
- {interactive && navigable && plotWidth > CHART_TOOLBAR_WIDTH + 4 ? (
577
+ {showReadout ? (
578
+ <CompositeCrosshairReadout
579
+ scene={scene}
580
+ series={visibleLegendSeries}
581
+ visibleSeriesIds={visibleSeriesIds}
582
+ lineCues={lineCues}
583
+ formatValue={formatValue}
584
+ colors={resolvedColors}
585
+ plotWidth={plotWidth}
586
+ left={leftPadding}
587
+ right={rightPadding}
588
+ top={legendRows + (showToolbar ? 1 : 0)}
589
+ />
590
+ ) : null}
591
+ {showToolbar ? (
533
592
  <ChartToolbar
534
593
  armedTool={armedTool}
535
594
  isDesktopWeb={isDesktopWeb}
@@ -605,6 +664,7 @@ function ThemedCompositeChart({
605
664
  zIndex={5}
606
665
  alignItems="center"
607
666
  justifyContent="center"
667
+ style={plotInsetStyle}
608
668
  data-gloom-role={CHART_WATERMARK_ROLE}
609
669
  >
610
670
  <AsciiText text="Gloomberb" font="wordmark" scale={watermarkScale} color={resolvedColors.textDim} />
@@ -618,7 +678,7 @@ function ThemedCompositeChart({
618
678
  width={plotWidth}
619
679
  height={plotHeight}
620
680
  zIndex={12}
621
- style={isDesktopWeb ? { pointerEvents: "none" } : undefined}
681
+ style={isDesktopWeb ? { ...plotInsetStyle, pointerEvents: "none" } : undefined}
622
682
  >
623
683
  <StaticXMarkerOverlay
624
684
  markers={xMarkers}
@@ -629,7 +689,7 @@ function ThemedCompositeChart({
629
689
  </Box>
630
690
  ) : null}
631
691
  {timeAxisLayout ? (
632
- <Box flexDirection="row" width={totalWidth} height={1}>
692
+ <Box flexDirection="row" width={totalWidth} height={1} style={isDesktopWeb ? DESKTOP_FULL_ROW : undefined}>
633
693
  {leftPadding > 0 ? <Box width={leftPadding} /> : null}
634
694
  <StaticXAxisLabels
635
695
  labels={xAxis?.ticks ? [] : xAxis?.labels ? [...xAxis.labels] : [timeAxisLayout.text]}
@@ -647,7 +707,7 @@ function ThemedCompositeChart({
647
707
  </Box>
648
708
  ) : null}
649
709
  {xMarkerRows > 0 ? (
650
- <Box flexDirection="row" width={totalWidth} height={1}>
710
+ <Box flexDirection="row" width={totalWidth} height={1} style={isDesktopWeb ? DESKTOP_FULL_ROW : undefined}>
651
711
  {leftPadding > 0 ? <Box width={leftPadding} /> : null}
652
712
  <StaticXMarkerLabels
653
713
  markers={xMarkers}