gloomberb 0.16.3 → 0.16.5

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 (820) hide show
  1. package/README.md +14 -91
  2. package/package.json +7 -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 +42 -17
  11. package/src/account/upgrade-personalization.ts +57 -0
  12. package/src/account/upgrade-tickers.ts +124 -0
  13. package/src/{plugins/builtin/cloud → account}/verification-panel.tsx +6 -6
  14. package/src/api-client/askg.ts +43 -0
  15. package/src/api-client/auth.ts +15 -0
  16. package/src/api-client/beneficial-owners.ts +4 -0
  17. package/src/api-client/chat.ts +19 -0
  18. package/src/api-client/company-kpis.ts +14 -2
  19. package/src/api-client/data.ts +58 -18
  20. package/src/api-client/earnings.ts +6 -0
  21. package/src/api-client/futures-curve.ts +56 -0
  22. package/src/api-client/index.ts +16 -1
  23. package/src/api-client/market-discovery.ts +10 -1
  24. package/src/api-client/normalizers.ts +27 -0
  25. package/src/api-client/paths.ts +95 -23
  26. package/src/api-client/request.ts +2 -1
  27. package/src/api-client/research-activity.ts +46 -10
  28. package/src/api-client/socket.ts +39 -8
  29. package/src/api-client/types.ts +74 -2
  30. package/src/api-client/upgrade-experiment.ts +90 -0
  31. package/src/api-client/yield-curves.ts +8 -0
  32. package/src/app/global-shortcuts.ts +26 -2
  33. package/src/app/keybindings/actions.ts +10 -0
  34. package/src/app/pane-runtime/index.tsx +8 -0
  35. package/src/app/pane-runtime/pane-template-runtime.ts +5 -0
  36. package/src/app/pane-runtime/plugin-bindings.ts +65 -25
  37. package/src/app/pane-runtime/ticker-inspector-runtime.ts +12 -0
  38. package/src/app/pane-runtime/ticker-open-runtime.ts +25 -4
  39. package/src/app/runtime/desktop-deeplink.ts +5 -0
  40. package/src/app/star-prompt/model.ts +98 -0
  41. package/src/app/star-prompt/runtime.ts +41 -0
  42. package/src/app/star-prompt/status-line.tsx +190 -0
  43. package/src/app.tsx +13 -7
  44. package/src/architecture/core-builtin-allowlist.json +61 -0
  45. package/src/brokers/signed-in/adapter.ts +33 -2
  46. package/src/brokers/signed-in/client.ts +10 -0
  47. package/src/brokers/signed-in/sign-in-dialog.tsx +34 -14
  48. package/src/brokers/signed-in/sign-in.ts +62 -5
  49. package/src/capabilities/chart-series.ts +11 -1
  50. package/src/capabilities/registry.ts +8 -1
  51. package/src/capabilities/types.ts +2 -0
  52. package/src/cli/commands/crypto-hints.ts +19 -4
  53. package/src/cli/commands/fred-series.ts +61 -0
  54. package/src/cli/commands/market.ts +744 -181
  55. package/src/cli/commands/news-hints.ts +62 -0
  56. package/src/cli/commands/news-search.ts +53 -0
  57. package/src/cli/commands/options-chain.ts +172 -0
  58. package/src/cli/commands/options-leaps.ts +425 -0
  59. package/src/cli/commands/overview.ts +251 -40
  60. package/src/cli/commands/remote.ts +2 -1
  61. package/src/cli/commands/search.ts +109 -15
  62. package/src/cli/commands/system.ts +151 -24
  63. package/src/cli/commands/themes.ts +64 -0
  64. package/src/cli/commands/ticker.ts +149 -40
  65. package/src/cli/context.ts +45 -14
  66. package/src/cli/desktop-pane-shot.ts +150 -17
  67. package/src/cli/earnings-calendar.ts +71 -0
  68. package/src/cli/errors.ts +25 -2
  69. package/src/cli/freshness.ts +22 -8
  70. package/src/cli/fx-pair.ts +57 -0
  71. package/src/cli/glossary.ts +429 -0
  72. package/src/cli/help.ts +14 -1
  73. package/src/cli/history-rows.ts +48 -7
  74. package/src/cli/index-roots.ts +58 -0
  75. package/src/cli/index.ts +29 -12
  76. package/src/cli/known-gaps.ts +27 -0
  77. package/src/cli/listing-arg.ts +595 -26
  78. package/src/cli/not-a-ticker.ts +44 -0
  79. package/src/cli/options.ts +50 -6
  80. package/src/cli/pane-functions/access-gate.ts +5 -0
  81. package/src/cli/pane-functions/capabilities.ts +11 -4
  82. package/src/cli/pane-functions/catalog.ts +48 -7
  83. package/src/cli/pane-functions/data.ts +48 -13
  84. package/src/cli/pane-functions/discovery.ts +1 -0
  85. package/src/cli/pane-functions/dom.ts +41 -19
  86. package/src/cli/pane-functions/freshness.ts +531 -32
  87. package/src/cli/pane-functions/function-help.ts +77 -25
  88. package/src/cli/pane-functions/headless.ts +50 -21
  89. package/src/cli/pane-functions/index.ts +66 -10
  90. package/src/cli/pane-functions/market-session.ts +147 -0
  91. package/src/cli/pane-functions/options.ts +77 -25
  92. package/src/cli/pane-functions/report-notices.ts +81 -0
  93. package/src/cli/pane-functions/report.ts +19 -8
  94. package/src/cli/pane-functions/resolver.ts +53 -18
  95. package/src/cli/pane-functions/screenshot-evidence.ts +2 -0
  96. package/src/cli/pane-functions/screenshot.ts +199 -30
  97. package/src/cli/registry.ts +2 -1
  98. package/src/cli/report-tables.ts +3 -0
  99. package/src/cli/result.ts +53 -13
  100. package/src/cli/row-window.ts +76 -0
  101. package/src/cli/scroll-truncation.ts +34 -0
  102. package/src/cli/staged-tickers.ts +52 -0
  103. package/src/cli/symbol-args.ts +9 -0
  104. package/src/cli/symbol-list.ts +172 -0
  105. package/src/cli/ticker-resolution.ts +223 -30
  106. package/src/cli/types.ts +5 -0
  107. package/src/components/chart/composite/axis-overlays.tsx +6 -2
  108. package/src/components/chart/composite/composite-chart.tsx +83 -10
  109. package/src/components/chart/composite/legend.tsx +88 -8
  110. package/src/components/chart/composite/panel-surface.tsx +44 -17
  111. package/src/components/chart/composite/price-axis-labels.tsx +3 -1
  112. package/src/components/chart/composite/rasterizer.ts +64 -4
  113. package/src/components/chart/composite/series-cues.ts +71 -0
  114. package/src/components/chart/composite/text-renderer.ts +16 -8
  115. package/src/components/chart/composite/types.ts +3 -0
  116. package/src/components/command-bar/commands/direct/index.ts +9 -1
  117. package/src/components/command-bar/commands/plugin/items.ts +3 -1
  118. package/src/components/command-bar/commands/registry.ts +7 -0
  119. package/src/components/command-bar/layout-items/focused-pane.ts +38 -0
  120. package/src/components/command-bar/pane-templates/workflow.ts +5 -0
  121. package/src/components/command-bar/panel/index.tsx +11 -3
  122. package/src/components/command-bar/panel/runtime.ts +3 -0
  123. package/src/components/command-bar/panel/types.ts +2 -0
  124. package/src/components/command-bar/routes/root/command-items.ts +2 -0
  125. package/src/components/command-bar/routes/root/plugin-turn-on.ts +92 -0
  126. package/src/components/command-bar/routes/root/provider-search.ts +4 -3
  127. package/src/components/command-bar/routes/root/results.ts +40 -10
  128. package/src/components/command-bar/routes/root/runtime.ts +8 -0
  129. package/src/components/command-bar/routes/root/search-providers.ts +97 -14
  130. package/src/components/command-bar/routes/ticker-search/results.ts +12 -11
  131. package/src/components/command-bar/routes/ticker-search/route.ts +4 -3
  132. package/src/components/command-bar/surface/index.tsx +18 -4
  133. package/src/components/command-bar/theme-picker.tsx +48 -13
  134. package/src/components/command-bar/workflow/ops.ts +5 -3
  135. package/src/components/command-bar/workflow/tickers.ts +23 -4
  136. package/src/components/data-table/view.tsx +28 -9
  137. package/src/components/layout/detached-pane-shell.tsx +9 -0
  138. package/src/components/layout/floating-pane.tsx +9 -2
  139. package/src/components/layout/header.tsx +20 -5
  140. package/src/components/layout/market-summary.ts +23 -9
  141. package/src/components/layout/pane/content.tsx +40 -29
  142. package/src/components/layout/pane/cycle-order.ts +2 -11
  143. package/src/components/layout/pane/footer/index.tsx +6 -2
  144. package/src/components/layout/pane/footer/model.ts +35 -1
  145. package/src/components/layout/pane/header.tsx +26 -2
  146. package/src/components/layout/pane/index.tsx +12 -2
  147. package/src/components/layout/pane/sidebar.tsx +78 -10
  148. package/src/components/layout/pane/title.ts +1 -1
  149. package/src/components/layout/presentation.ts +22 -0
  150. package/src/components/layout/shell/active-drag.ts +21 -5
  151. package/src/components/layout/shell/drag/index.ts +43 -9
  152. package/src/components/layout/shell/drag/live.ts +87 -6
  153. package/src/components/layout/shell/drag/runtime.ts +62 -20
  154. package/src/components/layout/shell/index.tsx +71 -12
  155. package/src/components/layout/shell/layout-state.ts +5 -11
  156. package/src/components/layout/shell/menu.ts +33 -1
  157. package/src/components/layout/shell/native/pointer-runtime.ts +3 -1
  158. package/src/components/layout/shell/pane/actions.ts +2 -1
  159. package/src/components/layout/shell/pane/layers.tsx +216 -28
  160. package/src/components/layout/shell/pane/management-shortcuts.ts +5 -0
  161. package/src/components/layout/shell/pane/new-layout.ts +116 -0
  162. package/src/components/layout/shell/shortcuts.ts +5 -2
  163. package/src/components/layout/shell/terminal-pointer-runtime.ts +24 -0
  164. package/src/components/layout/shell/visible-layout.ts +44 -1
  165. package/src/components/layout/status-bar.tsx +4 -1
  166. package/src/components/markdown-text.tsx +69 -23
  167. package/src/components/metric-treemap/heat-surface.tsx +37 -9
  168. package/src/components/metric-treemap/heat-tiles.ts +48 -17
  169. package/src/components/onboarding/account-step/form-panel.tsx +1 -1
  170. package/src/components/onboarding/account-step/index.tsx +1 -1
  171. package/src/components/onboarding/account-step/qr-panel.tsx +1 -1
  172. package/src/components/onboarding/account-step/signed-in-panel.tsx +1 -1
  173. package/src/components/onboarding/onboarding-frame.tsx +33 -10
  174. package/src/components/onboarding/onboarding-keyboard.ts +1 -1
  175. package/src/components/onboarding/onboarding-wizard.tsx +50 -41
  176. package/src/components/onboarding/portfolio-step/positions-panel.tsx +5 -2
  177. package/src/components/onboarding/pro-step-layout.ts +86 -0
  178. package/src/components/onboarding/use-onboarding-upgrade.ts +8 -4
  179. package/src/components/onboarding/wizard-account.ts +2 -2
  180. package/src/components/pane-template-wizard.tsx +9 -1
  181. package/src/components/price-selector-dialog.tsx +11 -2
  182. package/src/components/sign-in-gate.tsx +3 -3
  183. package/src/components/ticker/list-table-view.tsx +24 -1
  184. package/src/components/ui/action-row.tsx +2 -1
  185. package/src/components/ui/button.tsx +17 -1
  186. package/src/components/ui/choice-dialog.tsx +6 -4
  187. package/src/components/ui/confirm-dialog.tsx +28 -18
  188. package/src/components/ui/data-table/index.tsx +49 -0
  189. package/src/components/ui/data-table/opentui/index.tsx +37 -6
  190. package/src/components/ui/data-table/types.ts +20 -1
  191. package/src/components/ui/data-table/visible-range.ts +2 -0
  192. package/src/components/ui/dialog-actions.tsx +64 -0
  193. package/src/components/ui/display.tsx +17 -3
  194. package/src/components/ui/frame.tsx +35 -2
  195. package/src/components/ui/icon.tsx +13 -2
  196. package/src/components/ui/index.ts +1 -1
  197. package/src/components/ui/text-prompt-dialog.tsx +11 -9
  198. package/src/core/connection-health.ts +1 -1
  199. package/src/core/state/app/layout-reducer.ts +89 -3
  200. package/src/core/state/app/state.ts +8 -5
  201. package/src/core/state/app/types.ts +13 -2
  202. package/src/data/cached-query.ts +2 -0
  203. package/src/data/config/layout.ts +55 -21
  204. package/src/data/config/store/fold-panes.ts +149 -0
  205. package/src/data/config/store/migrations.ts +7 -0
  206. package/src/data/config/store/node.ts +27 -6
  207. package/src/data/config/store/normalize.ts +44 -5
  208. package/src/data/ticker-repository.ts +5 -0
  209. package/src/data/ticker-store.ts +15 -0
  210. package/src/docs/content.ts +215 -0
  211. package/src/docs/load.ts +139 -0
  212. package/src/docs/requests.ts +39 -0
  213. package/src/docs/snapshot.chunk.ts +8 -0
  214. package/src/docs/snapshot.json +7416 -0
  215. package/src/docs/topics.ts +216 -0
  216. package/src/i18n/es.ts +75 -5
  217. package/src/i18n/ja.ts +75 -5
  218. package/src/i18n/ko.ts +75 -5
  219. package/src/i18n/zh-cn.ts +75 -5
  220. package/src/i18n/zh-tw.ts +75 -5
  221. package/src/layout/desks.ts +2 -3
  222. package/src/layout/pane-layout-move.ts +264 -0
  223. package/src/layout/pane-manager/dock-tree.ts +18 -0
  224. package/src/layout/pane-manager/hidden-panes.ts +160 -0
  225. package/src/layout/pane-manager/index.ts +2 -0
  226. package/src/market-data/coordinator/chart.ts +10 -4
  227. package/src/market-data/coordinator/entries.ts +7 -1
  228. package/src/market-data/coordinator/index.ts +6 -3
  229. package/src/market-data/coordinator/quotes.ts +2 -2
  230. package/src/{plugins/builtin/futures/contracts.ts → market-data/futures-board.ts} +81 -28
  231. package/src/market-data/futures-contract.ts +151 -0
  232. package/src/market-data/hooks.tsx +10 -2
  233. package/src/market-data/market/format.ts +39 -21
  234. package/src/market-data/market/freshness.ts +193 -30
  235. package/src/market-data/market/status.ts +59 -23
  236. package/src/market-data/options-alternatives.ts +69 -0
  237. package/src/market-data/published-apac-sessions.ts +23 -1
  238. package/src/market-data/quotes/contributions.ts +22 -2
  239. package/src/market-data/quotes/metadata.ts +8 -9
  240. package/src/market-data/quotes/resolution.ts +2 -0
  241. package/src/market-data/quotes/screener-live-quotes.ts +61 -9
  242. package/src/market-data/result-types.ts +2 -0
  243. package/src/plugins/builtin/account-management/keyboard.ts +3 -0
  244. package/src/plugins/builtin/account-management/model.ts +2 -56
  245. package/src/plugins/builtin/account-management/navigation.ts +1 -1
  246. package/src/plugins/builtin/account-management/pane.tsx +37 -8
  247. package/src/plugins/builtin/account-management/password-dialog.tsx +1 -1
  248. package/src/plugins/builtin/alerts/cli.ts +313 -47
  249. package/src/plugins/builtin/alerts/events-pane.tsx +45 -7
  250. package/src/plugins/builtin/alerts/events.ts +23 -2
  251. package/src/plugins/builtin/alerts/history-pane.tsx +7 -2
  252. package/src/plugins/builtin/alerts/history.ts +2 -0
  253. package/src/plugins/builtin/alerts/index.tsx +41 -9
  254. package/src/plugins/builtin/alerts/pane.tsx +8 -0
  255. package/src/plugins/builtin/alerts/quotes.ts +3 -0
  256. package/src/plugins/builtin/alerts/research-builder.ts +8 -3
  257. package/src/plugins/builtin/alerts/research-rules.ts +18 -2
  258. package/src/plugins/builtin/alerts/scheduled-check.ts +122 -0
  259. package/src/plugins/builtin/alerts/scheduled-sources.ts +25 -0
  260. package/src/plugins/builtin/alerts/scheduled.ts +254 -0
  261. package/src/plugins/builtin/alerts/targets.ts +92 -0
  262. package/src/plugins/builtin/analytics/index.tsx +4 -2
  263. package/src/plugins/builtin/analytics/risk-headless.ts +33 -13
  264. package/src/plugins/builtin/analytics/risk-math.ts +91 -27
  265. package/src/plugins/builtin/analytics/risk-model.ts +71 -12
  266. package/src/plugins/builtin/analytics/risk-pane.tsx +23 -12
  267. package/src/plugins/builtin/attention/index.tsx +2 -0
  268. package/src/plugins/builtin/attention/pane.tsx +3 -1
  269. package/src/plugins/builtin/attention/series.ts +26 -0
  270. package/src/plugins/builtin/awards/index.tsx +2 -0
  271. package/src/plugins/builtin/awards/pane.tsx +3 -1
  272. package/src/plugins/builtin/awards/series.ts +29 -0
  273. package/src/plugins/builtin/backtest/pane.tsx +1 -1
  274. package/src/plugins/builtin/bond-calculator/model.ts +2 -1
  275. package/src/plugins/builtin/broker-manager/detail.tsx +4 -0
  276. package/src/plugins/builtin/broker-manager/index.tsx +7 -3
  277. package/src/plugins/builtin/broker-manager/model.ts +8 -0
  278. package/src/plugins/builtin/broker-manager/pane-actions.tsx +8 -2
  279. package/src/plugins/builtin/broker-manager/sign-in-end.ts +82 -0
  280. package/src/plugins/builtin/broker-manager/table.ts +5 -0
  281. package/src/plugins/builtin/builtin-plugin-meta.ts +121 -11
  282. package/src/plugins/builtin/catalysts/pane.tsx +3 -1
  283. package/src/plugins/builtin/cds/client.ts +70 -13
  284. package/src/plugins/builtin/cds/headless.ts +116 -19
  285. package/src/plugins/builtin/cds/index.tsx +3 -1
  286. package/src/plugins/builtin/cds/model.ts +193 -31
  287. package/src/plugins/builtin/cds/pane.tsx +56 -14
  288. package/src/plugins/builtin/cds/series.ts +19 -0
  289. package/src/plugins/builtin/central-bank-rates/index.tsx +2 -0
  290. package/src/plugins/builtin/central-bank-rates/series.ts +42 -0
  291. package/src/plugins/builtin/chart-composer/catalog-inventory.ts +192 -255
  292. package/src/plugins/builtin/chart-composer/data-catalog-pane.tsx +84 -46
  293. package/src/plugins/builtin/chart-composer/editor.tsx +5 -4
  294. package/src/plugins/builtin/chart-composer/field-series.ts +40 -0
  295. package/src/plugins/builtin/chart-composer/headless.ts +8 -3
  296. package/src/plugins/builtin/chart-composer/index.tsx +9 -2
  297. package/src/plugins/builtin/chart-composer/pane.tsx +1 -1
  298. package/src/plugins/builtin/chart-composer/series-catalog.ts +58 -50
  299. package/src/plugins/builtin/chart-composer/series-expression.ts +18 -10
  300. package/src/plugins/builtin/chart-composer/use-series-catalog.ts +59 -3
  301. package/src/plugins/builtin/chart-composer/user-series.ts +84 -0
  302. package/src/plugins/builtin/chat/channels.ts +34 -36
  303. package/src/plugins/builtin/chat/command-bar.ts +138 -0
  304. package/src/plugins/builtin/chat/composer-commands.ts +21 -1
  305. package/src/plugins/builtin/chat/content/composer-runtime.ts +11 -1
  306. package/src/plugins/builtin/chat/content/footer.tsx +5 -3
  307. package/src/plugins/builtin/chat/content/index.tsx +21 -1
  308. package/src/plugins/builtin/chat/content/mentions.ts +2 -1
  309. package/src/plugins/builtin/chat/content/new-dm-dialog.tsx +10 -2
  310. package/src/plugins/builtin/chat/content/user-map.ts +3 -1
  311. package/src/plugins/builtin/chat/controller/index.ts +50 -0
  312. package/src/plugins/builtin/chat/conversations.ts +256 -0
  313. package/src/plugins/builtin/chat/discord-command.ts +91 -0
  314. package/src/plugins/builtin/chat/edit-window.ts +12 -6
  315. package/src/plugins/builtin/chat/ghost-user.ts +14 -0
  316. package/src/plugins/builtin/chat/index.tsx +40 -2
  317. package/src/plugins/builtin/chat/layout.ts +2 -0
  318. package/src/plugins/builtin/chat/message/desktop.tsx +2 -1
  319. package/src/plugins/builtin/chat/message/header.tsx +24 -15
  320. package/src/plugins/builtin/chat/message/profile-popover.tsx +2 -1
  321. package/src/plugins/builtin/chat/message/render-state.ts +3 -0
  322. package/src/plugins/builtin/chat/pane-requests.ts +60 -0
  323. package/src/plugins/builtin/chat/pane-state.ts +32 -2
  324. package/src/plugins/builtin/chat/pane.tsx +8 -0
  325. package/src/plugins/builtin/cloud/askg/controller.ts +223 -23
  326. package/src/plugins/builtin/cloud/askg/conversation-store.ts +21 -0
  327. package/src/plugins/builtin/cloud/askg/executor.ts +57 -3
  328. package/src/plugins/builtin/cloud/askg/manifest.ts +33 -7
  329. package/src/plugins/builtin/cloud/askg/model.ts +156 -78
  330. package/src/plugins/builtin/cloud/askg/pane.tsx +772 -377
  331. package/src/plugins/builtin/cloud/askg/protocol.ts +50 -3
  332. package/src/plugins/builtin/cloud/askg/tool-display.ts +440 -0
  333. package/src/plugins/builtin/cloud/askg/tool-timeline.tsx +403 -0
  334. package/src/plugins/builtin/cloud/askg/undo.ts +2 -0
  335. package/src/plugins/builtin/cloud/auth-actions.tsx +1 -1
  336. package/src/plugins/builtin/cloud/auth-commands.ts +1 -1
  337. package/src/plugins/builtin/cloud/auth-dialog.tsx +3 -3
  338. package/src/plugins/builtin/cloud/company-picker.tsx +1 -9
  339. package/src/plugins/builtin/cloud/mcp-connect/command.ts +24 -0
  340. package/src/plugins/builtin/cloud/mcp-connect/dialog.tsx +363 -0
  341. package/src/plugins/builtin/cloud/mcp-connect/model.ts +135 -0
  342. package/src/plugins/builtin/cloud/mcp-connect/sections.ts +62 -0
  343. package/src/plugins/builtin/cloud/plugin.tsx +36 -1
  344. package/src/plugins/builtin/cloud/terminal-relay/acm-tab.tsx +89 -0
  345. package/src/plugins/builtin/cloud/terminal-relay/client.ts +97 -0
  346. package/src/plugins/builtin/cloud/terminal-relay/connect-section.tsx +57 -0
  347. package/src/plugins/builtin/cloud/terminal-relay/engine.ts +734 -0
  348. package/src/plugins/builtin/cloud/terminal-relay/grants.ts +137 -0
  349. package/src/plugins/builtin/cloud/terminal-relay/host.tsx +81 -0
  350. package/src/plugins/builtin/cloud/terminal-relay/indicator.tsx +82 -0
  351. package/src/plugins/builtin/cloud/terminal-relay/manifest.ts +239 -0
  352. package/src/plugins/builtin/cloud/terminal-relay/policy.ts +162 -0
  353. package/src/plugins/builtin/cloud/terminal-relay/prompts.tsx +192 -0
  354. package/src/plugins/builtin/cloud/terminal-relay/redact.ts +73 -0
  355. package/src/plugins/builtin/cloud/terminal-relay/summary.ts +62 -0
  356. package/src/plugins/builtin/cloud/thesis/exposure.ts +1 -1
  357. package/src/plugins/builtin/cloud/thesis/prompts.tsx +2 -1
  358. package/src/plugins/builtin/comment-letters/client.ts +1 -3
  359. package/src/plugins/builtin/company-attention/app-rank.tsx +1 -1
  360. package/src/plugins/builtin/company-attention/headless.ts +19 -5
  361. package/src/plugins/builtin/company-attention/index.tsx +2 -0
  362. package/src/plugins/builtin/company-attention/model.ts +26 -7
  363. package/src/plugins/builtin/company-attention/pane.tsx +12 -9
  364. package/src/plugins/builtin/company-attention/series.ts +52 -0
  365. package/src/plugins/builtin/company-kpis/client.ts +23 -8
  366. package/src/plugins/builtin/company-kpis/headless.ts +3 -1
  367. package/src/plugins/builtin/company-kpis/pane.tsx +19 -9
  368. package/src/plugins/builtin/company-kpis/screenshot-evidence.ts +10 -3
  369. package/src/plugins/builtin/composite-plugins.ts +116 -67
  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/credit-boards/cdx-pane.tsx +4 -4
  374. package/src/plugins/builtin/credit-boards/index.tsx +23 -21
  375. package/src/plugins/builtin/credit-boards/model.ts +0 -1
  376. package/src/plugins/builtin/credit-boards/pane.tsx +30 -0
  377. package/src/plugins/builtin/credit-boards/series.ts +66 -0
  378. package/src/plugins/builtin/credit-boards/sovr-pane.tsx +4 -4
  379. package/src/plugins/builtin/credit-conditions/index.tsx +2 -0
  380. package/src/plugins/builtin/credit-conditions/series.ts +26 -0
  381. package/src/plugins/builtin/credit-documents/headless.ts +31 -1
  382. package/src/plugins/builtin/credit-documents/pane.tsx +3 -1
  383. package/src/plugins/builtin/crypto-board/headless.ts +2 -3
  384. package/src/plugins/builtin/crypto-board/index.tsx +2 -0
  385. package/src/plugins/builtin/crypto-board/model.ts +12 -0
  386. package/src/plugins/builtin/crypto-board/pane.tsx +19 -12
  387. package/src/plugins/builtin/crypto-board/series.ts +48 -0
  388. package/src/plugins/builtin/custom-view/live-quotes.ts +2 -2
  389. package/src/plugins/builtin/debt-maturities/client.ts +37 -9
  390. package/src/plugins/builtin/debt-maturities/headless.ts +3 -1
  391. package/src/plugins/builtin/debt-maturities/index.tsx +2 -0
  392. package/src/plugins/builtin/debt-maturities/pane.tsx +5 -4
  393. package/src/plugins/builtin/debt-maturities/series.ts +45 -0
  394. package/src/plugins/builtin/dividend-yield/headless.ts +2 -2
  395. package/src/plugins/builtin/dividend-yield/index.tsx +3 -1
  396. package/src/plugins/builtin/dividend-yield/pane.tsx +1 -1
  397. package/src/plugins/builtin/dividend-yield/series.ts +20 -0
  398. package/src/plugins/builtin/docs/blocks.tsx +181 -0
  399. package/src/plugins/builtin/docs/index.tsx +68 -0
  400. package/src/plugins/builtin/docs/pane.tsx +426 -0
  401. package/src/plugins/builtin/docs/targets.ts +72 -0
  402. package/src/plugins/builtin/docs/use-docs.ts +60 -0
  403. package/src/plugins/builtin/doe/index.tsx +2 -0
  404. package/src/plugins/builtin/doe/series.ts +62 -0
  405. package/src/plugins/builtin/earnings/client.ts +3 -2
  406. package/src/plugins/builtin/earnings/format.ts +1 -5
  407. package/src/plugins/builtin/earnings/headless.ts +58 -6
  408. package/src/plugins/builtin/earnings/history-model.ts +15 -1
  409. package/src/plugins/builtin/earnings/history-table.ts +13 -2
  410. package/src/plugins/builtin/earnings/history.tsx +7 -3
  411. package/src/plugins/builtin/earnings-calls/data.ts +28 -7
  412. package/src/plugins/builtin/earnings-calls/headless.ts +3 -2
  413. package/src/plugins/builtin/earnings-calls/pane.tsx +10 -5
  414. package/src/plugins/builtin/econ/calendar-model.ts +42 -17
  415. package/src/plugins/builtin/econ/detail-view.tsx +2 -2
  416. package/src/plugins/builtin/econ/fred-catalog.ts +189 -0
  417. package/src/plugins/builtin/econ/fred-series-map.ts +0 -46
  418. package/src/plugins/builtin/econ/index.tsx +70 -22
  419. package/src/plugins/builtin/econ-statistics/defs.ts +5 -0
  420. package/src/plugins/builtin/econ-statistics/headless.ts +30 -5
  421. package/src/plugins/builtin/econ-statistics/pane.tsx +1 -1
  422. package/src/plugins/builtin/econ-statistics/stats.ts +1 -0
  423. package/src/plugins/builtin/econ-statistics/view.ts +17 -0
  424. package/src/plugins/builtin/equity-screener/pane.tsx +4 -11
  425. package/src/plugins/builtin/executives/data.ts +17 -6
  426. package/src/plugins/builtin/executives/pane.tsx +16 -7
  427. package/src/plugins/builtin/exposure/holdings.ts +1 -1
  428. package/src/plugins/builtin/exposure/pane.tsx +3 -1
  429. package/src/plugins/builtin/fear-greed/index.tsx +4 -0
  430. package/src/plugins/builtin/fear-greed/series.ts +52 -0
  431. package/src/plugins/builtin/filing-events/pane.tsx +22 -5
  432. package/src/plugins/builtin/futures/index.tsx +43 -3
  433. package/src/plugins/builtin/futures/model.ts +1 -1
  434. package/src/plugins/builtin/futures/returns.ts +1 -1
  435. package/src/plugins/builtin/futures/series.ts +13 -0
  436. package/src/plugins/builtin/futures/table.tsx +1 -1
  437. package/src/plugins/builtin/futures/use-front-returns.ts +1 -1
  438. package/src/plugins/builtin/futures-curve/client.ts +12 -3
  439. package/src/plugins/builtin/futures-curve/headless.ts +70 -9
  440. package/src/plugins/builtin/futures-curve/index.tsx +1 -1
  441. package/src/plugins/builtin/futures-curve/model.ts +66 -11
  442. package/src/plugins/builtin/futures-curve/pane.tsx +52 -18
  443. package/src/plugins/builtin/fx-matrix/index.tsx +22 -1
  444. package/src/plugins/builtin/fx-matrix/pairs.ts +1 -1
  445. package/src/plugins/builtin/fx-matrix/settings.ts +42 -2
  446. package/src/plugins/builtin/gpu/board.tsx +13 -10
  447. package/src/plugins/builtin/gpu/changes.tsx +4 -4
  448. package/src/plugins/builtin/gpu/client.ts +19 -1
  449. package/src/plugins/builtin/gpu/equities.tsx +14 -10
  450. package/src/plugins/builtin/gpu/headless.ts +64 -27
  451. package/src/plugins/builtin/gpu/history.tsx +3 -3
  452. package/src/plugins/builtin/gpu/index.tsx +2 -0
  453. package/src/plugins/builtin/gpu/model.ts +114 -20
  454. package/src/plugins/builtin/gpu/pane.tsx +28 -12
  455. package/src/plugins/builtin/gpu/series.ts +38 -0
  456. package/src/plugins/builtin/help/function-card.tsx +25 -6
  457. package/src/plugins/builtin/help/index.tsx +18 -8
  458. package/src/plugins/builtin/holders/beneficial-client.ts +29 -7
  459. package/src/plugins/builtin/holders/beneficial-model.ts +90 -3
  460. package/src/plugins/builtin/holders/beneficial-report.ts +57 -5
  461. package/src/plugins/builtin/holders/beneficial-view.tsx +62 -14
  462. package/src/plugins/builtin/holders/client.ts +22 -3
  463. package/src/plugins/builtin/holders/format.ts +18 -3
  464. package/src/plugins/builtin/holders/headless.ts +42 -134
  465. package/src/plugins/builtin/holders/pane.tsx +14 -4
  466. package/src/plugins/builtin/holders/report-header.ts +40 -5
  467. package/src/plugins/builtin/holders/report-rows.ts +240 -0
  468. package/src/plugins/builtin/insider/client.ts +35 -20
  469. package/src/plugins/builtin/insider/headless.ts +41 -11
  470. package/src/plugins/builtin/insider/index.tsx +27 -10
  471. package/src/plugins/builtin/insider/insider-data.ts +10 -0
  472. package/src/plugins/builtin/insider/issuer.ts +49 -0
  473. package/src/plugins/builtin/insider/model.ts +3 -0
  474. package/src/plugins/builtin/iv-history/charts.tsx +21 -7
  475. package/src/plugins/builtin/iv-history/client.ts +26 -6
  476. package/src/plugins/builtin/iv-history/format.ts +33 -2
  477. package/src/plugins/builtin/iv-history/headless.ts +27 -12
  478. package/src/plugins/builtin/iv-history/index.tsx +5 -3
  479. package/src/plugins/builtin/iv-history/model.ts +172 -20
  480. package/src/plugins/builtin/iv-history/pane.tsx +11 -3
  481. package/src/plugins/builtin/iv-history/screen-pane.tsx +45 -25
  482. package/src/plugins/builtin/iv-history/series.ts +29 -0
  483. package/src/plugins/builtin/jobs/headless.ts +28 -3
  484. package/src/plugins/builtin/jobs/index.tsx +3 -1
  485. package/src/plugins/builtin/jobs/pane.tsx +1 -1
  486. package/src/plugins/builtin/jobs/series.ts +19 -0
  487. package/src/plugins/builtin/kelly-sizer/headless.ts +149 -0
  488. package/src/plugins/builtin/kelly-sizer/history.ts +80 -0
  489. package/src/plugins/builtin/kelly-sizer/index.tsx +2 -0
  490. package/src/plugins/builtin/kelly-sizer/pane.tsx +111 -40
  491. package/src/plugins/builtin/kelly-sizer/portfolio.ts +0 -39
  492. package/src/plugins/builtin/kelly-sizer/sections.tsx +14 -0
  493. package/src/plugins/builtin/kelly-sizer/types.ts +9 -1
  494. package/src/plugins/builtin/layout-manager/index.tsx +9 -1
  495. package/src/plugins/builtin/macro-day/client.ts +68 -3
  496. package/src/plugins/builtin/macro-day/headless.ts +18 -12
  497. package/src/plugins/builtin/macro-day/index.tsx +3 -0
  498. package/src/plugins/builtin/macro-day/model.ts +66 -15
  499. package/src/plugins/builtin/macro-day/pane.tsx +34 -20
  500. package/src/plugins/builtin/macro-day/release-table.ts +40 -0
  501. package/src/plugins/builtin/macro-day/releases.ts +62 -44
  502. package/src/plugins/builtin/market-heatmap/data.ts +25 -5
  503. package/src/plugins/builtin/market-heatmap/evidence.ts +90 -0
  504. package/src/plugins/builtin/market-heatmap/index.tsx +144 -63
  505. package/src/plugins/builtin/market-heatmap/model.ts +102 -3
  506. package/src/plugins/builtin/market-heatmap/portfolio.ts +12 -2
  507. package/src/plugins/builtin/market-movers/client.ts +7 -5
  508. package/src/plugins/builtin/market-movers/headless.ts +31 -4
  509. package/src/plugins/builtin/market-movers/index.tsx +11 -3
  510. package/src/plugins/builtin/market-movers/model.ts +101 -17
  511. package/src/plugins/builtin/market-movers/screener.ts +31 -0
  512. package/src/plugins/builtin/market-movers/table.ts +50 -23
  513. package/src/plugins/builtin/market-valuation/chart-series.ts +29 -69
  514. package/src/plugins/builtin/market-valuation/index.tsx +3 -3
  515. package/src/plugins/builtin/market-valuation/indicators.ts +0 -5
  516. package/src/plugins/builtin/members/headless.ts +7 -2
  517. package/src/plugins/builtin/members/model.ts +31 -3
  518. package/src/plugins/builtin/members/pane.tsx +3 -6
  519. package/src/plugins/builtin/mna/headless.ts +15 -3
  520. package/src/plugins/builtin/money-markets/index.tsx +2 -0
  521. package/src/plugins/builtin/money-markets/series.ts +41 -0
  522. package/src/plugins/builtin/news/headless.ts +9 -2
  523. package/src/plugins/builtin/news/wire/news/footer.ts +10 -0
  524. package/src/plugins/builtin/notes/cli.ts +12 -7
  525. package/src/plugins/builtin/openfda/client.ts +1 -1
  526. package/src/plugins/builtin/options/carry.ts +95 -0
  527. package/src/plugins/builtin/options/index.tsx +58 -5
  528. package/src/plugins/builtin/options/strike-window.ts +183 -0
  529. package/src/plugins/builtin/options/table.ts +55 -3
  530. package/src/plugins/builtin/options/types.ts +8 -1
  531. package/src/plugins/builtin/options/view.tsx +162 -13
  532. package/src/plugins/builtin/options-calculator/inputs.ts +2 -1
  533. package/src/plugins/builtin/options-positioning/client.ts +7 -3
  534. package/src/plugins/builtin/options-positioning/headless.ts +5 -2
  535. package/src/plugins/builtin/options-positioning/pane.tsx +2 -2
  536. package/src/plugins/builtin/options-scenario/charts.tsx +2 -2
  537. package/src/plugins/builtin/options-scenario/client.ts +75 -18
  538. package/src/plugins/builtin/options-scenario/headless.ts +72 -24
  539. package/src/plugins/builtin/options-scenario/hedge.ts +285 -0
  540. package/src/plugins/builtin/options-scenario/index.tsx +9 -2
  541. package/src/plugins/builtin/options-scenario/model.ts +33 -0
  542. package/src/plugins/builtin/options-scenario/pane.tsx +40 -16
  543. package/src/plugins/builtin/pe-band/model.ts +2 -2
  544. package/src/plugins/builtin/pe-band/report-dates.ts +11 -7
  545. package/src/plugins/builtin/perps/client.ts +40 -6
  546. package/src/plugins/builtin/perps/equity-row.tsx +33 -8
  547. package/src/plugins/builtin/perps/freshness.ts +66 -0
  548. package/src/plugins/builtin/perps/headless.ts +45 -30
  549. package/src/plugins/builtin/perps/index.tsx +18 -1
  550. package/src/plugins/builtin/perps/model.ts +32 -6
  551. package/src/plugins/builtin/perps/pane.tsx +76 -20
  552. package/src/plugins/builtin/perps/series.ts +76 -0
  553. package/src/plugins/builtin/plugin-marketplace/model.ts +64 -21
  554. package/src/plugins/builtin/plugin-marketplace/packs.ts +118 -0
  555. package/src/plugins/builtin/plugin-marketplace/pane.tsx +357 -39
  556. package/src/plugins/builtin/plugin-marketplace/store.ts +7 -1
  557. package/src/plugins/builtin/plugin-module.ts +90 -4
  558. package/src/plugins/builtin/portfolio-list/account-metrics.ts +1 -1
  559. package/src/plugins/builtin/portfolio-list/cli/bulk-symbols.ts +273 -0
  560. package/src/plugins/builtin/portfolio-list/cli/import-13f.ts +109 -0
  561. package/src/plugins/builtin/portfolio-list/cli/portfolio-command.ts +400 -99
  562. package/src/plugins/builtin/portfolio-list/cli/render.ts +281 -43
  563. package/src/plugins/builtin/portfolio-list/cli/shared.ts +26 -16
  564. package/src/plugins/builtin/portfolio-list/cli/watchlist-command.ts +120 -47
  565. package/src/plugins/builtin/portfolio-list/column-values.ts +1 -1
  566. package/src/plugins/builtin/portfolio-list/grid.tsx +1 -1
  567. package/src/plugins/builtin/portfolio-list/headless.ts +70 -9
  568. package/src/plugins/builtin/portfolio-list/imported-from.ts +8 -0
  569. package/src/plugins/builtin/portfolio-list/live-valuation.ts +6 -2
  570. package/src/plugins/builtin/portfolio-list/pane/index.tsx +6 -1
  571. package/src/plugins/builtin/portfolio-list/quick-add/index.tsx +17 -1
  572. package/src/plugins/builtin/portfolio-list/summary/totals.ts +1 -1
  573. package/src/plugins/builtin/portfolio-list/table.tsx +7 -1
  574. package/src/plugins/builtin/power/client.ts +16 -0
  575. package/src/plugins/builtin/power/evidence.ts +6 -2
  576. package/src/plugins/builtin/power/headless.ts +71 -7
  577. package/src/plugins/builtin/power/index.tsx +4 -1
  578. package/src/plugins/builtin/power/model.ts +72 -1
  579. package/src/plugins/builtin/power/pane.tsx +32 -9
  580. package/src/plugins/builtin/rate-path/headless.ts +11 -3
  581. package/src/plugins/builtin/realized-vol/headless.ts +8 -0
  582. package/src/plugins/builtin/realized-vol/pane.tsx +1 -1
  583. package/src/plugins/builtin/research/corporate-actions-pane.tsx +7 -4
  584. package/src/plugins/builtin/research/equity-diagnostic-pane.tsx +1 -1
  585. package/src/plugins/builtin/research/event-model.ts +68 -24
  586. package/src/plugins/builtin/research/events-headless.ts +2 -1
  587. package/src/plugins/builtin/research/headless.ts +2 -1
  588. package/src/plugins/builtin/revenue-breakdown/client.ts +13 -6
  589. package/src/plugins/builtin/revenue-breakdown/headless.ts +4 -1
  590. package/src/plugins/builtin/revenue-breakdown/pane.tsx +7 -4
  591. package/src/plugins/builtin/reverse-dcf/headless.ts +5 -1
  592. package/src/plugins/builtin/reverse-dcf/pane.tsx +1 -1
  593. package/src/plugins/builtin/risk-factors/data.ts +23 -9
  594. package/src/plugins/builtin/risk-factors/headless.ts +5 -2
  595. package/src/plugins/builtin/risk-factors/pane.tsx +6 -5
  596. package/src/plugins/builtin/seasonality/client.ts +15 -7
  597. package/src/plugins/builtin/seasonality/headless.ts +36 -12
  598. package/src/plugins/builtin/seasonality/index.tsx +2 -2
  599. package/src/plugins/builtin/seasonality/model.ts +119 -0
  600. package/src/plugins/builtin/seasonality/pane.tsx +108 -37
  601. package/src/plugins/builtin/sec/index.tsx +5 -5
  602. package/src/plugins/builtin/sectors/client.ts +10 -2
  603. package/src/plugins/builtin/sectors/headless.ts +35 -6
  604. package/src/plugins/builtin/sectors/index.tsx +18 -1
  605. package/src/plugins/builtin/sectors/sector-model.ts +150 -41
  606. package/src/plugins/builtin/series-inventory.ts +91 -0
  607. package/src/plugins/builtin/shared/cloud-upgrade.ts +1 -1
  608. package/src/plugins/builtin/shared/command-tab.ts +69 -0
  609. package/src/plugins/builtin/shared/earnings-report.ts +55 -0
  610. package/src/plugins/builtin/shared/fred-points.ts +20 -0
  611. package/src/plugins/builtin/shared/fx-rate-freshness.ts +101 -0
  612. package/src/plugins/builtin/shared/headless-market-data.ts +33 -1
  613. package/src/plugins/builtin/shared/members-menu.tsx +4 -4
  614. package/src/plugins/builtin/shared/open-description.ts +29 -0
  615. package/src/plugins/builtin/shared/report-freshness.ts +59 -2
  616. package/src/plugins/builtin/shared/series-warning.ts +5 -0
  617. package/src/plugins/builtin/shared/ticker-request.ts +25 -1
  618. package/src/plugins/builtin/shared/use-quote-board.ts +25 -5
  619. package/src/plugins/builtin/shared/volatility/options.ts +1 -46
  620. package/src/plugins/builtin/short-interest/headless.ts +1 -0
  621. package/src/plugins/builtin/short-interest/index.tsx +21 -4
  622. package/src/plugins/builtin/short-interest/series.ts +36 -0
  623. package/src/plugins/builtin/short-interest/surface.tsx +4 -4
  624. package/src/plugins/builtin/short-interest/watch-headless.ts +1 -0
  625. package/src/plugins/builtin/short-interest/watch-model.ts +9 -5
  626. package/src/plugins/builtin/short-volume/headless.ts +1 -0
  627. package/src/plugins/builtin/short-volume/index.tsx +3 -10
  628. package/src/plugins/builtin/short-volume/series.ts +23 -0
  629. package/src/plugins/builtin/social-mentions/index.tsx +2 -0
  630. package/src/plugins/builtin/social-mentions/series.ts +23 -0
  631. package/src/plugins/builtin/supply-chain/graph-pane.tsx +3 -2
  632. package/src/plugins/builtin/supply-chain/model.ts +1 -1
  633. package/src/plugins/builtin/supply-chain/pane.tsx +3 -1
  634. package/src/plugins/builtin/thirteenf/api.ts +1 -0
  635. package/src/plugins/builtin/thirteenf/data.ts +6 -4
  636. package/src/plugins/builtin/thirteenf/headless.ts +217 -36
  637. package/src/plugins/builtin/thirteenf/model.ts +39 -1
  638. package/src/plugins/builtin/thirteenf/overlap.ts +75 -0
  639. package/src/plugins/builtin/thirteenf/pane.tsx +10 -1
  640. package/src/plugins/builtin/thirteenf/report-notes.ts +103 -1
  641. package/src/plugins/builtin/thirteenf/types.ts +2 -0
  642. package/src/plugins/builtin/ticker-detail/headless.ts +43 -21
  643. package/src/plugins/builtin/ticker-detail/index.tsx +3 -0
  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 +48 -4
  649. package/src/plugins/builtin/ticker-detail/pane.tsx +4 -5
  650. package/src/plugins/builtin/ticker-detail/quote-monitor/card.tsx +94 -6
  651. package/src/plugins/builtin/ticker-detail/quote-monitor/index.tsx +13 -3
  652. package/src/plugins/builtin/time-sales/headless.ts +1 -0
  653. package/src/plugins/builtin/treasury-auctions/cache.ts +5 -2
  654. package/src/plugins/builtin/treasury-auctions/client.ts +22 -8
  655. package/src/plugins/builtin/treasury-auctions/headless.ts +56 -6
  656. package/src/plugins/builtin/treasury-auctions/index.tsx +12 -9
  657. package/src/plugins/builtin/treasury-auctions/model.ts +205 -30
  658. package/src/plugins/builtin/treasury-auctions/pane.tsx +35 -11
  659. package/src/plugins/builtin/treasury-auctions/types.ts +11 -1
  660. package/src/plugins/builtin/vol-surface/charts.tsx +1 -3
  661. package/src/plugins/builtin/vol-surface/client.ts +6 -2
  662. package/src/plugins/builtin/vol-surface/evidence.ts +11 -6
  663. package/src/plugins/builtin/vol-surface/headless.ts +125 -20
  664. package/src/plugins/builtin/vol-surface/model.ts +23 -11
  665. package/src/plugins/builtin/vol-surface/pane.tsx +38 -27
  666. package/src/plugins/builtin/vol-surface/tables.ts +124 -0
  667. package/src/plugins/builtin/volatility/index.tsx +2 -0
  668. package/src/plugins/builtin/volatility/series.ts +84 -0
  669. package/src/plugins/builtin/world-indices/client.ts +22 -4
  670. package/src/plugins/builtin/world-indices/headless.ts +54 -27
  671. package/src/plugins/builtin/world-indices/model.ts +4 -2
  672. package/src/plugins/builtin/world-indices/table.tsx +13 -2
  673. package/src/plugins/builtin/world-venue-map/geo-series.ts +27 -2
  674. package/src/plugins/builtin/world-venue-map/headless.ts +4 -1
  675. package/src/plugins/builtin/world-venue-map/index.ts +3 -2
  676. package/src/plugins/builtin/world-venue-map/layered-pane.tsx +8 -4
  677. package/src/plugins/builtin/world-venue-map/layers.ts +29 -0
  678. package/src/plugins/builtin/yield-curve/chart.ts +2 -2
  679. package/src/plugins/builtin/yield-curve/curves.ts +21 -8
  680. package/src/plugins/builtin/yield-curve/headless.ts +71 -18
  681. package/src/plugins/builtin/yield-curve/index.tsx +4 -2
  682. package/src/plugins/builtin/yield-curve/series.ts +86 -0
  683. package/src/plugins/builtin-editorial.ts +126 -0
  684. package/src/plugins/catalog-backend.ts +16 -9
  685. package/src/plugins/catalog-browser.ts +129 -64
  686. package/src/plugins/catalog-manifest.ts +73 -40
  687. package/src/plugins/catalog-ui.ts +26 -6
  688. package/src/plugins/extracted-plugins.ts +7 -1
  689. package/src/plugins/ownership.ts +150 -7
  690. package/src/plugins/plugin-functions.ts +54 -0
  691. package/src/plugins/plugin-off.ts +36 -0
  692. package/src/plugins/registry/host-actions.ts +16 -0
  693. package/src/plugins/registry/index.ts +173 -28
  694. package/src/plugins/registry/plugin-state.ts +25 -1
  695. package/src/plugins/runtime/context.tsx +29 -0
  696. package/src/{plugins/builtin/portfolio-list → portfolio}/position-metrics.ts +6 -6
  697. package/src/portfolio/position-value.ts +40 -0
  698. package/src/public/__snapshots__/public-api.test.ts.snap +7 -0
  699. package/src/public/time-series.ts +17 -0
  700. package/src/react/auto-refresh.ts +13 -3
  701. package/src/react/input.ts +48 -1
  702. package/src/remote/app-host.tsx +25 -4
  703. package/src/remote/confirm-change.tsx +85 -0
  704. package/src/remote/controller-utils.ts +8 -1
  705. package/src/remote/controller.ts +126 -59
  706. package/src/remote/matching.ts +69 -0
  707. package/src/remote/pane-screenshot.ts +47 -0
  708. package/src/remote/schema.ts +63 -1
  709. package/src/remote/semantic-tree.tsx +14 -0
  710. package/src/remote/types.ts +32 -0
  711. package/src/remote/watchlist.ts +306 -0
  712. package/src/renderers/browser/main.tsx +3 -2
  713. package/src/renderers/cloudflare/worker.ts +1 -1
  714. package/src/renderers/dom/data-table/frozen-column.ts +3 -1
  715. package/src/renderers/dom/data-table/index.tsx +33 -6
  716. package/src/renderers/dom/data-table/row.tsx +27 -1
  717. package/src/renderers/dom/desktop/control-styles.ts +63 -1
  718. package/src/renderers/dom/desktop/controls.tsx +30 -23
  719. package/src/renderers/dom/desktop/dialog-actions.tsx +170 -0
  720. package/src/renderers/dom/desktop/icons.tsx +21 -0
  721. package/src/renderers/dom/desktop/query-bar.tsx +59 -32
  722. package/src/renderers/dom/dom-ui-host.tsx +3 -0
  723. package/src/renderers/dom/host/box.tsx +4 -1
  724. package/src/renderers/dom/host/chart-surface.tsx +6 -2
  725. package/src/renderers/dom/host/drag-shield.ts +17 -6
  726. package/src/renderers/dom/host/live-frame.ts +14 -2
  727. package/src/renderers/dom/host/overflow-fade.ts +14 -1
  728. package/src/renderers/dom/host/size-observer.ts +26 -0
  729. package/src/renderers/dom/host/surface-3d.tsx +7 -2
  730. package/src/renderers/dom/host/text.tsx +1 -1
  731. package/src/renderers/dom/input-host.tsx +6 -1
  732. package/src/renderers/dom/styles.css +74 -0
  733. package/src/renderers/electrobun/bun/desktop/backend.ts +5 -1
  734. package/src/renderers/electrobun/bun/desktop/detached-windows.ts +12 -1
  735. package/src/renderers/electrobun/bun/desktop/initialization.ts +2 -1
  736. package/src/renderers/electrobun/shared/protocol.ts +2 -0
  737. package/src/renderers/electrobun/view/cli-pane-shot-entry.tsx +18 -3
  738. package/src/renderers/electrobun/view/cli-pane-shot-frame.tsx +109 -5
  739. package/src/renderers/electrobun/view/cli-pane-shot-health.ts +10 -26
  740. package/src/renderers/electrobun/view/main.tsx +6 -1
  741. package/src/renderers/opentui/input-host.tsx +6 -1
  742. package/src/renderers/opentui/start.tsx +9 -0
  743. package/src/series/capability.ts +75 -0
  744. package/src/series/csv.ts +160 -0
  745. package/src/series/files.ts +107 -0
  746. package/src/series/registry.ts +198 -0
  747. package/src/series/resolve.ts +107 -0
  748. package/src/series/standalone.ts +48 -0
  749. package/src/series/types.ts +145 -0
  750. package/src/series/validate.ts +171 -0
  751. package/src/shares/portable-layout.ts +16 -6
  752. package/src/sources/gloomberb-cloud/index.ts +26 -17
  753. package/src/sources/gloomberb-cloud/normalizers.ts +5 -1
  754. package/src/sources/history-result.ts +1 -0
  755. package/src/sources/listing-symbols.ts +14 -5
  756. package/src/sources/provider-errors.ts +88 -3
  757. package/src/sources/provider-router/batches.ts +4 -1
  758. package/src/sources/provider-router/cache.ts +4 -2
  759. package/src/sources/provider-router/cached-routes.ts +9 -5
  760. package/src/sources/provider-router/financial-routes.ts +12 -5
  761. package/src/sources/provider-router/financials.ts +55 -15
  762. package/src/sources/provider-router/history.ts +68 -34
  763. package/src/sources/provider-router/index.ts +1 -1
  764. package/src/sources/provider-router/primary.ts +23 -5
  765. package/src/sources/provider-router/search.ts +1 -0
  766. package/src/sources/sec-edgar.ts +68 -8
  767. package/src/sync/core-contributors.ts +5 -3
  768. package/src/test-support/cli-context.ts +2 -1
  769. package/src/test-support/data-provider.ts +34 -0
  770. package/src/test-support/shell-pane-keys.tsx +1 -0
  771. package/src/theme/series-colors.ts +46 -0
  772. package/src/theme/themes.ts +149 -0
  773. package/src/tickers/company-name.ts +75 -0
  774. package/src/tickers/instrument-kind.ts +25 -0
  775. package/src/tickers/open-target.ts +3 -2
  776. package/src/tickers/search/index.ts +67 -9
  777. package/src/tickers/search/ranking.ts +78 -18
  778. package/src/tickers/search/types.ts +10 -2
  779. package/src/tickers/starter-symbols.ts +8 -0
  780. package/src/tickers/us-listing.ts +34 -0
  781. package/src/time-series/hooks.ts +9 -0
  782. package/src/time-series/resolve.ts +96 -30
  783. package/src/time-series/types.ts +4 -2
  784. package/src/time-series/use-chart-resolution.ts +32 -0
  785. package/src/types/config.ts +67 -1
  786. package/src/types/data-provider.ts +5 -0
  787. package/src/types/financials.ts +52 -1
  788. package/src/types/headless.ts +72 -0
  789. package/src/types/instrument.ts +8 -0
  790. package/src/types/plugin.ts +68 -3
  791. package/src/types/price-history.ts +7 -0
  792. package/src/types/ticker.ts +14 -0
  793. package/src/ui/host.tsx +26 -4
  794. package/src/ui/index.tsx +2 -0
  795. package/src/ui/live-resize.ts +81 -0
  796. package/src/ui/live-stretch.ts +121 -0
  797. package/src/ui/measured-cells.ts +58 -0
  798. package/src/ui/pane-fill.ts +11 -0
  799. package/src/utils/basis-points.ts +17 -0
  800. package/src/utils/cli-output.ts +21 -2
  801. package/src/utils/concurrency.ts +25 -0
  802. package/src/utils/crypto-pair.ts +20 -0
  803. package/src/utils/currency-pair.ts +19 -0
  804. package/src/utils/decimal-comma.ts +19 -0
  805. package/src/utils/dom-screenshot-css.ts +265 -0
  806. package/src/utils/dom-screenshot-rasters.ts +276 -0
  807. package/src/utils/dom-screenshot.ts +437 -52
  808. package/src/utils/exchange-rate-snapshot.ts +6 -2
  809. package/src/utils/exchanges.ts +120 -1
  810. package/src/utils/format.ts +17 -3
  811. package/src/utils/fundamentals.ts +66 -0
  812. package/src/utils/futures-generic.ts +6 -12
  813. package/src/utils/fx-market-hours.ts +44 -0
  814. package/src/utils/option-expiry.ts +126 -0
  815. package/src/utils/price-history.ts +130 -40
  816. package/src/utils/rpc-timeout-error.ts +6 -2
  817. package/src/utils/sec-eps-basis.ts +178 -36
  818. package/src/utils/sec.ts +98 -40
  819. package/src/utils/throttled-fetch.ts +51 -22
  820. package/src/utils/utc-time.ts +51 -4
