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,8 +1,11 @@
1
1
  import type { AppConfig } from "../../../../types/config";
2
2
  import type { CliCommandContext } from "../../../../types/plugin";
3
- import { parseListingArg, type SavedListingName } from "../../../../cli/listing-arg";
3
+ import { parseListingArg } from "../../../../cli/listing-arg";
4
4
  import { findPortfolio, isManualPortfolio } from "../mutations";
5
5
  import { CASH_SYMBOL } from "../allocation";
6
+ import { findNamedCollection } from "../../../../portfolio/collection-name";
7
+
8
+ export { listingFields } from "../../../../cli/listing-arg";
6
9
 
7
10
  /** A command error with a hint printed under it. */
8
11
  export class PortfolioCliError extends Error {
@@ -21,9 +24,23 @@ export function failPortfolioCommand(ctx: CliCommandContext, error: unknown, fal
21
24
  return ctx.fail(fallback);
22
25
  }
23
26
 
24
- /** What every collection command reports about the listing it changed, as JSON and as the sentence's subject. */
25
- export function listingFields(saved: Pick<SavedListingName, "key" | "symbol" | "exchange" | "name">) {
26
- return { listing: saved.key, symbol: saved.symbol, exchange: saved.exchange || null, name: saved.name };
27
+ /**
28
+ * The portfolio or watchlist the leading arguments name, and the arguments
29
+ * after it. The first argument is the name (quoted when it has spaces); an
30
+ * unquoted name with spaces still works, as the longest leading run of
31
+ * arguments that names a collection. Null when none does, so a symbol is never
32
+ * read as part of a name.
33
+ */
34
+ export function takeCollectionName<T extends { id: string; name: string }>(
35
+ args: readonly string[],
36
+ collections: readonly T[],
37
+ ): { collection: T; rest: string[] } | null {
38
+ for (let length = args.length; length >= 1; length -= 1) {
39
+ const name = args.slice(0, length).join(" ");
40
+ const collection = findNamedCollection(collections, name);
41
+ if (collection) return { collection, rest: args.slice(length) };
42
+ }
43
+ return null;
27
44
  }
28
45
 
29
46
  export function parseFiniteNumber(rawValue: string | undefined, label: string): number {
@@ -2,25 +2,45 @@ import { saveConfig } from "../../../../data/config/store";
2
2
  import { withConfigData, withMarketData } from "../../../../cli/scoped-context";
3
3
  import { countCollectionTickers, findWatchlist } from "../../../../cli/helpers";
4
4
  import { slugifyName } from "../../../../utils/slugify";
5
- import { resolveTickerForCli } from "../../../../cli/ticker-resolution";
5
+ import { resolveCliTicker } from "../../../../cli/ticker-resolution";
6
6
  import { takeOption } from "../../../../cli/commands/command-utils";
7
- import { EXCHANGE_OPTION, loadSavedListing, requireListingArg, savedListingName } from "../../../../cli/listing-arg";
7
+ import { EXCHANGE_OPTION, ListingArgError, loadSavedListing, requireListingArg, savedListingName } from "../../../../cli/listing-arg";
8
8
  import {
9
9
  cliStyles,
10
10
  renderSection,
11
11
  renderStats,
12
12
  renderTable,
13
13
  } from "../../../../utils/cli-output";
14
+ import type { AppConfig } from "../../../../types/config";
14
15
  import type { CliCommandContext, CliCommandDef } from "../../../../types/plugin";
16
+ import type { Watchlist } from "../../../../types/ticker";
17
+ import type { ConfigContext, MarketContext } from "../../../../cli/types";
15
18
  import {
16
19
  addTickerToWatchlist,
17
20
  deleteWatchlist as deleteWatchlistConfig,
18
21
  removeTickerFromWatchlist as removeWatchlistMembership,
19
22
  } from "../mutations";
20
23
  import { showCollection } from "./render";
21
- import { listingFields } from "./shared";
24
+ import { listingFields, takeCollectionName } from "./shared";
25
+ import { addSymbols, FILE_OPTION, printSymbolRows, removeSymbols, requireSymbolList, retryNotice, SYMBOL_LIST_HELP } from "./bulk-symbols";
22
26
  import { CLI_COMMAND_GROUPS } from "../../../../cli/help";
23
27
 
28
+ const ADD_USAGE = "Usage: gloomberb watchlist add <watchlist> <symbols...> [--file <path>]";
29
+ const REMOVE_USAGE = "Usage: gloomberb watchlist remove <watchlist> <symbols...> [--file <path>]";
30
+
31
+ /** The watchlist the leading arguments name and the symbols after it; fails naming the watchlists there are. */
32
+ function requireWatchlistArgs(config: AppConfig, args: readonly string[], usage: string, ctx: CliCommandContext): { watchlist: Watchlist; rest: string[] } {
33
+ if (args.length === 0) ctx.fail(usage);
34
+ const match = takeCollectionName(args, config.watchlists);
35
+ if (!match) {
36
+ ctx.fail(
37
+ `Watchlist "${args[0]}" was not found.`,
38
+ config.watchlists.length > 0 ? `Watchlists: ${config.watchlists.map((entry) => entry.name).join(", ")}` : undefined,
39
+ );
40
+ }
41
+ return { watchlist: match.collection, rest: match.rest };
42
+ }
43
+
24
44
  async function createWatchlist(name: string, ctx: CliCommandContext) {
25
45
  await withConfigData(ctx, async ({ config }) => {
26
46
  const trimmedName = name.trim();
@@ -58,47 +78,83 @@ async function deleteWatchlist(name: string, ctx: CliCommandContext) {
58
78
  });
59
79
  }
60
80
 
61
- async function addTickerToWatchlistCommand(watchlistName: string, symbol: string, exchange: string | undefined, ctx: CliCommandContext) {
62
- await withMarketData(ctx, async ({ config, store, dataProvider }) => {
63
- const watchlist = findWatchlist(config, watchlistName);
64
- if (!watchlist) ctx.fail(`Watchlist "${watchlistName}" was not found.`);
65
-
66
- try {
67
- const ticker = await resolveTickerForCli(symbol, store, dataProvider, exchange);
68
- const result = addTickerToWatchlist(ticker, watchlist.id);
69
- // Name the listing that was stored: SAN:EPA is not the SAN that a bare SAN means.
70
- const saved = savedListingName(ticker);
71
- const data = { changed: result.changed, ...listingFields(saved), watchlist: watchlist.name };
72
- if (!result.changed) {
73
- ctx.printResult({ data }, { text: () => cliStyles.warning(`${saved.label} is already in "${watchlist.name}".`) });
74
- return;
75
- }
76
-
77
- await store.saveTicker(result.ticker);
78
- ctx.printResult({ data }, { text: () => cliStyles.success(`Added ${saved.label} to "${watchlist.name}".`) });
79
- } catch (error) {
80
- ctx.fail(error instanceof Error ? error.message : `Failed to add ${symbol} to "${watchlist.name}".`);
81
+ async function addTickerToWatchlistCommand(watchlist: Watchlist, symbol: string, exchange: string | undefined, ctx: CliCommandContext, { store, dataProvider }: MarketContext) {
82
+ try {
83
+ // A bare symbol is stored on the listing `quote` reads it as, and the notes say which.
84
+ const { ticker, notes, change } = await resolveCliTicker(symbol, store, dataProvider, exchange, {
85
+ retry: (key) => `gloomberb watchlist add ${watchlist.name} ${key}`,
86
+ });
87
+ const result = addTickerToWatchlist(ticker, watchlist.id);
88
+ // Name the listing that was stored: SAN:EPA is not the SAN that a bare SAN means.
89
+ const saved = savedListingName(ticker);
90
+ const data = { changed: result.changed, ...listingFields(saved), watchlist: watchlist.name, ...change ? { tickerChange: change } : {} };
91
+ const warnings = notes.length > 0 ? notes : undefined;
92
+ if (!result.changed) {
93
+ ctx.printResult({ data, warnings }, { text: () => cliStyles.warning(`${saved.label} is already in "${watchlist.name}".`) });
94
+ return;
81
95
  }
96
+
97
+ await store.saveTicker(result.ticker);
98
+ ctx.printResult({ data, warnings }, { text: () => cliStyles.success(`Added ${saved.label} to "${watchlist.name}".`) });
99
+ } catch (error) {
100
+ ctx.fail(
101
+ error instanceof Error ? error.message : `Failed to add ${symbol} to "${watchlist.name}".`,
102
+ error instanceof ListingArgError ? error.details : undefined,
103
+ );
104
+ }
105
+ }
106
+
107
+ async function addToWatchlistCommand(args: string[], file: string | undefined, exchange: string | undefined, ctx: CliCommandContext) {
108
+ await withMarketData(ctx, async (market) => {
109
+ const { watchlist, rest } = requireWatchlistArgs(market.config, args, ADD_USAGE, ctx);
110
+ const list = await requireSymbolList(ctx, rest, file, ADD_USAGE);
111
+ if (list.single) {
112
+ await addTickerToWatchlistCommand(watchlist, list.single, exchange, ctx, market);
113
+ return;
114
+ }
115
+ const rows = await addSymbols({
116
+ symbols: list.symbols,
117
+ exchange,
118
+ store: market.store,
119
+ dataProvider: market.dataProvider,
120
+ onRetry: retryNotice(ctx),
121
+ retry: (key) => `gloomberb watchlist add ${watchlist.name} ${key}`,
122
+ add: (ticker) => addTickerToWatchlist(ticker, watchlist.id),
123
+ });
124
+ printSymbolRows(ctx, rows, { verb: "add", collection: { kind: "watchlist", name: watchlist.name }, repeated: list.repeated });
82
125
  });
83
126
  }
84
127
 
85
- async function removeTickerFromWatchlist(watchlistName: string, symbol: string, exchange: string | undefined, ctx: CliCommandContext) {
128
+ async function removeTickerFromWatchlist(watchlist: Watchlist, symbol: string, exchange: string | undefined, ctx: CliCommandContext, { store }: ConfigContext) {
86
129
  // SAN:EPA and SAN --exchange EPA name the stored listing, which a bare SAN may hold under another venue.
87
130
  const listing = await requireListingArg(symbol, exchange, ctx);
88
- await withConfigData(ctx, async ({ config, store }) => {
89
- const watchlist = findWatchlist(config, watchlistName);
90
- if (!watchlist) ctx.fail(`Watchlist "${watchlistName}" was not found.`);
131
+ const ticker = await loadSavedListing(store, listing);
132
+ if (!ticker) ctx.fail(`Ticker "${listing.key}" was not found in your local data.`);
133
+ const saved = savedListingName(ticker);
134
+ const result = removeWatchlistMembership(ticker, watchlist.id);
135
+ if (!result.changed) ctx.fail(`${saved.key} is not in "${watchlist.name}".`);
91
136
 
92
- const ticker = await loadSavedListing(store, listing);
93
- if (!ticker) ctx.fail(`Ticker "${listing.key}" was not found in your local data.`);
94
- const saved = savedListingName(ticker);
95
- const result = removeWatchlistMembership(ticker, watchlist.id);
96
- if (!result.changed) ctx.fail(`${saved.key} is not in "${watchlist.name}".`);
137
+ await store.saveTicker(result.ticker);
138
+ ctx.printResult({ data: { changed: true, ...listingFields(saved), watchlist: watchlist.name } }, {
139
+ text: () => cliStyles.success(`Removed ${saved.label} from "${watchlist.name}".`),
140
+ });
141
+ }
97
142
 
98
- await store.saveTicker(result.ticker);
99
- ctx.printResult({ data: { changed: true, ...listingFields(saved), watchlist: watchlist.name } }, {
100
- text: () => cliStyles.success(`Removed ${saved.label} from "${watchlist.name}".`),
143
+ async function removeFromWatchlistCommand(args: string[], file: string | undefined, exchange: string | undefined, ctx: CliCommandContext) {
144
+ await withConfigData(ctx, async (context) => {
145
+ const { watchlist, rest } = requireWatchlistArgs(context.config, args, REMOVE_USAGE, ctx);
146
+ const list = await requireSymbolList(ctx, rest, file, REMOVE_USAGE);
147
+ if (list.single) {
148
+ await removeTickerFromWatchlist(watchlist, list.single, exchange, ctx, context);
149
+ return;
150
+ }
151
+ const rows = await removeSymbols({
152
+ symbols: list.symbols,
153
+ exchange,
154
+ store: context.store,
155
+ remove: (ticker) => removeWatchlistMembership(ticker, watchlist.id),
101
156
  });
157
+ printSymbolRows(ctx, rows, { verb: "remove", collection: { kind: "watchlist", name: watchlist.name }, repeated: list.repeated });
102
158
  });
103
159
  }
104
160
 
@@ -154,16 +210,29 @@ export const watchlistCliCommand: CliCommandDef = {
154
210
  "watchlist show <name>",
155
211
  "watchlist create <name>",
156
212
  "watchlist delete <name>",
157
- "watchlist add <watchlist> <symbol>",
158
- "watchlist remove <watchlist> <symbol>",
213
+ "watchlist add <watchlist> <symbols...> [--file <path>]",
214
+ "watchlist remove <watchlist> <symbols...> [--file <path>]",
159
215
  ],
160
- options: [EXCHANGE_OPTION],
161
- examples: ["watchlist show Growth", "watchlist create Growth", "watchlist add Growth NVDA", "watchlist add Growth SAN:EPA"],
216
+ options: [EXCHANGE_OPTION, FILE_OPTION],
217
+ examples: [
218
+ "watchlist show Growth",
219
+ "watchlist create Growth",
220
+ "watchlist add Growth NVDA",
221
+ "watchlist add Growth SAN:EPA",
222
+ "watchlist add Energy hyperliquid:xyz:BRENTOIL",
223
+ "watchlist add Growth NVDA AMD,AVGO",
224
+ "watchlist add Growth --file holdings.csv",
225
+ "watchlist show Growth --csv",
226
+ ],
227
+ sections: [SYMBOL_LIST_HELP],
162
228
  },
163
229
  execute: async (rawArgs, ctx) => {
164
230
  const args = [...rawArgs];
165
231
  const exchange = takeOption(args, "--exchange");
232
+ const hasFile = args.some((arg) => arg === "--file" || arg.startsWith("--file="));
233
+ const file = hasFile ? takeOption(args, "--file") ?? "" : undefined;
166
234
  const action = args[0];
235
+ if (file != null && action !== "add" && action !== "remove") ctx.fail(`--file is an option of watchlist add and remove, not watchlist ${action ?? "list"}.`, ADD_USAGE);
167
236
 
168
237
  if (!action || action === "list") {
169
238
  await listWatchlists(ctx);
@@ -192,21 +261,26 @@ export const watchlistCliCommand: CliCommandDef = {
192
261
  }
193
262
 
194
263
  if (action === "add") {
195
- const symbol = args.at(-1);
196
- const name = args.slice(1, -1).join(" ");
197
- if (!name || !symbol) ctx.fail("Usage: gloomberb watchlist add <watchlist> <ticker>");
198
- await addTickerToWatchlistCommand(name!, symbol!, exchange, ctx);
264
+ await addToWatchlistCommand(args.slice(1), file, exchange, ctx);
199
265
  return;
200
266
  }
201
267
 
202
268
  if (action === "remove") {
203
- const symbol = args.at(-1);
204
- const name = args.slice(1, -1).join(" ");
205
- if (!name || !symbol) ctx.fail("Usage: gloomberb watchlist remove <watchlist> <ticker>");
206
- await removeTickerFromWatchlist(name!, symbol!, exchange, ctx);
269
+ await removeFromWatchlistCommand(args.slice(1), file, exchange, ctx);
207
270
  return;
208
271
  }
209
272
 
273
+ if (action === "import") {
274
+ // A list of symbols is what add reads; say how, with the user's own list and file.
275
+ const rest = args.slice(1);
276
+ const path = /\.\w+$/.test(rest.at(-1) ?? "") ? rest.at(-1)! : null;
277
+ const name = (path ? rest.slice(0, -1) : rest).join(" ") || "<watchlist>";
278
+ ctx.fail(
279
+ `watchlist has no import. To add the symbols in ${path ?? "a file"}, run: gloomberb watchlist add ${/\s/.test(name) ? `"${name}"` : name} --file ${path ?? "<path>"}`,
280
+ ADD_USAGE,
281
+ );
282
+ }
283
+
210
284
  await showCollection(args.join(" "), ctx);
211
285
  },
212
286
  };
@@ -1,14 +1,14 @@
1
1
  // Public API: gloomberb/components re-exports getColumnValue, getSortValue and
2
2
  // ColumnContext from here, so external plugins depend on their names and shapes.
3
3
  import { comparablePriceEarnings, formatPriceEarnings } from "../../../utils/price-earnings";
4
- import { convertMarketCapitalization } from "../../../utils/market-capitalization";
4
+ import { convertMarketCapitalization, listedMarketCapitalization } from "../../../utils/market-capitalization";
5
5
  import type { ColumnConfig } from "../../../types/config";
6
6
  import type { AnalystResearchData, CorporateActionsData, MarketState, TickerFinancials } from "../../../types/financials";
7
7
  import type { EarningsEvent } from "../../../types/data-provider";
8
8
  import type { TickerRecord } from "../../../types/ticker";
9
- import { priceColor } from "../../../theme/colors";
9
+ import { colors, priceColor } from "../../../theme/colors";
10
10
  import { formatQuoteAgeWithSource, resolveQuoteAgeTimestamp } from "../../../market-data/quotes/time";
11
- import { formatShortDate, parseDisplayDate, type ShortDateOptions } from "../../../utils/datetime-format";
11
+ import { formatFeedTime, formatShortDate, parseDisplayDate, type ShortDateOptions } from "../../../utils/datetime-format";
12
12
  import { convertCurrency, formatCompact, formatCompactAmount, formatNumber, formatPercentRaw } from "../../../utils/format";
13
13
  import {
14
14
  formatMarketCost,
@@ -31,6 +31,9 @@ import {
31
31
  type ActiveQuoteDisplay,
32
32
  } from "../../../market-data/market/status";
33
33
  import { formatOptionTicker } from "../../../utils/options";
34
+ import { classifyInstrumentType } from "../../../tickers/instrument-kind";
35
+ import { perpetualDisplaySymbol, perpetualListing } from "../../../tickers/perpetual-listing";
36
+ import { currentListingName } from "../../../tickers/listing-name";
34
37
  import { PRICE_SPARKLINE_COLUMN_ID } from "../../../components/price-sparkline/view";
35
38
  import { followLiveSparklinePrice, resolveSparklineHistory, sparklineValues } from "../../../components/price-sparkline/model";
36
39
  import {
@@ -49,7 +52,12 @@ import {
49
52
  portfolioPnlPercent,
50
53
  signedPositionDirection,
51
54
  type PortfolioPositionPnl,
52
- } from "./position-metrics";
55
+ } from "../../../portfolio/position-metrics";
56
+ import {
57
+ getPortfolioValuationDisplay,
58
+ getPortfolioValuationTime,
59
+ type PortfolioValuationBasis,
60
+ } from "../../../portfolio/valuation-basis";
53
61
  import { isFiniteNumber } from "../../../utils/guards";
54
62
  import {
55
63
  allocationFigures,
@@ -67,6 +75,8 @@ export interface ColumnContext {
67
75
  exchangeRates: Map<string, number>;
68
76
  /** Clock for quote age (per second while shown) and day-based columns. */
69
77
  now: number;
78
+ /** What market values, P&L, weights and the day's move are priced at; the latest print when absent. */
79
+ valuationBasis?: PortfolioValuationBasis;
70
80
  /**
71
81
  * The total a portfolio's weights divide by: its priced holdings at net
72
82
  * market value plus its cash (see allocation.ts). It may trail the rows by
@@ -79,6 +89,35 @@ export interface ColumnContext {
79
89
  analystResearch?: Map<string, AnalystResearchData | null>;
80
90
  corporateActions?: Map<string, CorporateActionsData | null>;
81
91
  earningsEvents?: Map<string, EarningsEvent | null>;
92
+ /** Each row's stock perpetual by ticker, null for none; a row is missing while its lookup loads. */
93
+ perpetuals?: ReadonlyMap<string, ListedPerpetual | null>;
94
+ /** Moves whenever `perpetuals` does. */
95
+ perpetualsVersion?: number;
96
+ }
97
+
98
+ /** A row's stock perpetual as PERP% and FUND 8H read it; rates are fractions. */
99
+ interface ListedPerpetual {
100
+ marketId: string;
101
+ /** The mark over the stock's last price; null without a comparable reference. */
102
+ underlyingPremium: number | null;
103
+ /** Funding per eight hours, whatever interval the venue pays on. */
104
+ fundingRate8h: number | null;
105
+ /** The venue's latest reading is old. */
106
+ stale: boolean;
107
+ }
108
+
109
+ /** The two perpetual columns: what each reads from the row's contract. */
110
+ const PERPETUAL_FIELDS = { perp_premium: "underlyingPremium", perp_funding: "fundingRate8h" } as const;
111
+
112
+ /** A perpetual's rate in percent: two decimals for a premium, four for funding, as PERP shows them. */
113
+ export function formatPerpetualRate(value: number, decimals: number): string {
114
+ const fixed = Math.abs(value * 100).toFixed(decimals);
115
+ return `${/[1-9]/.test(fixed) ? (value > 0 ? "+" : "-") : ""}${fixed}%`;
116
+ }
117
+
118
+ function perpetualValue(columnId: keyof typeof PERPETUAL_FIELDS, symbol: string, ctx: ColumnContext): { pending: boolean; data: ListedPerpetual | null; value: number | null } {
119
+ const perp = mapData(ctx.perpetuals, symbol);
120
+ return { ...perp, value: perp.data?.[PERPETUAL_FIELDS[columnId]] ?? null };
82
121
  }
83
122
 
84
123
  /** Position and calendar dates as "Jan 5", read in UTC. */
@@ -133,7 +172,7 @@ function targetValue(data: AnalystResearchData | null | undefined): number | nul
133
172
  return target?.average ?? target?.median ?? target?.high ?? target?.low ?? null;
134
173
  }
135
174
 
136
- function mapData<T>(map: Map<string, T | null> | undefined, symbol: string): { pending: boolean; data: T | null } {
175
+ function mapData<T>(map: ReadonlyMap<string, T | null> | undefined, symbol: string): { pending: boolean; data: T | null } {
137
176
  if (!map) return { pending: false, data: null };
138
177
  if (!map.has(symbol)) return { pending: true, data: null };
139
178
  return { pending: false, data: map.get(symbol) ?? null };
@@ -193,7 +232,8 @@ function tradedQuoteDisplay(
193
232
  * from that close. Until the close, and wherever no close is reported (a
194
233
  * pre-market quote without it, venues without extended hours), the traded price
195
234
  * as above.
196
- * Valuation columns (DAY P&L, MKT VAL, weight, P&L) keep the live price.
235
+ * Valuation columns (DAY P&L, MKT VAL, weight, P&L) keep the latest print,
236
+ * unless the pane values at the regular close, which is this headline.
197
237
  * A watchlist's Avg Day averages this CHG%.
198
238
  */
199
239
  export function headlineQuoteDisplay(
@@ -241,6 +281,17 @@ function rowAllocation(
241
281
  /** A held position without a price says so where its allocation would be. */
242
282
  const UNPRICED = "n/a";
243
283
 
284
+ /**
285
+ * The symbol the Ticker column shows after its market-state dot: an option reads as its contract (`AAPL C $300
286
+ * Dec'26`, from an OCC code or a broker's symbol), a perpetual as its venue writes it (`BZUSDT`, `xyz:BRENTOIL`),
287
+ * the venue being its exchange.
288
+ */
289
+ export function tickerDisplayName(ticker: TickerRecord): string {
290
+ if (classifyInstrumentType(ticker.metadata.assetCategory) === "option") return formatOptionTicker(ticker.metadata.ticker);
291
+ const perpetual = perpetualListing(ticker.metadata.ticker, ticker.metadata.exchange);
292
+ return perpetual ? perpetualDisplaySymbol(perpetual) : ticker.metadata.ticker;
293
+ }
294
+
244
295
  export function resolvePortfolioPriceValue(
245
296
  activeQuote: ActiveQuoteDisplay | null,
246
297
  brokerMarkPrice: number | undefined,
@@ -265,15 +316,17 @@ export function getColumnValue(
265
316
  ticker: TickerRecord,
266
317
  financials: TickerFinancials | undefined,
267
318
  ctx: ColumnContext,
268
- ): { text: string; color?: string; pnlBasis?: PortfolioPositionPnl["basis"] } {
319
+ ): { text: string; color?: string; value?: number | null; pnlBasis?: PortfolioPositionPnl["basis"] } {
269
320
  const quote = financials?.quote;
270
321
 
271
322
  const fundamentals = financials?.fundamentals;
272
323
  const quoteCurrency = quote?.currency || ticker.metadata.currency || "USD";
273
324
 
274
325
  const positionMetrics = getPortfolioPositionMetrics(ticker, ctx.activeTab, quoteCurrency, undefined, quote);
275
- const activeQuote = getPortfolioQuoteDisplay(positionMetrics, quote);
276
- const displayQuote = tradedQuoteDisplay(positionMetrics, activeQuote, quote);
326
+ // The latest print, which the quote columns read, and the price the position is valued at.
327
+ const liveQuote = getPortfolioQuoteDisplay(positionMetrics, quote);
328
+ const activeQuote = getPortfolioValuationDisplay(positionMetrics, quote, ctx.valuationBasis);
329
+ const displayQuote = tradedQuoteDisplay(positionMetrics, liveQuote, quote);
277
330
  const headlineQuote = headlineQuoteDisplay(displayQuote, quote);
278
331
  const { positionCurrency, totalShares, totalCost, totalCostUnits, totalPriceUnits, multiplierHint, brokerMarkPrice } = positionMetrics;
279
332
  const baseMetrics = getPortfolioPositionMetrics(ticker, ctx.activeTab, quoteCurrency, {
@@ -303,19 +356,19 @@ export function getColumnValue(
303
356
  case "ticker": {
304
357
  const marketState = quote?.marketState;
305
358
  const statusDot = marketStateDot(marketState);
306
- const displayName = ticker.metadata.assetCategory === "OPT"
307
- ? formatOptionTicker(ticker.metadata.ticker)
308
- : ticker.metadata.ticker;
309
- return { text: `${statusDot} ${displayName}` };
359
+ return { text: `${statusDot} ${tickerDisplayName(ticker)}` };
310
360
  }
311
361
  case "name":
312
- return { text: compactText(ticker.metadata.name || quote?.name) };
362
+ // The name the listing's quote gives now, as `quote` and `portfolio show` name it, else the saved one.
363
+ return { text: compactText(currentListingName(ticker, quote) || ticker.metadata.name || quote?.name) };
313
364
  case "asset_type":
314
365
  return { text: compactText(ticker.metadata.assetCategory) };
315
366
  case "exchange":
316
367
  return {
317
368
  text: compactText(
318
- quote?.listingExchangeName
369
+ // A row saved as 247540:KRX shows KOSDAQ, the board its quote is read on.
370
+ quote?.tradingExchangeName
371
+ || quote?.listingExchangeName
319
372
  || quote?.exchangeName
320
373
  || quote?.routingExchangeName
321
374
  || ticker.metadata.exchange,
@@ -375,7 +428,7 @@ export function getColumnValue(
375
428
  }
376
429
  case "market_cap": {
377
430
  const cap = liveMarketCapitalization(quote, fundamentals);
378
- const value = cap ? convertMarketCapitalization(cap.value, cap.currency, ctx.baseCurrency, ctx.exchangeRates) : null;
431
+ const value = cap ? listedMarketCapitalization(convertMarketCapitalization(cap.value, cap.currency, ctx.baseCurrency, ctx.exchangeRates)) : null;
379
432
  return { text: value == null ? "—" : formatCompact(value, { fixedDecimals: true }) };
380
433
  }
381
434
  case "pe":
@@ -423,7 +476,8 @@ export function getColumnValue(
423
476
  const allocation = rowAllocation(ticker, activeQuote, baseMetrics, toBaseQuote, ctx);
424
477
  if (allocation.unpriced && allocation.targetWeight != null) return { text: UNPRICED };
425
478
  const text = formatTradeUnits(allocation.tradeUnits, { units: totalShares, assetCategory: ticker.metadata.assetCategory });
426
- return { text, color: /[1-9]/.test(text) ? priceColor(allocation.tradeUnits!) : undefined };
479
+ // The cell shows the trade rounded; exports and rendered-view reports keep the full figure.
480
+ return { text, value: allocation.tradeUnits, color: /[1-9]/.test(text) ? priceColor(allocation.tradeUnits!) : undefined };
427
481
  }
428
482
  case "trade_value": {
429
483
  const allocation = rowAllocation(ticker, activeQuote, baseMetrics, toBaseQuote, ctx);
@@ -447,9 +501,9 @@ export function getColumnValue(
447
501
  return percent === null ? { text: "—" } : { text: formatPercentRaw(percent), color: priceColor(percent) };
448
502
  }
449
503
  case "mark_delta":
450
- if (!activeQuote || brokerMarkPrice == null || activeQuote.price === 0 || positionMetrics.priceBasis !== (quote?.priceBasis ?? "per-unit") || positionCurrency !== quoteCurrency) return { text: "—" };
504
+ if (!liveQuote || brokerMarkPrice == null || liveQuote.price === 0 || positionMetrics.priceBasis !== (quote?.priceBasis ?? "per-unit") || positionCurrency !== quoteCurrency) return { text: "—" };
451
505
  {
452
- const percent = ((brokerMarkPrice - activeQuote.price) / Math.abs(activeQuote.price)) * 100;
506
+ const percent = ((brokerMarkPrice - liveQuote.price) / Math.abs(liveQuote.price)) * 100;
453
507
  return { text: formatPercentRaw(percent), color: priceColor(percent) };
454
508
  }
455
509
  case "acq_date": {
@@ -493,8 +547,25 @@ export function getColumnValue(
493
547
  if (result.pending) return { text: "…" };
494
548
  return { text: formatShortDate(result.date, MONTH_DAY) };
495
549
  }
550
+ case "perp_premium":
551
+ case "perp_funding": {
552
+ const perp = perpetualValue(col.id, ticker.metadata.ticker, ctx);
553
+ if (perp.pending) return { text: "…" };
554
+ if (perp.value == null) return { text: "—" };
555
+ // An old venue reading keeps its figure, dimmed, as PERP shows a stale market.
556
+ return {
557
+ text: formatPerpetualRate(perp.value, col.id === "perp_funding" ? 4 : 2),
558
+ color: perp.data?.stale ? colors.textDim : priceColor(perp.value),
559
+ };
560
+ }
496
561
  case "latency":
497
562
  return { text: formatQuoteAgeWithSource(quote, ctx.now, { seconds: true }) };
563
+ case "as_of": {
564
+ const time = getPortfolioValuationTime(quote, ctx.valuationBasis, positionMetrics);
565
+ if (!time) return { text: "—" };
566
+ // In UTC, as the header says; a close the venue's calendar gives no hour for is dated by its day.
567
+ return { text: time.dateOnly ? formatShortDate(time.time, MONTH_DAY) : formatFeedTime(time.time, ctx.now, "—", { utc: true }) };
568
+ }
498
569
  case PRICE_SPARKLINE_COLUMN_ID:
499
570
  return { text: "" };
500
571
  default:
@@ -514,8 +585,9 @@ export function getSortValue(
514
585
  const quoteCurrency = quote?.currency || ticker.metadata.currency || "USD";
515
586
 
516
587
  const positionMetrics = getPortfolioPositionMetrics(ticker, ctx.activeTab, quoteCurrency, undefined, quote);
517
- const activeQuote = getPortfolioQuoteDisplay(positionMetrics, quote);
518
- const displayQuote = tradedQuoteDisplay(positionMetrics, activeQuote, quote);
588
+ const liveQuote = getPortfolioQuoteDisplay(positionMetrics, quote);
589
+ const activeQuote = getPortfolioValuationDisplay(positionMetrics, quote, ctx.valuationBasis);
590
+ const displayQuote = tradedQuoteDisplay(positionMetrics, liveQuote, quote);
519
591
  const headlineQuote = headlineQuoteDisplay(displayQuote, quote);
520
592
  const { positionCurrency, totalShares, totalCost, totalCostUnits, totalPriceUnits, brokerMarkPrice } = positionMetrics;
521
593
  const baseMetrics = getPortfolioPositionMetrics(ticker, ctx.activeTab, quoteCurrency, {
@@ -532,11 +604,12 @@ export function getSortValue(
532
604
  case "ticker":
533
605
  return ticker.metadata.ticker;
534
606
  case "name":
535
- return ticker.metadata.name || quote?.name || null;
607
+ return currentListingName(ticker, quote) || ticker.metadata.name || quote?.name || null;
536
608
  case "asset_type":
537
609
  return ticker.metadata.assetCategory ?? null;
538
610
  case "exchange":
539
- return quote?.listingExchangeName
611
+ return quote?.tradingExchangeName
612
+ ?? quote?.listingExchangeName
540
613
  ?? quote?.exchangeName
541
614
  ?? quote?.routingExchangeName
542
615
  ?? ticker.metadata.exchange
@@ -582,7 +655,7 @@ export function getSortValue(
582
655
  return fiftyTwoWeekPosition(displayQuote, quote);
583
656
  case "market_cap": {
584
657
  const cap = liveMarketCapitalization(quote, fundamentals);
585
- return cap ? convertMarketCapitalization(cap.value, cap.currency, ctx.baseCurrency, ctx.exchangeRates) : null;
658
+ return cap ? listedMarketCapitalization(convertMarketCapitalization(cap.value, cap.currency, ctx.baseCurrency, ctx.exchangeRates)) : null;
586
659
  }
587
660
  case "pe":
588
661
  return comparablePriceEarnings(liveTrailingPE(quote, fundamentals));
@@ -622,8 +695,8 @@ export function getSortValue(
622
695
  case "pnl_pct":
623
696
  return portfolioPnlPercent(positionPnl.value, baseMetrics.totalCost);
624
697
  case "mark_delta":
625
- return activeQuote && brokerMarkPrice != null && activeQuote.price !== 0 && positionMetrics.priceBasis === (quote?.priceBasis ?? "per-unit") && positionCurrency === quoteCurrency
626
- ? ((brokerMarkPrice - activeQuote.price) / Math.abs(activeQuote.price)) * 100
698
+ return liveQuote && brokerMarkPrice != null && liveQuote.price !== 0 && positionMetrics.priceBasis === (quote?.priceBasis ?? "per-unit") && positionCurrency === quoteCurrency
699
+ ? ((brokerMarkPrice - liveQuote.price) / Math.abs(liveQuote.price)) * 100
627
700
  : null;
628
701
  case "acq_date":
629
702
  return earliestDateAcquired(ticker, ctx.activeTab)?.getTime() ?? null;
@@ -651,8 +724,13 @@ export function getSortValue(
651
724
  const result = nextEarningsDate(ticker.metadata.ticker, ctx);
652
725
  return result.pending ? null : result.date?.getTime() ?? null;
653
726
  }
727
+ case "perp_premium":
728
+ case "perp_funding":
729
+ return perpetualValue(col.id, ticker.metadata.ticker, ctx).value;
654
730
  case "latency":
655
731
  return quote ? ctx.now - (resolveQuoteAgeTimestamp(quote, ctx.now) ?? ctx.now) : null;
732
+ case "as_of":
733
+ return getPortfolioValuationTime(quote, ctx.valuationBasis, positionMetrics)?.time ?? null;
656
734
  case PRICE_SPARKLINE_COLUMN_ID: {
657
735
  // The trend the sparkline draws: its window, closed by the live price.
658
736
  const history = followLiveSparklinePrice(financials?.priceHistory ?? [], quote, {
@@ -17,7 +17,7 @@ import { createRowValueCache, type RowValueCache } from "../../../components/ui/
17
17
  import { objectVersion } from "../../../utils/object-version";
18
18
  import { columnContextVersion } from "./cell-version";
19
19
  import { getColumnValue, getSortValue, type ColumnContext } from "./metrics";
20
- import { getPortfolioPositionMetrics, getPortfolioQuoteDisplay } from "./position-metrics";
20
+ import { getPortfolioPositionMetrics, getPortfolioQuoteDisplay } from "../../../portfolio/position-metrics";
21
21
  import { PORTFOLIO_ROW_MENU_KEYS } from "./row-actions";
22
22
  import { PORTFOLIO_REORDER_THROTTLE_MS } from "./use-throttled-ticker-order";
23
23
  import { useThrottledMemo } from "./use-throttled-memo";