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,24 +1,84 @@
1
1
  import {
2
2
  cliStyles,
3
+ cliTerminalWidth,
4
+ renderDefinitions,
3
5
  renderSection,
4
6
  renderTable,
7
+ wrapText,
5
8
  } from "../../utils/cli-output";
6
9
  import type { DataProvider } from "../../types/data-provider";
10
+ import type { Quote } from "../../types/financials";
11
+ import { quotedListingName } from "../../tickers/listing-name";
7
12
  import type { TickerRecord } from "../../types/ticker";
8
13
  import {
14
+ LISTING_SEARCH_LIMIT,
9
15
  searchTickerCandidates,
10
16
  type TickerSearchCandidate,
11
17
  } from "../../tickers/search";
12
18
  import { initMarketData, withMarketData } from "../context";
19
+ import { loadListingFate } from "../listing-arg";
20
+ import { formatMarketPriceWithCurrency, quoteFormatOptions } from "../../market-data/market/format";
21
+ import { startTickerChangeLookup, tickerChangeLine, type TickerChangeLookup } from "../../tickers/ticker-changes";
13
22
  import { fail } from "../errors";
14
23
  import type { MarketContext } from "../types";
15
- import type { CliCommandContext } from "../../types/plugin";
24
+ import type { CliCommandContext, GloomPlugin } from "../../types/plugin";
16
25
  import { indexRootFor, indexRootTryLine } from "../index-roots";
26
+ import { knownGapMessage } from "../known-gaps";
27
+ import { instrumentTypeLabel } from "../../tickers/instrument-kind";
28
+ import { canonicalExchange, isUsListingExchange } from "../../utils/exchanges";
29
+ import { groupByCompany } from "../../tickers/company-name";
30
+ import { findCatalogSeries, renderSeriesMatches, type SeriesMatch } from "../series-search";
31
+ import { centralBankCiting, centralBankNamed, type CentralBank } from "../../utils/central-banks";
32
+ import { createPaneCatalog } from "../pane-functions/discovery";
33
+ import { buildPaneCatalogEntries, filterPaneCatalogEntries, selectPaneCatalogMatches } from "../pane-functions/catalog";
17
34
 
18
35
  interface SearchCommandDependencies {
19
36
  initMarketData?: () => Promise<MarketContext>;
20
37
  fail?: (message: string, details?: string) => never;
21
38
  printResult?: CliCommandContext["printResult"];
39
+ /**
40
+ * Plugins whose data catalog series a query can name, listed before the
41
+ * tickers, and whose functions a search that finds no ticker lists.
42
+ */
43
+ plugins?: GloomPlugin[];
44
+ }
45
+
46
+ /** Series a search lists before pointing at the catalog for the rest. */
47
+ const SEARCH_SERIES_LIMIT = 3;
48
+ /** Functions a search that finds no ticker lists, as `catalog` would. */
49
+ const SEARCH_FUNCTION_LIMIT = 3;
50
+
51
+ /** A function a search lists: what `catalog` shows of it in a list. */
52
+ export interface SearchFunctionMatch {
53
+ token: string;
54
+ label: string;
55
+ description: string;
56
+ }
57
+
58
+ /**
59
+ * The functions that carry every word of the query in their name, keywords
60
+ * or description, best first, as `catalog <query>` ranks them: "target
61
+ * weights rebalance" names no company, but PF does that. None when only some
62
+ * of the words match.
63
+ */
64
+ export async function searchFunctionsForCli(query: string, plugins: GloomPlugin[], context: MarketContext): Promise<SearchFunctionMatch[]> {
65
+ let registry: Awaited<ReturnType<typeof createPaneCatalog>> | null = null;
66
+ try {
67
+ registry = await createPaneCatalog(context, plugins);
68
+ const entries = await buildPaneCatalogEntries(registry, context);
69
+ const { shown, loose } = selectPaneCatalogMatches(filterPaneCatalogEntries(entries, query), query, SEARCH_FUNCTION_LIMIT);
70
+ return loose ? [] : shown.map(({ token, label, description }) => ({ token, label, description }));
71
+ } catch {
72
+ // A plugin that cannot set up for discovery leaves the search as it was.
73
+ return [];
74
+ } finally {
75
+ registry?.destroy();
76
+ }
77
+ }
78
+
79
+ /** A bare symbol's quote, asked as `quote SYM` asks it: on the venue a saved row of the symbol is on, else the bare symbol. */
80
+ function loadSearchedQuote(symbol: string, savedExchange: string, dataProvider: DataProvider): Promise<Quote | null> {
81
+ return Promise.resolve().then(() => dataProvider.getQuote(symbol, savedExchange)).catch(() => null);
22
82
  }
23
83
 