@@ -11,13 +11,13 @@ import { useState } from "react";
11
11
  import { t } from "../i18n";
12
12
  import { useAppLanguage } from "../i18n/react";
13
13
  import { matchesKeyChord, parseKeyChord } from "../app/keybindings";
14
- import { AuthForm, authFormTitle } from "../plugins/builtin/cloud/auth-form";
15
- import type { AccountMode } from "../plugins/builtin/cloud/auth-model";
14
+ import { AuthForm, authFormTitle } from "../account/auth-form";
15
+ import type { AccountMode } from "../account/auth-model";
16
16
  import {
17
17
  DeviceSignInPanel,
18
18
  isDeviceSignInRetryKey,
19
19
  useDeviceSignIn,
20
- } from "../plugins/builtin/cloud/device-signin-dialog";
20
+ } from "../account/device-signin-dialog";
21
21
  import { useShortcut, useViewport } from "../react/input";
22
22
  import { useThemeColors } from "../theme/theme-context";
23
23
  import { Box, Text } from "../ui";
@@ -29,6 +29,8 @@ import type { QuoteFlashDirection } from "../quote-flash";
29
29
  import { objectVersion } from "../../utils/object-version";
30
30
  import { getCompletedRegularSessionDisplay } from "../../market-data/market/status";
