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,9 +1,9 @@
1
1
  import { useEffect, useMemo, useState } from "react";
2
- import { Box, Text } from "../../ui";
2
+ import { Box, Text, useUiHost } from "../../ui";
3
3
  import { type PromptContext, useDialogKeyboard } from "../../ui/dialog";
4
4
  import { useThemeColors } from "../../theme/theme-context";
5
5
  import { t } from "../../i18n";
6
- import { DialogFrame } from "./frame";
6
+ import { DialogFrame, fitDialogWidth } from "./frame";
7
7
  import { ListView, listCursorMove, type ListViewItem } from "./list-view";
8
8
  import { clampIndex } from "../../utils/math";
9
9
 
@@ -53,6 +53,7 @@ export function ChoiceDialog({
53
53
  bgColor,
54
54
  }: ChoiceDialogProps) {
55
55
  const colors = useThemeColors();
56
+ const desktop = useUiHost().kind === "desktop-web";
56
57
  const [index, setIndex] = useState(() =>
57
58
  clampIndex(getInitialChoiceIndex(choices, selectedChoiceId), choices.length, -1)
58
59
  );
@@ -90,7 +91,8 @@ export function ChoiceDialog({
90
91
 
91
92
  return (
92
93
  <DialogFrame title={title} footer={footer} showTitleDivider={false}>
93
- <Box flexDirection="column" width={width}>
94
+ {/* Never wider than the dialog: the terminal's box is 60 columns, a phone narrower than the cells asked for. */}
95
+ <Box flexDirection="column" {...(desktop ? { style: { width: fitDialogWidth(width) } } : { width, maxWidth: "100%" })}>
94
96
  <ListView
95
97
  items={items}
96
98
  selectedIndex={selectedIndex}
@@ -105,7 +107,7 @@ export function ChoiceDialog({
105
107
  onActivate={(_, nextIndex) => activateChoice(choices[nextIndex])}
106
108
  />
107
109
  <Box height={1} />
108
- <Text fg={colors.textDim} wrapText width={width}>{getChoiceDescription(selectedChoice)}</Text>
110
+ <Text fg={colors.textDim} wrapText>{getChoiceDescription(selectedChoice)}</Text>
109
111
  </Box>
110
112
  </DialogFrame>
111
113
  );
@@ -1,11 +1,12 @@
1
- import { useCallback, type ReactNode } from "react";
2
- import { Box, Text } from "../../ui";
1
+ import { useCallback, useRef, type ReactNode } from "react";
2
+ import { Box, Text, useUiHost } from "../../ui";
3
3
  import { colors } from "../../theme/colors";
4
4
  import { t, tf } from "../../i18n";
5
5
  import { type DialogApi, type PromptContext, useDialogKeyboard } from "../../ui/dialog";
6
6
  import { isPlainKey } from "../../utils/keyboard";
7
7
  import { Button, type ButtonVariant } from "./button";
8
- import { DialogFrame } from "./frame";
8
+ import { DialogActions } from "./dialog-actions";
9
+ import { DialogFrame, fitDialogWidth } from "./frame";
9
10
 
10
11
  export interface ConfirmDialogProps extends PromptContext<boolean> {
11
12
  title: string;
@@ -14,7 +15,10 @@ export interface ConfirmDialogProps extends PromptContext<boolean> {
14
15
  cancelLabel?: string;
15
16
  confirmVariant?: ButtonVariant;
16
17
  width?: number;
17
- /** The key-hint line under the buttons; an empty string leaves it out. */
18
+ /**
19
+ * The terminal's key-hint line under the buttons; an empty string leaves it
20
+ * out, and the keys off the desktop buttons too.
21
+ */
18
22
  footer?: string;
19
23
  /** A line under the body: the work the confirm started, or why it failed. */
20
24
  status?: ReactNode;
@@ -27,6 +31,11 @@ export interface ConfirmDialogProps extends PromptContext<boolean> {
27
31
  * action, at the right. By default the action comes first, at the left.
28
32
  */
29
33
  formButtons?: boolean;
34
+ /**
35
+ * How long after opening Enter and `y` do not confirm, for a confirm that
36
+ * opens on its own while the person may be typing. Esc and `n` always answer.
37
+ */
38
+ keyGraceMs?: number;
30
39
  }
31
40
 
32
41
  export function ConfirmDialog({
@@ -42,7 +51,10 @@ export function ConfirmDialog({
42
51
  busy = false,
43
52
  onClose,
44
53
  formButtons = false,
54
+ keyGraceMs = 0,
45
55
  }: ConfirmDialogProps) {
56
+ const desktop = useUiHost().kind === "desktop-web";
57
+ const openedAt = useRef(Date.now());
46
58
  const confirm = useCallback(() => resolve(true), [resolve]);
47
59
  const cancel = useCallback(() => resolve(false), [resolve]);
48
60
 
@@ -61,6 +73,7 @@ export function ConfirmDialog({
61
73
  }
62
74
  if (event.name === "enter" || event.name === "return" || isPlainKey(event, "y")) {
63
75
  event.preventDefault();
76
+ if (Date.now() - openedAt.current < keyGraceMs) return;
64
77
  confirm();
65
78
  return;
66
79
  }
@@ -73,15 +86,19 @@ export function ConfirmDialog({
73
86
  if (event.name === "tab") event.preventDefault();
74
87
  }, { allowEditable: true });
75
88
 
76
- const confirmButton = <Button label={confirmLabel} variant={confirmVariant} disabled={busy} onPress={confirm} />;
77
- const cancelButton = <Button label={cancelLabel} variant="secondary" disabled={busy} onPress={cancel} />;
89
+ // The desktop shows the keys on the buttons instead of a footer line; a
90
+ // confirm with no key line keeps its buttons plain there too.
91
+ const keys = footer !== "";
92
+ const confirmButton = <Button label={confirmLabel} variant={confirmVariant} disabled={busy} desktopShortcut={keys ? "Enter" : undefined} onPress={confirm} />;
93
+ const cancelButton = <Button label={cancelLabel} variant="secondary" disabled={busy} desktopShortcut={keys ? "Esc" : undefined} onPress={cancel} />;
78
94
  return (
79
95
  <DialogFrame
80
96
  title={title}
81
97
  footer={footer ?? tf("Enter {action} · Esc cancel", { action: t(confirmLabel).toLowerCase() })}
98
+ desktopFooter={null}
82
99
  onClose={onClose}
83
100
  >
84
- <Box flexDirection="column" width={width}>
101
+ <Box flexDirection="column" {...(desktop ? { style: { width: fitDialogWidth(width) } } : { width })}>
85
102
  {renderBody(body)}
86
103
  {status && (
87
104
  <>
@@ -90,17 +107,10 @@ export function ConfirmDialog({
90
107
  </>
91
108
  )}
92
109
  <Box height={1} />
93
- {formButtons ? (
94
- <Box flexDirection="row" gap={1} justifyContent="flex-end">
95
- {cancelButton}
96
- {confirmButton}
97
- </Box>
98
- ) : (
99
- <Box flexDirection="row" gap={1}>
100
- {confirmButton}
101
- {cancelButton}
102
- </Box>
103
- )}
110
+ <DialogActions alignEnd={formButtons}>
111
+ {formButtons ? cancelButton : confirmButton}
112
+ {formButtons ? confirmButton : cancelButton}
113
+ </DialogActions>
104
114
  </Box>
105
115
  </DialogFrame>
106
116
  );
@@ -126,19 +126,31 @@ function resolveTableIndex<T, C extends DataTableColumn>(
126
126
  * Every row as a report reads it: the key, whether it is selected and each
127
127
  * column's text, the same text the cells draw. Captured with the semantic
128
128
  * snapshot, so a row scrolled out of the viewport still reaches the report.
129
+ * A section header sits in the first column and a time cell carries the
130
+ * instant behind its short text, as the capture of a drawn row reads them.
129
131
  */
130
132
  function reportedRows<T, C extends DataTableColumn>(props: DataTableProps<T, C>) {
131
133
  const normalize = (text: string) => text.replace(/\s+/g, " ").trim();
134
+ const first = props.columns[0];
132
135
  return props.items.map((item, index) => {
133
136
  const selected = props.isSelected(item, index);
134
137
  const section = props.renderSectionHeader?.(item, index);
135
138
  const cells = section
136
- ? [{ columnLabel: "Row", text: normalize(section.text) }]
137
- : props.columns.map((column) => ({
138
- columnId: column.id,
139
- columnLabel: column.label,
140
- text: normalize(props.renderCell(item, column, index, { selected }).text),
141
- }));
139
+ ? [{
140
+ ...(first ? { columnId: first.id } : {}),
141
+ columnLabel: first?.label ?? "Row",
142
+ text: normalize(section.action ? `${section.text} ${section.action.label}` : section.text),
143
+ }]
144
+ : props.columns.map((column) => {
145
+ const cell = props.renderCell(item, column, index, { selected });
146
+ return {
147
+ columnId: column.id,
148
+ columnLabel: column.label,
149
+ text: normalize(cell.text),
150
+ ...(cell.value instanceof Date && Number.isFinite(cell.value.getTime()) ? { instant: cell.value.toISOString() } : {}),
151
+ ...(typeof cell.value === "number" && Number.isFinite(cell.value) ? { value: cell.value } : {}),
152
+ };
153
+ });
142
154
  return { key: props.getItemKey(item, index), selected, cells: cells.filter((cell) => cell.text.length > 0) };
143
155
  });
144
156
  }
@@ -72,11 +72,14 @@ function OpenTuiDataTableRowInner<
72
72
  renderCell,
73
73
  renderSectionHeader,
74
74
  rowContextMenuSurface,
75
+ sectionWidth,
75
76
  selected,
76
77
  selectedTextOverridesCellColor,
77
78
  }: {
78
79
  /** Only compared by the row memo; see `getRowVersion`. */
79
80
  rowVersion?: unknown;
81
+ /** Columns of the row in view, which a section header's action keeps to. */
82
+ sectionWidth: number;
80
83
  colors: ReturnType<typeof useThemeColors>;
81
84
  columnGap: number;
82
85
  columnStarts: number[];
@@ -108,6 +111,7 @@ function OpenTuiDataTableRowInner<
108
111
  if (sectionHeader) {
109
112
  // A header the cursor can land on (a collapsible group) shows it like a row.
110
113
  const headerColor = sectionHeader.color ?? (selected ? colors.selectedText : colors.textBright);
114
+ const action = sectionHeader.action;
111
115
  return (
112
116
  <Box
113
117
  flexDirection="row"
@@ -125,12 +129,37 @@ function OpenTuiDataTableRowInner<
125
129
  {sectionHeader.expanded !== undefined && (
126
130
  <Text fg={headerColor}>{sectionHeader.expanded ? "\u25be " : "\u25b8 "}</Text>
127
131
  )}
128
- <Text
129
- attributes={sectionHeader.attributes ?? TextAttributes.BOLD}
130
- fg={headerColor}
131
- >
132
- {sectionHeader.text}
133
- </Text>
132
+ {action ? (
133
+ // Kept to the columns in view, so a table wider than its pane does not push the action out of sight.
134
+ <Box flexDirection="row" height={1} flexShrink={1} minWidth={0} width={Math.max(1, sectionWidth - horizontalPadding * 2)}>
135
+ <Text attributes={sectionHeader.attributes ?? TextAttributes.BOLD} fg={headerColor} wrapMode="none" truncate flexShrink={1} minWidth={0}>
136
+ {sectionHeader.text}
137
+ </Text>
138
+ <Box flexGrow={1} minWidth={1} />
139
+ <Box
140
+ flexShrink={0}
141
+ height={1}
142
+ cursor="pointer"
143
+ hoverBackgroundColor={selected ? undefined : hoverBg(colors)}
144
+ onMouseDown={(event: any) => {
145
+ // The action, not the header's own press (a group's collapse).
146
+ event.stopPropagation?.();
147
+ event.preventDefault?.();
148
+ focusPane();
149
+ action.onPress();
150
+ }}
151
+ >
152
+ <Text fg={selected ? colors.selectedText : colors.text}>{action.label}</Text>
153
+ </Box>
154
+ </Box>
155
+ ) : (
156
+ <Text
157
+ attributes={sectionHeader.attributes ?? TextAttributes.BOLD}
158
+ fg={headerColor}
159
+ >
160
+ {sectionHeader.text}
161
+ </Text>
162
+ )}
134
163
  </Box>
135
164
  );
136
165
  }
@@ -320,6 +349,7 @@ export function OpenTuiDataTable<T, C extends DataTableColumn = DataTableColumn>
320
349
  const horizontalScrollbarVisible = showHorizontalScrollbar
321
350
  && hasMeaningfulTableHorizontalOverflow(tableWidth, measuredViewportWidth, columnGap);
322
351
  const contentWidth = fillAvailableWidth ? measuredContentWidth : tableWidth;
352
+ const sectionWidth = measuredViewportWidth > 0 ? Math.min(contentWidth, measuredViewportWidth) : contentWidth;
323
353
  const displayColumns = useMemo(
324
354
  () => expandTableColumns(columns, contentWidth, columnGap, horizontalPadding),
325
355
  [columnGap, columns, contentWidth, horizontalPadding],
@@ -634,6 +664,7 @@ export function OpenTuiDataTable<T, C extends DataTableColumn = DataTableColumn>
634
664
  renderSectionHeader={renderSectionHeader}
635
665
  rowContextMenuSurface={rowContextMenuSurface}
636
666
  rowVersion={getRowVersion?.(item, index)}
667
+ sectionWidth={sectionWidth}
637
668
  selected={isSelected(item, index)}
638
669
  selectedTextOverridesCellColor={selectedTextOverridesCellColor}
639
670
  />
@@ -58,6 +58,18 @@ export interface DataTableSectionHeader {
58
58
  * `onMouseDown` instead of `onActivate`.
59
59
  */
60
60
  expanded?: boolean;
61
+ /**
62
+ * A quiet control at the right end of the header that acts on the whole
63
+ * group, such as the preset its rows are set to. A header is not a stop for
64
+ * the cursor, so the pane gives the same action a key (a footer hint).
65
+ */
66
+ action?: {
67
+ /** What the control says, already translated: the group's current setting. */
68
+ label: string;
69
+ /** Desktop tooltip: what pressing it does. */
70
+ title?: string;
71
+ onPress: () => void;
72
+ };
61
73
  }
62
74
 
63
75
  /** Where `scrollToIndex` puts its row: the nearest edge, the middle, or the top of the viewport. */
@@ -0,0 +1,64 @@
1
+ import { type ComponentType, type ReactNode } from "react";
2
+ import { Box, Text, useUiHost } from "../../ui";
3
+ import { t } from "../../i18n";
4
+ import { useThemeColors } from "../../theme/theme-context";
5
+ import type { DialogDesktopFooter, DialogKeyHint } from "./frame";
6
+
7
+ export interface DialogActionsProps {
8
+ /** The dialog's buttons. */
9
+ children: ReactNode;
10
+ /** The buttons sit at the right, as a form's Cancel and Submit do. */
11
+ alignEnd?: boolean;
12
+ /** Buttons that do not fit wrap to another row. */
13
+ wrap?: boolean;
14
+ /**
15
+ * Desktop and web: keys no button carries and a quiet note, across from
16
+ * the buttons. The terminal says these in the dialog's footer line.
17
+ */
18
+ hints?: DialogDesktopFooter;
19
+ }
20
+
21
+ /**
22
+ * The row of buttons that answers a dialog. On the desktop and the web the
23
+ * buttons show their keys and `hints` sit on the same row, so the dialog
24
+ * needs no key line under it.
25
+ */
26
+ export function DialogActions({ children, alignEnd = false, wrap = false, hints }: DialogActionsProps) {
27
+ const HostDialogActions = useUiHost().DialogActions as ComponentType<DialogActionsProps> | undefined;
28
+ if (HostDialogActions) {
29
+ return <HostDialogActions alignEnd={alignEnd} wrap={wrap} hints={hints}>{children}</HostDialogActions>;
30
+ }
31
+ return (
32
+ <Box
33
+ flexDirection="row"
34
+ gap={1}
35
+ {...(alignEnd ? { justifyContent: "flex-end" as const } : {})}
36
+ {...(wrap ? { flexWrap: "wrap" as const } : {})}
37
+ >
38
+ {children}
39
+ </Box>
40
+ );
41
+ }
42
+
43
+ export interface DialogHintsProps {
44
+ keys?: DialogKeyHint[];
45
+ note?: string;
46
+ }
47
+
48
+ /**
49
+ * Keys and a note for a dialog that has no button to put them on, such as a
50
+ * sign-in code waiting for a phone: keycaps on the desktop and the web, one
51
+ * muted line in the terminal.
52
+ */
53
+ export function DialogHints({ keys = [], note }: DialogHintsProps) {
54
+ const colors = useThemeColors();
55
+ const HostDialogHints = useUiHost().DialogHints as ComponentType<DialogHintsProps> | undefined;
56
+ if (HostDialogHints) return <HostDialogHints keys={keys} note={note} />;
57
+ const parts = [...keys.map((hint) => `${hint.key} ${t(hint.label)}`), ...(note ? [t(note)] : [])];
58
+ if (parts.length === 0) return null;
59
+ return (
60
+ <Box height={1}>
61
+ <Text fg={colors.textMuted}>{parts.join(" · ")}</Text>
62
+ </Box>
63
+ );
64
+ }
@@ -1,9 +1,10 @@
1
1
  import type { ReactNode } from "react";
2
2
  import { t } from "../../i18n";
3
- import { blendHex } from "../../theme/colors";
3
+ import { blendHex, hoverBg } from "../../theme/colors";
4
4
  import { useThemeColors } from "../../theme/theme-context";
5
5
  import { Box, Text, TextAttributes, useUiCapabilities } from "../../ui";
6
6
  import { truncateToDisplayWidth } from "../../utils/format";
7
+ import { usePaneLinkMenuEntry } from "./external-link";
7
8
  import { titleCase } from "./header-case";
8
9
  import { statToneColor, type StatTone } from "./stat-grid";
9
10
 
@@ -55,11 +56,24 @@ export interface KeyValueRowProps {
55
56
  width?: number;
56
57
  labelWidth?: number;
57
58
  emphasis?: boolean;
59
+ /**
60
+ * Opens what the value names (a security's DES, a function): the whole row is the target, and inside a
61
+ * `PaneLinkMenu` the pane menu lists it as `link.label`, so the keyboard reaches what a click opens.
62
+ */
63
+ link?: { label: string; onOpen: () => void };
58
64
  }
59
65
 
60
66
  /** Aligned labels and values; a bounded row reserves room for an optional detail. */
61
- export function KeyValueRow({ label, value, detail, tone, color, width, labelWidth, emphasis = true }: KeyValueRowProps) {
67
+ export function KeyValueRow({ label, value, detail, tone, color, width, labelWidth, emphasis = true, link }: KeyValueRowProps) {
62
68
  const colors = useThemeColors();
69
+ usePaneLinkMenuEntry(link ? `key-value:${label}:${value}` : null, link?.label ?? "", () => link?.onOpen());
70
+ const target = link ? {
71
+ cursor: "pointer" as const,
72
+ hoverBackgroundColor: hoverBg(colors),
73
+ onMouseDown: (event?: { button?: number }) => { if ((event?.button ?? 0) === 0) link.onOpen(); },
74
+ "data-gloom-interactive": "true",
75
+ "data-gloom-label": link.label,
76
+ } : {};
63
77
  const rowWidth = width === undefined ? undefined : Math.max(0, Math.floor(width));
64
78
  const preferredLabelWidth = Math.max(0, labelWidth ?? (rowWidth === undefined ? 14 : Math.min(12, Math.max(8, Math.floor(rowWidth * 0.32)))));
65
79
  const labelColumns = rowWidth === undefined ? preferredLabelWidth : Math.min(preferredLabelWidth, Math.max(0, rowWidth - 1));
@@ -69,7 +83,7 @@ export function KeyValueRow({ label, value, detail, tone, color, width, labelWid
69
83
  : availableWidth;
70
84
  const detailWidth = availableWidth === undefined ? undefined : availableWidth - valueWidth!;
71
85
  return (
72
- <Box height={1} width={rowWidth} flexDirection="row" overflow="hidden" data-gloom-ui="key-value-row">
86
+ <Box height={1} width={rowWidth} flexDirection="row" overflow="hidden" data-gloom-ui="key-value-row" {...target}>
73
87
  <Box width={labelColumns} flexShrink={0} overflow="hidden">
74
88
  <Text fg={colors.textDim}>{t(label)}</Text>
75
89
  </Box>
@@ -32,12 +32,45 @@ export function modalSurfaceStyle(colors: ThemeColors, options: ModalSurfaceOpti
32
32
  };
33
33
  }
34
34
 
35
+ /** A key and what it does, drawn on the desktop and the web as a keycap and a word. */
36
+ export interface DialogKeyHint {
37
+ /** As the terminal names it: "Enter", "Esc", "Shift+Enter", "Tab", "↑↓", "y". */
38
+ key: string;
39
+ /** What it does, short and lowercase; translated where it is drawn. */
40
+ label: string;
41
+ }
42
+
43
+ /**
44
+ * What a dialog's footer says on the desktop and the web. The buttons there
45
+ * carry their own keys, so this keeps only keys no button has and a quiet
46
+ * note, such as a deadline.
47
+ */
48
+ export interface DialogDesktopFooter {
49
+ keys?: DialogKeyHint[];
50
+ /** After the keys; translated where it is drawn. */
51
+ note?: string;
52
+ }
53
+
54
+ /**
55
+ * Desktop and web: the width of a dialog body laid out `columns` cells wide,
56
+ * narrowed to fit a phone, where the fixed width would run past the edge.
57
+ */
58
+ export function fitDialogWidth(columns: number): string {
59
+ return `min(calc(var(--cell-w) * ${columns}), calc(100vw - 80px))`;
60
+ }
61
+
35
62
  export interface DialogFrameProps {
36
63
  title: string;
37
64
  /** Muted line under the title. */
38
65
  subtitle?: string;
39
66
  children: ReactNode;
67
+ /** The terminal's key line under the dialog. */
40
68
  footer?: string;
69
+ /**
70
+ * Desktop and web: what shows instead of `footer`; `null` shows nothing.
71
+ * Left out, `footer` shows there as one quiet line.
72
+ */
73
+ desktopFooter?: DialogDesktopFooter | null;
41
74
  showTitleDivider?: boolean;
42
75
  /** Adds a close button at the right of the title (desktop). Esc still closes every dialog. */
43
76
  onClose?: () => void;
@@ -48,14 +81,14 @@ export interface DialogFrameProps {
48
81
  shrinkable?: boolean;
49
82
  }
50
83
 
51
- export function DialogFrame({ title: rawTitle, subtitle, children, footer: rawFooter, showTitleDivider = false, onClose, shrinkable }: DialogFrameProps) {
84
+ export function DialogFrame({ title: rawTitle, subtitle, children, footer: rawFooter, desktopFooter, showTitleDivider = false, onClose, shrinkable }: DialogFrameProps) {
52
85
  const title = t(rawTitle);
53
86
  const footer = rawFooter === undefined ? undefined : t(rawFooter);
54
87
  const colors = useThemeColors();
55
88
  const HostDialogFrame = useUiHost().DialogFrame as ComponentType<DialogFrameProps> | undefined;
56
89
  if (HostDialogFrame) {
57
90
  return (
58
- <HostDialogFrame title={title} subtitle={subtitle} footer={footer} showTitleDivider={showTitleDivider} onClose={onClose} shrinkable={shrinkable}>
91
+ <HostDialogFrame title={title} subtitle={subtitle} footer={footer} desktopFooter={desktopFooter} showTitleDivider={showTitleDivider} onClose={onClose} shrinkable={shrinkable}>
59
92
  {children}
60
93
  </HostDialogFrame>
61
94
  );
@@ -6,6 +6,7 @@ import { t } from "../../i18n";
6
6
 
7
7
  export type IconName =
8
8
  | "more"
9
+ | "help"
9
10
  | "close"
10
11
  | "zap"
11
12
  | "sqrt"
@@ -29,11 +30,13 @@ export type IconName =
29
30
  | "grip"
30
31
  | "image"
31
32
  | "thumbs-up"
32
- | "thumbs-down";
33
+ | "thumbs-down"
34
+ | "ask";
33
35
 
34
36
  /** Terminal glyph for each icon; the desktop host draws SVG. */
35
37
  export const ICON_GLYPHS: Record<IconName, string> = {
36
38
  more: "...",
39
+ help: "?",
37
40
  close: "x",
38
41
  zap: "⚡",
39
42
  sqrt: "√",
@@ -60,6 +63,8 @@ export const ICON_GLYPHS: Record<IconName, string> = {
60
63
  // show which thumb is chosen.
61
64
  "thumbs-up": "+1",
62
65
  "thumbs-down": "-1",
66
+ // Ask Gloom: a four-point spark.
67
+ ask: "✦",
63
68
  };
64
69
 
65
70
  export interface IconProps {
@@ -12,6 +12,7 @@ import { SelectButton, type SelectButtonOption, type SelectControl } from "./sel
12
12
  import { SegmentedControl } from "./toggle";
13
13
  import { Tabs } from "./tabs";
14
14
  import { useQueryBarKeys } from "./query-bar-keys";
15
+ import { useCaptureDatesData } from "../layout/pane/capture-status";
15
16
 
16
17
  export interface QueryBarSearch {
17
18
  value: string;
@@ -121,6 +122,12 @@ export interface QueryBarProps {
121
122
  view?: QueryBarView<any>;
122
123
  /** Muted context at the right edge (the selected row's date). Not for status. */
123
124
  meta?: string;
125
+ /**
126
+ * The date the data is as of (`as of 2026-10-09`), shown where `meta` is
127
+ * when there is none. A `gloomberb shot` whose status line dates the data
128
+ * leaves it out, so the date is said once.
129
+ */
130
+ asOf?: string;
124
131
  }
125
132
 
126
133
  /** Beyond this many options a terminal strip scrolls instead of segmenting. */
@@ -217,8 +224,10 @@ export function useQueryBarSearch(): QueryBarSearchFocus {
217
224
  * same everywhere. The desktop draws soft chips with menus; the terminal keeps
218
225
  * text controls and the choice dialogs.
219
226
  */
220
- export function QueryBar({ width, search, filters = [], view, meta }: QueryBarProps) {
227
+ export function QueryBar({ width, search, filters = [], view, meta: given, asOf }: QueryBarProps) {
221
228
  const ui = useUiHost();
229
+ const captureDatesData = useCaptureDatesData();
230
+ const meta = given ?? (captureDatesData ? undefined : asOf);
222
231
  const colors = useThemeColors();
223
232
  const HostQueryBar = ui.QueryBar as ComponentType<HostQueryBarProps> | undefined;
224
233
  const localInputRef = useRef<InputRenderable | null>(null);
@@ -4,8 +4,9 @@ import { t } from "../../i18n";
4
4
  import { useDialogKeyboard, type PromptContext } from "../../ui/dialog";
5
5
  import { useThemeColors } from "../../theme/theme-context";
6
6
  import { Button } from "./button";
7
+ import { DialogActions } from "./dialog-actions";
7
8
  import { FRAMED_TEXTAREA_DESKTOP_STYLE, TextField } from "./fields";
8
- import { DialogFrame } from "./frame";
9
+ import { DialogFrame, fitDialogWidth } from "./frame";
9
10
 
10
11
  export interface TextPromptDialogProps extends PromptContext<string> {
11
12
  title: string;
@@ -24,6 +25,7 @@ export interface TextPromptDialogProps extends PromptContext<string> {
24
25
  /** Empty is an answer (clearing a value) rather than nothing to save. */
25
26
  allowEmpty?: boolean;
26
27
  width?: number;
28
+ /** The terminal's key line; the desktop shows the keys on the buttons. */
27
29
  footer?: string;
28
30
  }
29
31
 
@@ -80,10 +82,10 @@ export function TextPromptDialog({
80
82
 
81
83
  const shownPlaceholder = placeholder ? t(placeholder) : "";
82
84
  return (
83
- <DialogFrame title={title} footer={footer}>
84
- <Box flexDirection="column" width={width}>
85
+ <DialogFrame title={title} footer={footer} desktopFooter={null}>
86
+ <Box flexDirection="column" {...(nativePaneChrome ? { style: { width: fitDialogWidth(width) } } : { width })}>
85
87
  {body?.map((line, index) => (
86
- <Text key={index} fg={colors.textDim} wrapText width={width}>{line ? t(line) : " "}</Text>
88
+ <Text key={index} fg={colors.textDim} wrapText width={nativePaneChrome ? undefined : width}>{line ? t(line) : " "}</Text>
87
89
  ))}
88
90
  {body && body.length > 0 && <Box height={1} />}
89
91
  {multiline ? (
@@ -116,17 +118,17 @@ export function TextPromptDialog({
116
118
  value={value}
117
119
  placeholder={shownPlaceholder}
118
120
  focused
119
- width={width}
121
+ width={nativePaneChrome ? undefined : width}
120
122
  onChange={setValue}
121
123
  onSubmit={submit}
122
124
  />
123
125
  )}
124
126
  <Box height={1} />
125
- <Box flexDirection="row" gap={1}>
127
+ <DialogActions hints={multiline ? { keys: [{ key: "Shift+Enter", label: "newline" }] } : undefined}>
126
128
  {/* A textarea is read when it submits, so its button stays live. */}
127
- <Button label={confirmLabel} variant="primary" disabled={!multiline && !allowEmpty && !value.trim()} onPress={() => submit(current())} />
128
- <Button label="Cancel" variant="secondary" onPress={dismiss} />
129
- </Box>
129
+ <Button label={confirmLabel} variant="primary" desktopShortcut="Enter" disabled={!multiline && !allowEmpty && !value.trim()} onPress={() => submit(current())} />
130
+ <Button label="Cancel" variant="secondary" desktopShortcut="Esc" onPress={dismiss} />
131
+ </DialogActions>
130
132
  </Box>
131
133
  </DialogFrame>
132
134
  );
@@ -11,6 +11,8 @@ export interface CachedValue<T> {
11
11
  source: string;
12
12
  /** Source observation time, when supplied; fetchedAt remains retrieval time. */
13
13
  asOf?: number;
14
+ /** How far a delayed source runs behind the market, in minutes; 0 for a real-time one. */
15
+ delayMinutes?: number;
14
16
  refreshError?: unknown;
15
17
  }
16
18
 
@@ -18,6 +18,7 @@ import {
18
18
  } from "../chart-settings";
19
19
  import { sanitizeLayout } from "../layout";
20
20
  import { foldSavedPanes } from "./fold-panes";
21
+ import { migratePortfolioAsOfColumn } from "./portfolio-as-of-column";
21
22
  import { sanitizeSavedPaneState } from "./pane-state";
22
23
  import { isRecord } from "../../../utils/guards";
23
24
 
@@ -28,6 +29,7 @@ const UNREACHABLE_PANE_CLEANUP_CONFIG_VERSION = 22;
28
29
  const MARKET_OVERVIEW_ABSORBED_CONFIG_VERSION = 23;
29
30
  const IPO_CALENDAR_ABSORBED_CONFIG_VERSION = 24;
30
31
  const FOLDED_PANES_CONFIG_VERSION = 25;
32
+ const PORTFOLIO_AS_OF_COLUMN_CONFIG_VERSION = 26;
31
33
 
32
34
  /** What a migration may ask of the machine the config is loaded on. */
33
35
  export interface ConfigMigrationHost {
@@ -87,6 +89,11 @@ const CONFIG_MIGRATIONS: readonly ConfigMigration[] = [
87
89
  toVersion: FOLDED_PANES_CONFIG_VERSION,
88
90
  migrate: foldSavedPanes,
89
91
  },
92
+ {
93
+ name: "portfolio-as-of-column",
94
+ toVersion: PORTFOLIO_AS_OF_COLUMN_CONFIG_VERSION,
95
+ migrate: migratePortfolioAsOfColumn,
96
+ },
90
97
  ];
91
98
 
92
99
  export function migrateSavedConfig(
@@ -90,6 +90,7 @@ export function normalizeLoadedConfig(
90
90
  seededPlugins: sanitizeUniqueStringList(candidate.seededPlugins),
91
91
  ...(candidate.portfolioCurrenciesAdopted === true ? { portfolioCurrenciesAdopted: true } : {}),
92
92
  ...(candidate.presentationMode === true ? { presentationMode: true } : {}),
93
+ ...(typeof candidate.timezone === "string" && candidate.timezone.trim() ? { timezone: candidate.timezone.trim() } : {}),
93
94
  disabledSources: sanitizeUniqueStringList(candidate.disabledSources ?? defaults.disabledSources),
94
95
  pluginConfig: sanitizePluginConfig(candidate.pluginConfig),
95
96
  theme: sanitizeTheme(candidate.theme, defaults.theme),
@@ -348,10 +349,14 @@ function sanitizePortfolios(value: unknown, fallback: Portfolio[]): Portfolio[]
348
349
  .map(sanitizePortfolioAllocation);
349
350
  }
350
351
 
351
- /** Cash and target weights the portfolio commands write; anything else is dropped. */
352
+ /** Cash, target weights and the import source the portfolio commands write; a malformed one is dropped. */
352
353
  function sanitizePortfolioAllocation(entry: Portfolio): Portfolio {
353
- const { cash, targetWeights, ...portfolio } = entry;
354
+ const { cash, targetWeights, importedFrom, ...portfolio } = entry;
354
355
  const next: Portfolio = { ...portfolio };
356
+ if (isRecord(importedFrom) && importedFrom.kind === "13f"
357
+ && [importedFrom.cik, importedFrom.name, importedFrom.period, importedFrom.filed].every((value) => typeof value === "string" && value)) {
358
+ next.importedFrom = { kind: "13f", cik: importedFrom.cik, name: importedFrom.name, period: importedFrom.period, filed: importedFrom.filed };
359
+ }
355
360
  if (isRecord(cash) && typeof cash.amount === "number" && Number.isFinite(cash.amount)
356
361
  && typeof cash.currency === "string" && /^[A-Z]{3}$/.test(cash.currency)) {
357
362
  next.cash = { amount: cash.amount, currency: cash.currency };