24
84
  export async function searchCandidatesForCli({
@@ -27,12 +87,15 @@ export async function searchCandidatesForCli({
27
87
  dataProvider,
28
88
  totalLimit = 10,
29
89
  localLimit = 6,
90
+ quote: quoted,
30
91
  }: {
31
92
  query: string;
32
93
  tickers: TickerRecord[];
33
94
  dataProvider: DataProvider;
34
95
  totalLimit?: number;
35
96
  localLimit?: number;
97
+ /** The symbol's quote when the caller asked for it beside the search; otherwise asked only when search lists the symbol. */
98
+ quote?: Promise<Quote | null>;
36
99
  }): Promise<TickerSearchCandidate[]> {
37
100
  const trimmedQuery = query.trim();
38
101
  if (!trimmedQuery) return [];
@@ -41,18 +104,146 @@ export async function searchCandidatesForCli({
41
104
  tickers.map((ticker) => [ticker.metadata.ticker.toUpperCase(), ticker] as const),
42
105
  );
43
106
  try {
44
- return await searchTickerCandidates({
107
+ const candidates = await searchTickerCandidates({
45
108
  query: trimmedQuery,
46
109
  tickers: localTickerMap,
47
110
  dataProvider,
48
111
  localLimit,
49
- totalLimit,
112
+ // Every company's listing of a symbol several use (CAR's ASX line is past the first ten), cut after ordering.
113
+ totalLimit: Math.max(totalLimit, LISTING_SEARCH_LIMIT),
114
+ searchContext: { limit: LISTING_SEARCH_LIMIT },
50
115
  });
116
+ const symbol = trimmedQuery.toUpperCase();
117
+ // A bare symbol search lists asks for the quote `quote SYM` reads, once, for its venue and its name:
118
+ // on the venue a saved row of the symbol is on, as `quote` asks for it, else the bare symbol.
119
+ const savedExchange = localTickerMap.get(symbol)?.metadata.exchange ?? "";
120
+ const quote = BARE_SYMBOL.test(symbol) && candidates.some((candidate) => candidate.symbol.toUpperCase() === symbol)
121
+ ? await (quoted ?? loadSearchedQuote(symbol, savedExchange, dataProvider))
122
+ : null;
123
+ return withQuotedNames(symbol, withPrimaryListingFirst(symbol, candidates, quote), quote).slice(0, totalLimit);
51
124
  } catch {
52
125
  return [];
53
126
  }
54
127
  }
55
128
 
129
+ /** A symbol search does not list whose quote stopped long ago: TWTR, last traded 2022-10-27. */
130
+ interface StoppedListing {
131
+ symbol: string;
132
+ /** The security's name, from its quote or the company that left the symbol; null when neither says. */
133
+ name: string | null;
134
+ /** The exchange-local date it last traded. */
135
+ lastTraded: string;
136
+ /** Its last price with its currency: $53.86. */
137
+ lastPrice: string;
138
+ /** What history and options say of it: "TWTR stopped trading 2022-10-27; no history or options served". */
139
+ note: string;
140
+ }
141
+
142
+ interface SearchFate {
143
+ /** The symbol searched for, when search no longer lists it and its quote stopped long ago. */
144
+ stopped: StoppedListing | null;
145
+ /** Lines beside the results: `quote`'s line for a company that left the symbol (FB), or a listed symbol that stopped trading. */
146
+ notes: string[];
147
+ }
148
+
149
+ const NO_SEARCH_FATE: SearchFate = { stopped: null, notes: [] };
150
+
151
+ /**
152
+ * What became of a bare symbol, read as `quote` reads it (`loadListingFate`):
153
+ * one search does not list but whose quote stopped long ago is listed as no
154
+ * longer trading, and a line says when its company left the symbol (FB) or a
155
+ * listing search still lists stopped trading. Nothing for anything else.
156
+ */
157
+ async function searchFate(
158
+ symbol: string,
159
+ candidates: readonly TickerSearchCandidate[],
160
+ quote: Quote | null,
161
+ dataProvider: DataProvider,
162
+ changes: TickerChangeLookup,
163
+ ): Promise<SearchFate> {
164
+ const fate = await loadListingFate({ symbol }, dataProvider, { quote, changes });
165
+ const unlisted = !candidates.some((candidate) => candidate.symbol.toUpperCase() === symbol);
166
+ const stopped = unlisted && quote && fate.endedOn && fate.note
167
+ ? {
168
+ symbol,
169
+ name: quote.name?.trim() || fate.change?.issuer || null,
170
+ lastTraded: fate.endedOn,
171
+ lastPrice: formatMarketPriceWithCurrency(quote.price, quote.currency, quoteFormatOptions(quote)),
172
+ note: fate.note,
173
+ }
174
+ : null;
175
+ // The row says when a listing stopped; a company that left the symbol is a line of its own.
176
+ const changed = tickerChangeLine(fate.change);
177
+ return { stopped, notes: changed ? [changed] : fate.note && !stopped ? [fate.note] : [] };
178
+ }
179
+
180
+ /** A query that is a bare symbol (CAR, BRK.B), not a name or a phrase. */
181
+ const BARE_SYMBOL = /^[A-Z0-9][A-Z0-9.\-]{0,11}$/;
182
+
183
+ function candidateExchange(candidate: TickerSearchCandidate): string {
184
+ return canonicalExchange(candidate.result?.exchange === "SMART"
185
+ ? candidate.result.primaryExchange
186
+ : candidate.result?.exchange || candidate.result?.primaryExchange || candidate.ticker?.metadata.exchange || candidate.right);
187
+ }
188
+
189
+ /**
190
+ * For a bare symbol several companies list (CAR: Avis, Carrefour, CAR Group),
191
+ * the listing `quote CAR` reads goes first as the primary listing, then each
192
+ * other company's first listing, then the rest of their venues, so a short
193
+ * list still shows every company. A saved listing is the user's choice and
194
+ * stays where search put it. Any other query keeps search's order.
195
+ */
196
+ function withPrimaryListingFirst(
197
+ symbol: string,
198
+ candidates: TickerSearchCandidate[],
199
+ quote: Quote | null,
200
+ ): TickerSearchCandidate[] {
201
+ if (!BARE_SYMBOL.test(symbol)) return candidates;
202
+ const exact = candidates.filter((candidate) => candidate.symbol.toUpperCase() === symbol);
203
+ if (exact.some((candidate) => candidate.kind === "ticker" || candidate.saved)) return candidates;
204
+ const listed = exact.filter((candidate) => candidate.kind === "search" && (candidate.instrumentClass === "equity" || candidate.instrumentClass === "other"));
205
+ const companies = groupByCompany(listed, resolveSearchName);
206
+ if (companies.length < 2) return candidates;
207
+ const primary = quotedCandidate(listed, quote);
208
+ if (!primary) return candidates;
209
+ const firsts = companies.filter((group) => !group.includes(primary)).map((group) => group[0]!);
210
+ const ordered = [primary, ...firsts, ...listed.filter((candidate) => candidate !== primary && !firsts.includes(candidate))];
211
+ const at = candidates.indexOf(listed[0]!);
212
+ const rest = candidates.filter((candidate) => !listed.includes(candidate));
213
+ return [...rest.slice(0, at), ...ordered, ...rest.slice(at)].map((candidate) => (
214
+ candidate === primary ? { ...candidate, category: "Primary Listing" as const }
215
+ : listed.includes(candidate) || candidate.category === "Primary Listing" ? { ...candidate, category: "Other Listings" as const }
216
+ : candidate
217
+ ));
218
+ }
219
+
220
+ /** The candidate on the venue the quote prices; the US exchanges share one symbol, so a quote on any of them is its one US line. */
221
+ function quotedCandidate(candidates: readonly TickerSearchCandidate[], quote: Quote | null): TickerSearchCandidate | undefined {
222
+ const quoted = canonicalExchange(quote?.listingExchangeName || quote?.exchangeName);
223
+ if (!quoted) return undefined;
224
+ return candidates.find((candidate) => candidateExchange(candidate) === quoted)
225
+ ?? (isUsListingExchange(quoted) ? candidates.find((candidate) => isUsListingExchange(candidateExchange(candidate))) : undefined);
226
+ }
227
+
228
+ /**
229
+ * A catalogue can keep a listing's name from before a rename. For a bare
230
+ * symbol, the listing its quote prices goes by the quote's name, as `quote`,
231
+ * `history` and the portfolio name it, and so do the same company's other
232
+ * venues of the symbol. Other companies' listings keep their own.
233
+ */
234
+ function withQuotedNames(symbol: string, candidates: TickerSearchCandidate[], quote: Quote | null): TickerSearchCandidate[] {
235
+ const exact = candidates.filter((candidate) => candidate.symbol.toUpperCase() === symbol && !candidate.contractKey);
236
+ const onVenue = quotedCandidate(exact, quote);
237
+ const name = onVenue ? quotedListingName(candidateExchange(onVenue), quote) : null;
238
+ if (!onVenue || !name) return candidates;
239
+ const company = groupByCompany(exact, resolveSearchName).find((group) => group.includes(onVenue)) ?? [onVenue];
240
+ return candidates.map((candidate) => {
241
+ if (!company.includes(candidate) || resolveSearchName(candidate) === name) return candidate;
242
+ const [, ...rest] = candidate.detail.split(" | ");
243
+ return { ...candidate, detail: [name, ...rest].join(" | "), ...candidate.result ? { result: { ...candidate.result, name } } : {} };
244
+ });
245
+ }
246
+
56
247
  /** "Saved", or the broker a row came from; never the data service's internal id. */
57
248
  function searchSourceLabel(candidate: TickerSearchCandidate): string {
58
249
  return candidate.kind === "ticker" ? "Saved" : candidate.result?.brokerLabel || "";
@@ -62,6 +253,31 @@ function resolveSearchName(candidate: TickerSearchCandidate): string {
62
253
  return candidate.detail.split(" | ")[0] || candidate.detail || "—";
63
254
  }
64
255
 
256
+ /** The listing's type as the table shows it; a perpetual price a provider types as a coin says what it is. */
257
+ function searchType(candidate: TickerSearchCandidate): string | undefined {
258
+ return instrumentTypeLabel(candidate.result?.type
259
+ || candidate.result?.brokerContract?.secType
260
+ || candidate.ticker?.metadata.assetCategory, resolveSearchName(candidate));
261
+ }
262
+
263
+ /** What `--json` lists for a symbol search no longer lists: its category says so, and it keeps its last date and price. */
264
+ function stoppedListingRow(stopped: StoppedListing) {
265
+ return {
266
+ category: STOPPED_CATEGORY, symbol: stopped.symbol, name: stopped.name ?? "", exchange: "", type: "", source: "", providerId: "",
267
+ saved: false, lastTraded: stopped.lastTraded, lastPrice: stopped.lastPrice, note: stopped.note,
268
+ };
269
+ }
270
+
271
+ const STOPPED_CATEGORY = "No Longer Trading";
272
+
273
+ /** The stopped listing in its own section, as the search results list: its name when known, its last date and price. */
274
+ function renderStoppedListing(stopped: StoppedListing): string {
275
+ return [renderSection(STOPPED_CATEGORY), renderTable(
276
+ [{ header: "Symbol" }, ...stopped.name ? [{ header: "Name" }] : [], { header: "Last traded" }, { header: "Last price", align: "right" as const }],
277
+ [[stopped.symbol, ...stopped.name ? [stopped.name] : [], stopped.lastTraded, stopped.lastPrice]],
278
+ )].join("\n");
279
+ }
280
+
65
281
  function searchCandidateRows(candidates: TickerSearchCandidate[]) {
66
282
  return candidates.map((candidate) => ({
67
283
  category: candidate.category,
@@ -92,19 +308,89 @@ function indexRootNote(query: string, candidates: TickerSearchCandidate[]): stri
92
308
  return indexRootTryLine(root);
93
309
  }
94
310
 
311
+ /** The bank on the CBR board a query names ("SNB", "Norges Bank"), or whose row reads the FRED series it names (DFEDTARU). */
312
+ function searchedCentralBank(query: string): CentralBank | null {
313
+ return centralBankNamed(query) ?? centralBankCiting(query.replace(/^FRED:/i, ""));
314
+ }
315
+
316
+ /** "Swiss National Bank (Switzerland): policy rate on the CBR board, gloomberb fn CBR." */
317
+ function centralBankLine(bank: CentralBank): string {
318
+ return `${bank.name} (${bank.place}): policy rate on the CBR board, gloomberb fn CBR.`;
319
+ }
320
+
321
+ /** Search finds tickers and companies; a function, a dataset or a term is in the catalog, so an empty search points there. */
322
+ function catalogHint(query: string): string {
323
+ return `Search finds tickers and company names. Try: gloomberb catalog "${query.replace(/"/g, "")}"`;
324
+ }
325
+
326
+ /**
327
+ * The notes beside the results: the index a bare root names, data the query
328
+ * asks for that no source carries yet, the central bank it names, and for an
329
+ * empty search the catalog, unless a known gap, the bank or the functions
330
+ * listed already said where to look instead.
331
+ */
332
+ function searchNotes(
333
+ query: string,
334
+ candidates: TickerSearchCandidate[],
335
+ functions: readonly SearchFunctionMatch[],
336
+ fate: SearchFate,
337
+ ): string[] {
338
+ const gap = knownGapMessage(query);
339
+ const bank = searchedCentralBank(query);
340
+ const empty = candidates.length === 0 && !fate.stopped;
341
+ return [...fate.notes, indexRootNote(query, candidates), gap, bank ? centralBankLine(bank) : null,
342
+ empty && !gap && !bank && functions.length === 0 ? catalogHint(query) : null]
343
+ .filter((note): note is string => !!note);
344
+ }
345
+
346
+ /** The functions an empty search lists: each with what it does, whole, since that is why it matched. */
347
+ function renderFunctionMatches(functions: readonly SearchFunctionMatch[]): string {
348
+ const width = Math.min(cliTerminalWidth() ?? 100, 100);
349
+ return [
350
+ renderSection("Functions"),
351
+ ...renderDefinitions(functions.map((match) => [`${match.token} ${match.label}`, match.description] as const), { width, termStyle: cliStyles.command }),
352
+ "",
353
+ ...wrapText("No ticker or company matches. gloomberb catalog <function> shows a function's options and examples.", width)
354
+ .map((line) => cliStyles.muted(line)),
355
+ ].join("\n");
356
+ }
357
+
95
358
  export function buildSearchReport({
96
359
  query,
97
360
  candidates,
361
+ series = [],
362
+ functions = [],
363
+ fate = NO_SEARCH_FATE,
98
364
  }: {
99
365
  query: string;
100
366
  candidates: TickerSearchCandidate[];
367
+ /** Data catalog series the query names: data, such as a price or a rate, that no ticker is. */
368
+ series?: readonly SeriesMatch[];
369
+ /** The functions that carry every word of a query no ticker matches. */
370
+ functions?: readonly SearchFunctionMatch[];
371
+ /** What became of the symbol searched for: a listing that stopped trading, a company that left it. */
372
+ fate?: SearchFate;
101
373
  }): string {
102
374
  const lines = [renderSection(`Search: ${query}`)];
375
+ if (fate.notes.length > 0) lines.push("", ...fate.notes);
103
376
  const indexNote = indexRootNote(query, candidates);
104
377
  if (indexNote) lines.push("", indexNote);
378
+ const gap = knownGapMessage(query);
379
+ if (gap) lines.push("", gap);
380
+ const bank = searchedCentralBank(query);
381
+ if (bank) lines.push("", centralBankLine(bank));
382
+ const charted = renderSeriesMatches(query, series, SEARCH_SERIES_LIMIT, cliTerminalWidth() ?? 100, "catalog");
383
+ // A query that names the data ("carbon", "day-ahead") lists its series first; words that happen to
384
+ // be in a series name ("apple") list them after the tickers.
385
+ const seriesFirst = series.some((match) => match.exact);
386
+ if (charted && (seriesFirst || candidates.length === 0)) lines.push("", charted);
387
+ // The symbol asked for goes first, though search no longer lists it.
388
+ if (fate.stopped) lines.push("", renderStoppedListing(fate.stopped));
105
389
 
106
390
  if (candidates.length === 0) {
107
- lines.push(cliStyles.muted("No matches found."));
391
+ if (fate.stopped) return lines.join("\n");
392
+ if (functions.length > 0) lines.push("", renderFunctionMatches(functions));
393
+ else if (!gap && !bank && !charted) lines.push(cliStyles.muted("No matches found."), cliStyles.muted(catalogHint(query)));
108
394
  return lines.join("\n");
109
395
  }
110
396
 
@@ -131,14 +417,12 @@ export function buildSearchReport({
131
417
  || candidate.ticker?.metadata.exchange
132
418
  || candidate.right
133
419
  || "—",
134
- candidate.result?.type
135
- || candidate.result?.brokerContract?.secType
136
- || candidate.ticker?.metadata.assetCategory
137
- || "—",
420
+ searchType(candidate) ?? "—",
138
421
  ...(showSource ? [searchSourceLabel(candidate) || "—"] : []),
139
422
  ]),
140
423
  ));
141
424
  }
425
+ if (charted && !seriesFirst) lines.push("", charted);
142
426
 
143
427
  return lines.join("\n");
144
428
  }
@@ -151,20 +435,36 @@ export async function search(query: string, dependencies: SearchCommandDependenc
151
435
  failCommand("Usage: gloomberb search <query>");
152
436
  }
153
437
 
154
- await withMarketData(initMarketDataFn, async ({ store, dataProvider }) => {
438
+ await withMarketData(initMarketDataFn, async (context) => {
439
+ const { store, dataProvider } = context;
155
440
  const tickers = await store.loadAllTickers();
441
+ const symbol = trimmedQuery.toUpperCase();
442
+ // A bare symbol's quote and whether it changed (FB is now META) are asked beside the search, so they cost no wait.
443
+ const bare = BARE_SYMBOL.test(symbol);
444
+ const savedExchange = tickers.find((ticker) => ticker.metadata.ticker.toUpperCase() === symbol)?.metadata.exchange ?? "";
445
+ const quote = bare ? loadSearchedQuote(symbol, savedExchange, dataProvider) : null;
446
+ const changes = bare ? startTickerChangeLookup(dataProvider, symbol) : null;
156
447
  const candidates = await searchCandidatesForCli({
157
448
  query: trimmedQuery,
158
449
  tickers,
159
450
  dataProvider,
451
+ ...quote ? { quote } : {},
160
452
  });
453
+ const fate = quote && changes ? await searchFate(symbol, candidates, await quote, dataProvider, changes) : NO_SEARCH_FATE;
161
454
 
455
+ const series = findCatalogSeries(dependencies.plugins ?? [], trimmedQuery, "names");
456
+ const bank = searchedCentralBank(trimmedQuery);
457
+ // A query that names no ticker may name what a function does; a known gap or a central bank already says where to look.
458
+ const functions = candidates.length === 0 && !fate.stopped && !knownGapMessage(trimmedQuery) && !bank && dependencies.plugins
459
+ ? await searchFunctionsForCli(trimmedQuery, dependencies.plugins, context)
460
+ : [];
162
461
  if (dependencies.printResult) {
163
- const indexNote = indexRootNote(trimmedQuery, candidates);
462
+ const warnings = searchNotes(trimmedQuery, candidates, functions, fate);
164
463
  dependencies.printResult({
165
- data: searchCandidateRows(candidates),
166
- metadata: { query: trimmedQuery },
167
- warnings: indexNote ? [indexNote] : undefined,
464
+ data: [...fate.stopped ? [stoppedListingRow(fate.stopped)] : [], ...searchCandidateRows(candidates)],
465
+ metadata: { query: trimmedQuery, ...(series.length ? { series } : {}), ...(functions.length ? { functions } : {}),
466
+ ...(bank ? { centralBank: { id: bank.id, name: bank.name, place: bank.place, function: "CBR" } } : {}) },
467
+ warnings: warnings.length ? warnings : undefined,
168
468
  }, {
169
469
  columns: [
170
470
  { key: "category", header: "Category" },
@@ -173,6 +473,7 @@ export async function search(query: string, dependencies: SearchCommandDependenc
173
473
  { key: "exchange", header: "Exchange" },
174
474
  { key: "type", header: "Type" },
175
475
  { key: "source", header: "Source" },
476
+ ...fate.stopped ? [{ key: "lastTraded", header: "Last traded" }, { key: "lastPrice", header: "Last price" }] : [],
176
477
  ],
177
478
  });
178
479
  return;
@@ -181,6 +482,9 @@ export async function search(query: string, dependencies: SearchCommandDependenc
181
482
  console.log(buildSearchReport({
182
483
  query: trimmedQuery,
183
484
  candidates,
485
+ series,
486
+ functions,
487
+ fate,
184
488
  }));
185
489
  });
186
490
  }
@@ -2,14 +2,16 @@ import { join } from "path";
2
2
  import { VERSION } from "../../version";
3
3
  import { saveConfig } from "../../data/config/store";
4
4
  import { builtinPluginGroupMembers } from "../../plugins/ownership";
5
- import type { TelemetryConfig } from "../../types/config";
5
+ import type { AppConfig, TelemetryConfig } from "../../types/config";
6
+ import { canonicalTimeZone } from "../../utils/utc-time";
6
7
  import type { CliCommandDef } from "../../types/plugin";
7
- import { withCliServices, withConfigData } from "../context";
8
+ import { resolveCliDataDir, withCliServices, withConfigData } from "../context";
8
9
  import { CLI_COMMAND_GROUPS } from "../help";
9
10
  import { dryRunNote, formatBytes, formatStatusCell } from "../helpers";
10
11
  import { cliStyles, cliTerminalWidth, renderSection, renderTable, wrapText } from "../../utils/cli-output";
11
12
  import { getThemeIds } from "../../theme/themes";
12
13
  import { requireArg } from "./command-utils";
14
+ import { fail } from "../errors";
13
15
  import { describeThemeId, requireThemeId, themeListNote, themeListRows, themeName } from "./themes";
14
16
  import {
15
17
  applyKeybindingCliSet,
@@ -27,6 +29,10 @@ const TELEMETRY_CONFIG_KEYS = {
27
29
  type TelemetryConfigKey = keyof typeof TELEMETRY_CONFIG_KEYS;
28
30
  /** The one-time GitHub star line in the terminal's status bar. */
29
31
  const STAR_PROMPT_CONFIG_KEY = "starPrompt.enabled";
32
+ /** The zone CLI text shows local times in, beside UTC. */
33
+ const TIMEZONE_CONFIG_KEY = "timezone";
34
+ /** What `config set timezone` takes to go back to UTC alone. */
35
+ const NO_TIMEZONE = "none";
30
36
  const EDITABLE_CONFIG_KEYS = [
31
37
  "baseCurrency",
32
38
  "refreshIntervalMinutes",
@@ -34,6 +40,7 @@ const EDITABLE_CONFIG_KEYS = [
34
40
  "valueFlashingEnabled",
35
41
  ...Object.keys(TELEMETRY_CONFIG_KEYS),
36
42
  STAR_PROMPT_CONFIG_KEY,
43
+ TIMEZONE_CONFIG_KEY,
37
44
  ];
38
45
 
39
46
  function isTelemetryConfigKey(key: string): key is TelemetryConfigKey {
@@ -44,6 +51,19 @@ function isBooleanConfigKey(key: string): boolean {
44
51
  return key === "valueFlashingEnabled" || key === STAR_PROMPT_CONFIG_KEY || isTelemetryConfigKey(key);
45
52
  }
46
53
 
54
+ /** The canonical zone name `config set timezone` stores, or null to clear it; fails on a name that is not a zone. */
55
+ function parseTimezoneSetting(value: string): string | null {
56
+ if (value.trim().toLowerCase() === NO_TIMEZONE) return null;
57
+ return canonicalTimeZone(value) ?? fail(
58
+ `"${value.trim()}" is not a time zone name.`,
59
+ `Use an IANA zone name, Region/City, such as Asia/Tokyo, or ${NO_TIMEZONE} for UTC alone.`,
60
+ );
61
+ }
62
+
63
+ function describeTimezone(value: unknown): string {
64
+ return typeof value === "string" && value ? value : "not set, times print in UTC alone";
65
+ }
66
+
47
67
  function describeConfigValue(value: unknown): string {
48
68
  if (value == null) return "nothing";
49
69
  if (Array.isArray(value)) return value.length > 0 ? value.join(", ") : "nothing";
@@ -51,6 +71,11 @@ function describeConfigValue(value: unknown): string {
51
71
  return String(value);
52
72
  }
53
73
 
74
+ function withTimezone(config: AppConfig, timezone: string | null): AppConfig {
75
+ const { timezone: _previous, ...rest } = config;
76
+ return timezone ? { ...rest, timezone } : rest;
77
+ }
78
+
54
79
  function summarizeKeybindings(value: unknown): string {
55
80
  const described = value as { actions?: Record<string, unknown>; commands?: Record<string, unknown>; issues?: unknown[] };
56
81
  const parts = [
@@ -122,9 +147,11 @@ export function createSystemCliCommands(): CliCommandDef[] {
122
147
  description: "Print the version, runtime, and data folder",
123
148
  help: { group: CLI_COMMAND_GROUPS.app, usage: ["version"] },
124
149
  execute: async (_args, ctx) => {
150
+ // Where the data lives, or will once a command or the app first runs:
151
+ // printing the version never creates the folder.
125
152
  let dataDir: string | null = null;
126
153
  try {
127
- dataDir = await withConfigData(ctx, ({ dataDir: configuredDataDir }) => configuredDataDir);
154
+ dataDir = await resolveCliDataDir();
128
155
  } catch {
129
156
  dataDir = null;
130
157
  }
@@ -148,7 +175,11 @@ export function createSystemCliCommands(): CliCommandDef[] {
148
175
  const checks: Array<{ check: string; status: string; detail: string }> = [];
149
176
  try {
150
177
  await withCliServices(ctx, async (services) => {
151
- checks.push({ check: "config", status: "ok", detail: services.dataDir });
178
+ checks.push({
179
+ check: "config",
180
+ status: "ok",
181
+ detail: services.createdDataDir ? `${services.dataDir} (created now)` : services.dataDir,
182
+ });
152
183
  checks.push({ check: "database", status: "ok", detail: join(services.dataDir, ".gloomberb-cache.db") });
153
184
  checks.push({ check: "plugins", status: "ok", detail: String(services.services.pluginRegistry.allPlugins.size) });
154
185
  checks.push({ check: "capabilities", status: "ok", detail: String(services.services.pluginRegistry.capabilities.manifests().length) });
@@ -187,6 +218,7 @@ export function createSystemCliCommands(): CliCommandDef[] {
187
218
  "config set telemetry.crashReports false",
188
219
  "config set telemetry.usage false",
189
220
  "config set starPrompt.enabled false",
221
+ "config set timezone <Region/City>|none",
190
222
  "config get keybindings",
191
223
  "config set keybindings.actions.<action> <keys>|null|default",
192
224
  "config set keybindings.commands.<keys> <command>|null",
@@ -194,6 +226,11 @@ export function createSystemCliCommands(): CliCommandDef[] {
194
226
  sections: [{
195
227
  title: "Editable keys",
196
228
  lines: [`${EDITABLE_CONFIG_KEYS.join(", ")}, and keybindings.*`],
229
+ }, {
230
+ title: "Time zone",
231
+ lines: [
232
+ "Times print in UTC. timezone takes an IANA zone name such as Asia/Tokyo or America/New_York, and CLI text and function reports then show your local time beside every UTC time. Trading days keep their market's date. none goes back to UTC alone. JSON and CSV keep the raw values.",
233
+ ],
197
234
  }, {
198
235
  title: "Themes",
199
236
  lines: [
@@ -205,6 +242,7 @@ export function createSystemCliCommands(): CliCommandDef[] {
205
242
  "config themes",
206
243
  "config set theme colorblind",
207
244
  "config set baseCurrency EUR",
245
+ "config set timezone Asia/Tokyo",
208
246
  "config get keybindings",
209
247
  "config set keybindings.actions.ticker-search \"Ctrl+T\"",
210
248
  "config set keybindings.commands.Alt+1 \"DES AAPL\"",
@@ -248,6 +286,7 @@ export function createSystemCliCommands(): CliCommandDef[] {
248
286
  "telemetry.usage": context.config.telemetry?.usage !== false,
249
287
  "telemetry.attention": context.config.telemetry?.attention === true,
250
288
  [STAR_PROMPT_CONFIG_KEY]: context.config.starPrompt?.enabled !== false,
289
+ [TIMEZONE_CONFIG_KEY]: context.config.timezone ?? null,
251
290
  };
252
291
 
253
292
  if (action === "list") {
@@ -257,6 +296,7 @@ export function createSystemCliCommands(): CliCommandDef[] {
257
296
  header: key,
258
297
  ...(key === KEYBINDINGS_CONFIG_KEY ? { format: summarizeKeybindings } : {}),
259
298
  ...(key === "theme" ? { format: (value: unknown) => describeThemeId(String(value)) } : {}),
299
+ ...(key === TIMEZONE_CONFIG_KEY ? { format: describeTimezone } : {}),
260
300
  })),
261
301
  });
262
302
  return;
@@ -274,7 +314,8 @@ export function createSystemCliCommands(): CliCommandDef[] {
274
314
  return;
275
315
  }
276
316
  ctx.printResult({ data: { key, value: safeConfig[key] } }, {
277
- text: (data) => key === KEYBINDINGS_CONFIG_KEY ? renderKeybindings(data.value) : describeConfigValue(data.value),
317
+ text: (data) => key === KEYBINDINGS_CONFIG_KEY ? renderKeybindings(data.value)
318
+ : key === TIMEZONE_CONFIG_KEY ? describeTimezone(data.value) : describeConfigValue(data.value),
278
319
  });
279
320
  return;
280
321
  }
@@ -309,7 +350,9 @@ export function createSystemCliCommands(): CliCommandDef[] {
309
350
  // A display name may come unquoted: config set theme White Phosphor.
310
351
  const parsedValue = key === "theme"
311
352
  ? requireThemeId(args.slice(2).join(" "))
312
- : key === "refreshIntervalMinutes"
353
+ : key === TIMEZONE_CONFIG_KEY
354
+ ? parseTimezoneSetting(value)
355
+ : key === "refreshIntervalMinutes"
313
356
  ? Number(value)
314
357
  : isBooleanConfigKey(key)
315
358
  ? value === "true"
@@ -318,7 +361,9 @@ export function createSystemCliCommands(): CliCommandDef[] {
318
361
  ? { ...context.config, telemetry: { ...context.config.telemetry, [TELEMETRY_CONFIG_KEYS[key]]: parsedValue as boolean } }
319
362
  : key === STAR_PROMPT_CONFIG_KEY
320
363
  ? { ...context.config, starPrompt: { ...context.config.starPrompt, enabled: parsedValue as boolean } }
321
- : { ...context.config, [key]: parsedValue };
364
+ : key === TIMEZONE_CONFIG_KEY
365
+ ? withTimezone(context.config, parsedValue as string | null)
366
+ : { ...context.config, [key]: parsedValue };
322
367
  if (!ctx.cliOptions.dryRun) await saveConfig(nextConfig);
323
368
  ctx.printResult({
324
369
  data: {
@@ -329,7 +374,9 @@ export function createSystemCliCommands(): CliCommandDef[] {
329
374
  ...(key === "theme" ? { name: themeName(String(parsedValue)) } : {}),
330
375
  },
331
376
  }, {
332
- text: (data) => `Set ${key} to ${key === "theme" ? describeThemeId(String(data.value)) : describeConfigValue(data.value)}.${dryRunNote(data.dryRun)}`,
377
+ text: (data) => key === TIMEZONE_CONFIG_KEY && data.value == null
378
+ ? `Cleared timezone: times print in UTC alone.${dryRunNote(data.dryRun)}`
379
+ : `Set ${key} to ${key === "theme" ? describeThemeId(String(data.value)) : describeConfigValue(data.value)}.${dryRunNote(data.dryRun)}`,
333
380
  });
334
381
  return;
335
382
  }