31
31
  import { usePaneFooter } from "../layout/pane/footer";
32
+ import { Button } from "../ui/button";
33
+ import { PaneStatusBody } from "../ui/status";
32
34
 
33
35
  export interface TickerTableCell {
34
36
  text: string;
@@ -83,6 +85,13 @@ export interface TickerListTableViewProps {
83
85
  rowMenuAccelerators?: Readonly<Record<string, string>>;
84
86
  emptyTitle?: string;
85
87
  emptyHint?: string;
88
+ /**
89
+ * Starts the pane's add-ticker flow. Given, the empty table offers a
90
+ * "+ ticker" button for it and says so before the key.
91
+ */
92
+ onAddTicker?: () => void;
93
+ /** The pane's key for the same flow, named after the click. The command bar's key when absent. */
94
+ addTickerShortcut?: string;
86
95
  virtualize?: boolean;
87
96
  overscan?: number;
88
97
  }
@@ -214,11 +223,24 @@ export function TickerListTableView({
214
223
  rowMenuAccelerators,
215
224
  emptyTitle = t("No tickers."),
216
225
  emptyHint,
226
+ onAddTicker,
227
+ addTickerShortcut,
217
228
  virtualize = true,
218
229
  overscan = 4,
219
230
  }: TickerListTableViewProps) {
220
231
  const commandBarShortcut = useCommandBarShortcut();
221
- const resolvedEmptyHint = emptyHint ?? tf("Press {shortcut} to add one.", { shortcut: commandBarShortcut });
232
+ const addLabel = `+ ${t("ticker")}`;
233
+ const resolvedEmptyHint = emptyHint ?? (onAddTicker
234
+ ? tf("Click {button} to add one, or press {shortcut}.", { button: addLabel, shortcut: addTickerShortcut ?? commandBarShortcut })
235
+ : tf("Press {shortcut} to add one.", { shortcut: commandBarShortcut }));
236
+ const emptyContent = onAddTicker ? (
237
+ <PaneStatusBody
238
+ empty
239
+ emptyTitle={emptyTitle}
240
+ emptyMessage={resolvedEmptyHint}
241
+ actions={<Button label="Add ticker" displayLabel={addLabel} compact onPress={onAddTicker} />}
242
+ />
243
+ ) : undefined;
222
244
  const renderer = useRendererHost();
223
245
  const { showContextMenu } = useContextMenu();
224
246
  const { nativeContextMenu } = useUiCapabilities();
@@ -349,6 +371,7 @@ export function TickerListTableView({
349
371
  getRowVersion={getRowVersion}
350
372
  emptyStateTitle={emptyTitle}
351
373
  emptyStateHint={resolvedEmptyHint}
374
+ emptyContent={emptyContent}
352
375
  virtualize={virtualize}
353
376
  overscan={overscan}
354
377
  rootBefore={rootBefore}
@@ -22,7 +22,8 @@ export function ActionRow({ label, children, expanded, active, disabled, fg, ...
22
22
  const foreground = disabled ? colors.textMuted : fg ?? (active ? colors.textBright : colors.text);
23
23
  return (
24
24
  <Button {...props} label={label} active={active} disabled={disabled} expanded={expanded} variant="plain" compact flush stopPropagation>
25
- <Box flexDirection="row" width="100%" alignItems="center" gap={1}>
25
+ {/* A label of two lines reads from the left; a desktop button would centre the shorter one. */}
26
+ <Box flexDirection="row" width="100%" alignItems="center" gap={1} style={{ textAlign: "left" }}>
26
27
  {expanded !== undefined && <DisclosureMarker expanded={expanded} color={foreground} width={2} />}
27
28
  <Text fg={foreground} attributes={active ? TextAttributes.BOLD : 0}>{t(label)}</Text>
28
29
  {children}
@@ -4,6 +4,7 @@ import { type ComponentType, type ReactNode } from "react";
4
4
  import type { ThemeColors } from "../../theme/colors";
5
5
  import { useThemeColors } from "../../theme/theme-context";
6
6
  import { t } from "../../i18n";
7
+ import { displayWidth } from "../../utils/format";
7
8
  import { useRemoteUiNode, useRemoteUiScope } from "../../remote/semantic-tree";
8
9
  import { useScopedButtonAction } from "./action-scope";
9
10
 
@@ -27,6 +28,11 @@ export interface ButtonProps {
27
28
  disabled?: boolean;
28
29
  active?: boolean;
29
30
  shortcut?: string;
31
+ /**
32
+ * The key that presses it, as a keycap on the desktop and the web only: for
33
+ * a dialog button whose key the terminal names in the footer line instead.
34
+ */
35
+ desktopShortcut?: string;
30
36
  /** Tooltip, when it should say more than the label. */
31
37
  title?: string;
32
38
  width?: number;
@@ -66,6 +72,15 @@ function resolveButtonColors(variant: ButtonVariant, active: boolean, disabled:
66
72
  }
67
73
  }
68
74
 
75
+ /**
76
+ * Terminal cells a button takes: the padded label, then its key. For a row that
77
+ * has to know whether its buttons fit before it lays them out.
78
+ */
79
+ export function terminalButtonColumns({ label, displayLabel, shortcut, compact = false }: Pick<ButtonProps, "label" | "displayLabel" | "shortcut" | "compact">): number {
80
+ const text = displayLabel ?? t(label);
81
+ return displayWidth(compact ? text : ` ${text} `) + (shortcut ? 1 + displayWidth(shortcut) : 0);
82
+ }
83
+
69
84
  export function Button({
70
85
  label: rawLabel,
71
86
  displayLabel,
@@ -76,6 +91,7 @@ export function Button({
76
91
  disabled = false,
77
92
  active = false,
78
93
  shortcut,
94
+ desktopShortcut,
79
95
  width,
80
96
  height,
81
97
  compact = false,
@@ -110,7 +126,7 @@ export function Button({
110
126
  variant={variant}
111
127
  disabled={disabled}
112
128
  active={active}
113
- shortcut={shortcut}
129
+ shortcut={shortcut ?? desktopShortcut}
114
130
  title={title}
115
131
  width={width}
116
132
  height={height}
@@ -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
  );
@@ -27,6 +27,8 @@ export function DataTable<T, C extends DataTableColumn = DataTableColumn>(
27
27
  const renderer = useRendererHost();
28
28
  const propsRef = useRef(props);
29
29
  propsRef.current = props;
30
+ // The semantic snapshot can be taken every frame; the rows are rebuilt only when what they are drawn from changes.
31
+ const reportedRowsRef = useRef<{ source: readonly unknown[]; rows: ReturnType<typeof reportedRows> } | null>(null);
30
32
 
31
33
  useEffect(() => {
32
34
  if (!paneId || !renderer.saveTextFile) return;
@@ -90,6 +92,7 @@ export function DataTable<T, C extends DataTableColumn = DataTableColumn>(
90
92
  columns: props.columns.map((column) => ({ id: column.id, label: column.label })),
91
93
  rowCount: props.items.length,
92
94
  selectedId: firstSelectedId(props),
95
+ ...(props.reportEveryRow ? { rows: cachedReportedRows(props, reportedRowsRef) } : {}),
93
96
  }),
94
97
  });
95
98
  // Header labels read the same in every table whatever case a pane wrote
@@ -119,6 +122,52 @@ function resolveTableIndex<T, C extends DataTableColumn>(
119
122
  return resolveRemoteItemIndex(input, props.items, { id: key, key });
120
123
  }
121
124
 
125
+ /**
126
+ * Every row as a report reads it: the key, whether it is selected and each
127
+ * column's text, the same text the cells draw. Captured with the semantic
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.
131
+ */
132
+ function reportedRows<T, C extends DataTableColumn>(props: DataTableProps<T, C>) {
133
+ const normalize = (text: string) => text.replace(/\s+/g, " ").trim();
134
+ const first = props.columns[0];
135
+ return props.items.map((item, index) => {
136
+ const selected = props.isSelected(item, index);
137
+ const section = props.renderSectionHeader?.(item, index);
138
+ const cells = section
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
+ };
152
+ });
153
+ return { key: props.getItemKey(item, index), selected, cells: cells.filter((cell) => cell.text.length > 0) };
154
+ });
155
+ }
156
+
157
+ function cachedReportedRows<T, C extends DataTableColumn>(
158
+ props: DataTableProps<T, C>,
159
+ cache: { current: { source: readonly unknown[]; rows: ReturnType<typeof reportedRows> } | null },
160
+ ) {
161
+ const source = [props.items, props.columns, props.renderCell, props.isSelected, props.renderSectionHeader];
162
+ const cached = cache.current;
163
+ if (cached && cached.source.length === source.length && cached.source.every((value, index) => value === source[index])) {
164
+ return cached.rows;
165
+ }
166
+ const rows = reportedRows(props);
167
+ cache.current = { source, rows };
168
+ return rows;
169
+ }
170
+
122
171
  function firstSelectedId<T, C extends DataTableColumn>(props: DataTableProps<T, C>): string | null {
123
172
  const index = props.items.findIndex((item, itemIndex) => props.isSelected(item, itemIndex));
124
173
  const item = props.items[index];
@@ -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,9 +58,22 @@ 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
- export type DataTableScrollAlign = "nearest" | "center";
75
+ /** Where `scrollToIndex` puts its row: the nearest edge, the middle, or the top of the viewport. */
76
+ export type DataTableScrollAlign = "nearest" | "center" | "start";
64
77
 
65
78
  interface DataTableRowState {
66
79
  selected: boolean;
@@ -146,6 +159,12 @@ export interface DataTableProps<
146
159
  freezeFirstColumn?: boolean;
147
160
  /** Append export-only source records after the displayed table. */
148
161
  getExportMetadata?: () => readonly (readonly unknown[])[];
162
+ /**
163
+ * A rendered-view report (`gloomberb fn`) reads every row, not only those
164
+ * the viewport shows. For a bounded table a reader needs whole, such as an
165
+ * option chain's strike window; leave it off for long or paged lists.
166
+ */
167
+ reportEveryRow?: boolean;
149
168
  scrollToIndex?: number | null;
150
169
  scrollToIndexAlign?: DataTableScrollAlign;
151
170
  scrollToIndexVersion?: number;
@@ -36,6 +36,8 @@ export function resolveDataTableScrollTop(
36
36
  let nextTop = currentTop;
37
37
  if (align === "center") {
38
38
  nextTop = targetIndex - Math.floor(visibleHeight / 2);
39
+ } else if (align === "start") {
40
+ nextTop = targetIndex;
39
41
  } else if (targetIndex < currentTop) {
40
42
  nextTop = targetIndex;
41
43
  } else if (targetIndex >= currentTop + visibleHeight) {
@@ -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
  );