gloomberb 0.16.3 → 0.16.4

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 (451) hide show
  1. package/package.json +4 -1
  2. package/src/api-client/askg.ts +43 -0
  3. package/src/api-client/auth.ts +15 -0
  4. package/src/api-client/beneficial-owners.ts +4 -0
  5. package/src/api-client/chat.ts +19 -0
  6. package/src/api-client/company-kpis.ts +14 -2
  7. package/src/api-client/data.ts +34 -16
  8. package/src/api-client/index.ts +12 -0
  9. package/src/api-client/normalizers.ts +27 -0
  10. package/src/api-client/paths.ts +88 -23
  11. package/src/api-client/request.ts +2 -1
  12. package/src/api-client/research-activity.ts +31 -0
  13. package/src/api-client/socket.ts +39 -8
  14. package/src/api-client/types.ts +57 -1
  15. package/src/api-client/upgrade-experiment.ts +90 -0
  16. package/src/app/global-shortcuts.ts +11 -1
  17. package/src/app/keybindings/actions.ts +10 -0
  18. package/src/app/pane-runtime/index.tsx +8 -0
  19. package/src/app/pane-runtime/pane-template-runtime.ts +5 -0
  20. package/src/app/pane-runtime/plugin-bindings.ts +65 -25
  21. package/src/app/pane-runtime/ticker-inspector-runtime.ts +12 -0
  22. package/src/app/pane-runtime/ticker-open-runtime.ts +18 -1
  23. package/src/app/runtime/desktop-deeplink.ts +5 -0
  24. package/src/app/star-prompt/model.ts +98 -0
  25. package/src/app/star-prompt/runtime.ts +41 -0
  26. package/src/app/star-prompt/status-line.tsx +190 -0
  27. package/src/app.tsx +13 -7
  28. package/src/architecture/core-builtin-allowlist.json +70 -0
  29. package/src/brokers/signed-in/adapter.ts +33 -2
  30. package/src/brokers/signed-in/client.ts +10 -0
  31. package/src/brokers/signed-in/sign-in-dialog.tsx +23 -9
  32. package/src/brokers/signed-in/sign-in.ts +62 -5
  33. package/src/capabilities/registry.ts +8 -1
  34. package/src/capabilities/types.ts +2 -0
  35. package/src/cli/commands/crypto-hints.ts +12 -4
  36. package/src/cli/commands/market.ts +359 -99
  37. package/src/cli/commands/options-chain.ts +172 -0
  38. package/src/cli/commands/options-leaps.ts +422 -0
  39. package/src/cli/commands/overview.ts +164 -26
  40. package/src/cli/commands/search.ts +29 -8
  41. package/src/cli/commands/system.ts +99 -19
  42. package/src/cli/commands/themes.ts +64 -0
  43. package/src/cli/commands/ticker.ts +62 -30
  44. package/src/cli/desktop-pane-shot.ts +97 -16
  45. package/src/cli/errors.ts +25 -2
  46. package/src/cli/freshness.ts +7 -4
  47. package/src/cli/fx-pair.ts +57 -0
  48. package/src/cli/help.ts +14 -1
  49. package/src/cli/index-roots.ts +51 -0
  50. package/src/cli/index.ts +9 -6
  51. package/src/cli/listing-arg.ts +211 -3
  52. package/src/cli/not-a-ticker.ts +37 -0
  53. package/src/cli/options.ts +50 -6
  54. package/src/cli/pane-functions/capabilities.ts +8 -2
  55. package/src/cli/pane-functions/catalog.ts +13 -2
  56. package/src/cli/pane-functions/data.ts +36 -5
  57. package/src/cli/pane-functions/dom.ts +21 -13
  58. package/src/cli/pane-functions/freshness.ts +205 -26
  59. package/src/cli/pane-functions/function-help.ts +67 -22
  60. package/src/cli/pane-functions/headless.ts +5 -4
  61. package/src/cli/pane-functions/index.ts +3 -0
  62. package/src/cli/pane-functions/market-session.ts +133 -0
  63. package/src/cli/pane-functions/options.ts +15 -4
  64. package/src/cli/pane-functions/report-notices.ts +63 -0
  65. package/src/cli/pane-functions/report.ts +4 -0
  66. package/src/cli/pane-functions/resolver.ts +4 -6
  67. package/src/cli/pane-functions/screenshot-evidence.ts +2 -0
  68. package/src/cli/pane-functions/screenshot.ts +105 -23
  69. package/src/cli/registry.ts +2 -1
  70. package/src/cli/result.ts +50 -13
  71. package/src/cli/row-window.ts +76 -0
  72. package/src/cli/scroll-truncation.ts +34 -0
  73. package/src/components/chart/composite/composite-chart.tsx +43 -4
  74. package/src/components/chart/composite/legend.tsx +39 -6
  75. package/src/components/chart/composite/rasterizer.ts +64 -4
  76. package/src/components/chart/composite/series-cues.ts +71 -0
  77. package/src/components/chart/composite/text-renderer.ts +16 -8
  78. package/src/components/chart/composite/types.ts +3 -0
  79. package/src/components/command-bar/commands/direct/index.ts +9 -1
  80. package/src/components/command-bar/commands/plugin/items.ts +3 -1
  81. package/src/components/command-bar/commands/registry.ts +7 -0
  82. package/src/components/command-bar/layout-items/focused-pane.ts +38 -0
  83. package/src/components/command-bar/pane-templates/workflow.ts +5 -0
  84. package/src/components/command-bar/routes/root/command-items.ts +2 -0
  85. package/src/components/command-bar/routes/root/plugin-turn-on.ts +92 -0
  86. package/src/components/command-bar/routes/root/results.ts +40 -10
  87. package/src/components/command-bar/routes/root/runtime.ts +8 -0
  88. package/src/components/command-bar/routes/root/search-providers.ts +97 -14
  89. package/src/components/command-bar/surface/index.tsx +18 -4
  90. package/src/components/command-bar/theme-picker.tsx +48 -13
  91. package/src/components/command-bar/workflow/ops.ts +5 -3
  92. package/src/components/data-table/view.tsx +28 -9
  93. package/src/components/layout/floating-pane.tsx +6 -2
  94. package/src/components/layout/market-summary.ts +23 -9
  95. package/src/components/layout/pane/content.tsx +46 -29
  96. package/src/components/layout/pane/cycle-order.ts +2 -11
  97. package/src/components/layout/pane/header.tsx +2 -1
  98. package/src/components/layout/pane/title.ts +1 -1
  99. package/src/components/layout/presentation.ts +22 -0
  100. package/src/components/layout/shell/active-drag.ts +1 -1
  101. package/src/components/layout/shell/drag/index.ts +4 -0
  102. package/src/components/layout/shell/drag/live.ts +76 -5
  103. package/src/components/layout/shell/drag/runtime.ts +8 -8
  104. package/src/components/layout/shell/index.tsx +47 -6
  105. package/src/components/layout/shell/layout-state.ts +5 -11
  106. package/src/components/layout/shell/menu.ts +28 -1
  107. package/src/components/layout/shell/pane/actions.ts +2 -1
  108. package/src/components/layout/shell/pane/layers.tsx +51 -10
  109. package/src/components/layout/shell/pane/management-shortcuts.ts +5 -0
  110. package/src/components/layout/shell/pane/new-layout.ts +116 -0
  111. package/src/components/layout/shell/shortcuts.ts +5 -2
  112. package/src/components/layout/shell/visible-layout.ts +44 -1
  113. package/src/components/layout/status-bar.tsx +4 -1
  114. package/src/components/markdown-text.tsx +9 -5
  115. package/src/components/metric-treemap/heat-surface.tsx +27 -8
  116. package/src/components/metric-treemap/heat-tiles.ts +48 -17
  117. package/src/components/onboarding/onboarding-frame.tsx +33 -10
  118. package/src/components/onboarding/onboarding-wizard.tsx +49 -40
  119. package/src/components/onboarding/portfolio-step/positions-panel.tsx +5 -2
  120. package/src/components/onboarding/pro-step-layout.ts +86 -0
  121. package/src/components/onboarding/use-onboarding-upgrade.ts +6 -2
  122. package/src/components/ui/button.tsx +10 -0
  123. package/src/components/ui/data-table/index.tsx +38 -0
  124. package/src/components/ui/data-table/types.ts +8 -1
  125. package/src/components/ui/data-table/visible-range.ts +2 -0
  126. package/src/components/ui/icon.tsx +11 -2
  127. package/src/components/ui/index.ts +1 -1
  128. package/src/core/connection-health.ts +1 -1
  129. package/src/core/state/app/layout-reducer.ts +89 -3
  130. package/src/core/state/app/state.ts +8 -5
  131. package/src/core/state/app/types.ts +13 -2
  132. package/src/data/config/layout.ts +55 -21
  133. package/src/data/config/store/fold-panes.ts +149 -0
  134. package/src/data/config/store/migrations.ts +7 -0
  135. package/src/data/config/store/node.ts +27 -6
  136. package/src/data/config/store/normalize.ts +37 -3
  137. package/src/i18n/es.ts +14 -1
  138. package/src/i18n/ja.ts +14 -1
  139. package/src/i18n/ko.ts +14 -1
  140. package/src/i18n/zh-cn.ts +14 -1
  141. package/src/i18n/zh-tw.ts +14 -1
  142. package/src/layout/desks.ts +1 -2
  143. package/src/layout/pane-layout-move.ts +264 -0
  144. package/src/layout/pane-manager/hidden-panes.ts +160 -0
  145. package/src/layout/pane-manager/index.ts +1 -0
  146. package/src/market-data/coordinator/entries.ts +7 -1
  147. package/src/market-data/coordinator/quotes.ts +2 -2
  148. package/src/market-data/market/freshness.ts +118 -18
  149. package/src/market-data/market/status.ts +40 -0
  150. package/src/market-data/options-alternatives.ts +69 -0
  151. package/src/market-data/quotes/contributions.ts +19 -2
  152. package/src/market-data/quotes/metadata.ts +16 -0
  153. package/src/market-data/quotes/screener-live-quotes.ts +56 -5
  154. package/src/plugins/builtin/account-management/keyboard.ts +3 -0
  155. package/src/plugins/builtin/account-management/model.ts +1 -0
  156. package/src/plugins/builtin/account-management/navigation.ts +1 -1
  157. package/src/plugins/builtin/account-management/pane.tsx +31 -4
  158. package/src/plugins/builtin/alerts/quotes.ts +3 -0
  159. package/src/plugins/builtin/analytics/risk-headless.ts +3 -1
  160. package/src/plugins/builtin/analytics/risk-model.ts +37 -8
  161. package/src/plugins/builtin/analytics/risk-pane.tsx +8 -4
  162. package/src/plugins/builtin/backtest/pane.tsx +1 -1
  163. package/src/plugins/builtin/broker-manager/detail.tsx +4 -0
  164. package/src/plugins/builtin/broker-manager/index.tsx +7 -3
  165. package/src/plugins/builtin/broker-manager/model.ts +8 -0
  166. package/src/plugins/builtin/broker-manager/pane-actions.tsx +8 -2
  167. package/src/plugins/builtin/broker-manager/sign-in-end.ts +82 -0
  168. package/src/plugins/builtin/broker-manager/table.ts +5 -0
  169. package/src/plugins/builtin/builtin-plugin-meta.ts +121 -11
  170. package/src/plugins/builtin/chart-composer/pane.tsx +1 -1
  171. package/src/plugins/builtin/chat/channels.ts +34 -36
  172. package/src/plugins/builtin/chat/command-bar.ts +138 -0
  173. package/src/plugins/builtin/chat/composer-commands.ts +21 -1
  174. package/src/plugins/builtin/chat/content/composer-runtime.ts +11 -1
  175. package/src/plugins/builtin/chat/content/footer.tsx +5 -3
  176. package/src/plugins/builtin/chat/content/index.tsx +21 -1
  177. package/src/plugins/builtin/chat/content/mentions.ts +2 -1
  178. package/src/plugins/builtin/chat/content/user-map.ts +3 -1
  179. package/src/plugins/builtin/chat/controller/index.ts +48 -0
  180. package/src/plugins/builtin/chat/conversations.ts +256 -0
  181. package/src/plugins/builtin/chat/discord-command.ts +91 -0
  182. package/src/plugins/builtin/chat/edit-window.ts +12 -6
  183. package/src/plugins/builtin/chat/ghost-user.ts +14 -0
  184. package/src/plugins/builtin/chat/index.tsx +40 -2
  185. package/src/plugins/builtin/chat/layout.ts +2 -0
  186. package/src/plugins/builtin/chat/message/desktop.tsx +2 -1
  187. package/src/plugins/builtin/chat/message/header.tsx +24 -15
  188. package/src/plugins/builtin/chat/message/profile-popover.tsx +2 -1
  189. package/src/plugins/builtin/chat/message/render-state.ts +3 -0
  190. package/src/plugins/builtin/chat/pane-requests.ts +60 -0
  191. package/src/plugins/builtin/chat/pane-state.ts +32 -2
  192. package/src/plugins/builtin/chat/pane.tsx +8 -0
  193. package/src/plugins/builtin/cloud/askg/controller.ts +112 -4
  194. package/src/plugins/builtin/cloud/askg/conversation-store.ts +21 -0
  195. package/src/plugins/builtin/cloud/askg/manifest.ts +1 -0
  196. package/src/plugins/builtin/cloud/askg/model.ts +129 -70
  197. package/src/plugins/builtin/cloud/askg/pane.tsx +772 -377
  198. package/src/plugins/builtin/cloud/askg/protocol.ts +40 -2
  199. package/src/plugins/builtin/cloud/askg/tool-display.ts +437 -0
  200. package/src/plugins/builtin/cloud/askg/tool-timeline.tsx +403 -0
  201. package/src/plugins/builtin/cloud/company-picker.tsx +1 -9
  202. package/src/plugins/builtin/cloud/mcp-connect/command.ts +24 -0
  203. package/src/plugins/builtin/cloud/mcp-connect/dialog.tsx +360 -0
  204. package/src/plugins/builtin/cloud/mcp-connect/model.ts +135 -0
  205. package/src/plugins/builtin/cloud/mcp-connect/sections.ts +62 -0
  206. package/src/plugins/builtin/cloud/plugin.tsx +36 -1
  207. package/src/plugins/builtin/cloud/starter-symbols.ts +8 -0
  208. package/src/plugins/builtin/cloud/terminal-relay/acm-tab.tsx +89 -0
  209. package/src/plugins/builtin/cloud/terminal-relay/client.ts +97 -0
  210. package/src/plugins/builtin/cloud/terminal-relay/connect-section.tsx +57 -0
  211. package/src/plugins/builtin/cloud/terminal-relay/engine.ts +666 -0
  212. package/src/plugins/builtin/cloud/terminal-relay/grants.ts +137 -0
  213. package/src/plugins/builtin/cloud/terminal-relay/host.tsx +81 -0
  214. package/src/plugins/builtin/cloud/terminal-relay/indicator.tsx +82 -0
  215. package/src/plugins/builtin/cloud/terminal-relay/manifest.ts +234 -0
  216. package/src/plugins/builtin/cloud/terminal-relay/policy.ts +153 -0
  217. package/src/plugins/builtin/cloud/terminal-relay/prompts.tsx +168 -0
  218. package/src/plugins/builtin/cloud/terminal-relay/redact.ts +73 -0
  219. package/src/plugins/builtin/cloud/terminal-relay/summary.ts +62 -0
  220. package/src/plugins/builtin/cloud/upgrade-dialog.tsx +26 -2
  221. package/src/plugins/builtin/cloud/upgrade-personalization.ts +57 -0
  222. package/src/plugins/builtin/cloud/upgrade-tickers.ts +124 -0
  223. package/src/plugins/builtin/comment-letters/client.ts +1 -3
  224. package/src/plugins/builtin/company-kpis/client.ts +23 -8
  225. package/src/plugins/builtin/company-kpis/headless.ts +3 -1
  226. package/src/plugins/builtin/company-kpis/pane.tsx +15 -7
  227. package/src/plugins/builtin/company-kpis/screenshot-evidence.ts +10 -3
  228. package/src/plugins/builtin/composite-plugins.ts +107 -64
  229. package/src/plugins/builtin/credit-boards/cdx-pane.tsx +4 -4
  230. package/src/plugins/builtin/credit-boards/index.tsx +21 -21
  231. package/src/plugins/builtin/credit-boards/model.ts +0 -1
  232. package/src/plugins/builtin/credit-boards/pane.tsx +30 -0
  233. package/src/plugins/builtin/credit-boards/sovr-pane.tsx +4 -4
  234. package/src/plugins/builtin/debt-maturities/client.ts +37 -9
  235. package/src/plugins/builtin/debt-maturities/headless.ts +3 -1
  236. package/src/plugins/builtin/debt-maturities/pane.tsx +5 -4
  237. package/src/plugins/builtin/dividend-yield/index.tsx +1 -1
  238. package/src/plugins/builtin/dividend-yield/pane.tsx +1 -1
  239. package/src/plugins/builtin/earnings-calls/data.ts +28 -7
  240. package/src/plugins/builtin/earnings-calls/headless.ts +3 -2
  241. package/src/plugins/builtin/earnings-calls/pane.tsx +10 -5
  242. package/src/plugins/builtin/econ/calendar-model.ts +42 -17
  243. package/src/plugins/builtin/econ/detail-view.tsx +2 -2
  244. package/src/plugins/builtin/econ/index.tsx +68 -22
  245. package/src/plugins/builtin/econ-statistics/headless.ts +12 -2
  246. package/src/plugins/builtin/econ-statistics/pane.tsx +1 -1
  247. package/src/plugins/builtin/econ-statistics/view.ts +17 -0
  248. package/src/plugins/builtin/executives/data.ts +17 -6
  249. package/src/plugins/builtin/executives/pane.tsx +16 -7
  250. package/src/plugins/builtin/filing-events/pane.tsx +22 -5
  251. package/src/plugins/builtin/fx-matrix/freshness.ts +65 -0
  252. package/src/plugins/builtin/fx-matrix/index.tsx +22 -1
  253. package/src/plugins/builtin/fx-matrix/pairs.ts +1 -1
  254. package/src/plugins/builtin/fx-matrix/settings.ts +42 -2
  255. package/src/plugins/builtin/gpu/headless.ts +9 -3
  256. package/src/plugins/builtin/gpu/model.ts +14 -5
  257. package/src/plugins/builtin/help/index.tsx +1 -0
  258. package/src/plugins/builtin/holders/beneficial-client.ts +29 -7
  259. package/src/plugins/builtin/holders/beneficial-view.tsx +7 -3
  260. package/src/plugins/builtin/holders/headless.ts +6 -1
  261. package/src/plugins/builtin/holders/pane.tsx +3 -0
  262. package/src/plugins/builtin/insider/index.tsx +4 -4
  263. package/src/plugins/builtin/iv-history/charts.tsx +21 -7
  264. package/src/plugins/builtin/iv-history/client.ts +12 -2
  265. package/src/plugins/builtin/iv-history/format.ts +33 -2
  266. package/src/plugins/builtin/iv-history/headless.ts +22 -10
  267. package/src/plugins/builtin/iv-history/index.tsx +3 -3
  268. package/src/plugins/builtin/iv-history/model.ts +61 -13
  269. package/src/plugins/builtin/iv-history/pane.tsx +11 -3
  270. package/src/plugins/builtin/iv-history/screen-pane.tsx +42 -18
  271. package/src/plugins/builtin/jobs/pane.tsx +1 -1
  272. package/src/plugins/builtin/kelly-sizer/headless.ts +149 -0
  273. package/src/plugins/builtin/kelly-sizer/history.ts +80 -0
  274. package/src/plugins/builtin/kelly-sizer/index.tsx +2 -0
  275. package/src/plugins/builtin/kelly-sizer/pane.tsx +109 -39
  276. package/src/plugins/builtin/kelly-sizer/sections.tsx +14 -0
  277. package/src/plugins/builtin/kelly-sizer/types.ts +9 -1
  278. package/src/plugins/builtin/layout-manager/index.tsx +9 -1
  279. package/src/plugins/builtin/macro-day/client.ts +24 -0
  280. package/src/plugins/builtin/macro-day/headless.ts +11 -8
  281. package/src/plugins/builtin/macro-day/index.tsx +3 -0
  282. package/src/plugins/builtin/macro-day/model.ts +11 -6
  283. package/src/plugins/builtin/macro-day/pane.tsx +12 -8
  284. package/src/plugins/builtin/macro-day/release-table.ts +40 -0
  285. package/src/plugins/builtin/macro-day/releases.ts +62 -44
  286. package/src/plugins/builtin/market-heatmap/data.ts +25 -5
  287. package/src/plugins/builtin/market-heatmap/evidence.ts +90 -0
  288. package/src/plugins/builtin/market-heatmap/index.tsx +144 -63
  289. package/src/plugins/builtin/market-heatmap/model.ts +94 -3
  290. package/src/plugins/builtin/market-heatmap/portfolio.ts +12 -2
  291. package/src/plugins/builtin/market-movers/headless.ts +31 -4
  292. package/src/plugins/builtin/market-movers/index.tsx +8 -1
  293. package/src/plugins/builtin/market-movers/model.ts +71 -17
  294. package/src/plugins/builtin/market-movers/table.ts +50 -23
  295. package/src/plugins/builtin/news/headless.ts +9 -2
  296. package/src/plugins/builtin/news/wire/news/footer.ts +10 -0
  297. package/src/plugins/builtin/openfda/client.ts +1 -1
  298. package/src/plugins/builtin/options/carry.ts +95 -0
  299. package/src/plugins/builtin/options/index.tsx +58 -5
  300. package/src/plugins/builtin/options/strike-window.ts +183 -0
  301. package/src/plugins/builtin/options/table.ts +55 -3
  302. package/src/plugins/builtin/options/types.ts +8 -1
  303. package/src/plugins/builtin/options/view.tsx +161 -12
  304. package/src/plugins/builtin/options-positioning/headless.ts +4 -2
  305. package/src/plugins/builtin/options-scenario/charts.tsx +2 -2
  306. package/src/plugins/builtin/options-scenario/client.ts +73 -17
  307. package/src/plugins/builtin/options-scenario/headless.ts +71 -24
  308. package/src/plugins/builtin/options-scenario/hedge.ts +284 -0
  309. package/src/plugins/builtin/options-scenario/index.tsx +9 -2
  310. package/src/plugins/builtin/options-scenario/model.ts +33 -0
  311. package/src/plugins/builtin/options-scenario/pane.tsx +40 -16
  312. package/src/plugins/builtin/pe-band/model.ts +2 -2
  313. package/src/plugins/builtin/pe-band/report-dates.ts +11 -7
  314. package/src/plugins/builtin/perps/equity-row.tsx +8 -5
  315. package/src/plugins/builtin/perps/model.ts +16 -5
  316. package/src/plugins/builtin/plugin-marketplace/model.ts +64 -21
  317. package/src/plugins/builtin/plugin-marketplace/packs.ts +118 -0
  318. package/src/plugins/builtin/plugin-marketplace/pane.tsx +344 -32
  319. package/src/plugins/builtin/plugin-marketplace/store.ts +7 -1
  320. package/src/plugins/builtin/plugin-module.ts +87 -4
  321. package/src/plugins/builtin/portfolio-list/cli/portfolio-command.ts +71 -36
  322. package/src/plugins/builtin/portfolio-list/cli/render.ts +87 -18
  323. package/src/plugins/builtin/portfolio-list/cli/shared.ts +2 -16
  324. package/src/plugins/builtin/portfolio-list/headless.ts +38 -7
  325. package/src/plugins/builtin/realized-vol/headless.ts +3 -0
  326. package/src/plugins/builtin/realized-vol/pane.tsx +1 -1
  327. package/src/plugins/builtin/research/corporate-actions-pane.tsx +2 -2
  328. package/src/plugins/builtin/research/equity-diagnostic-pane.tsx +1 -1
  329. package/src/plugins/builtin/revenue-breakdown/client.ts +13 -6
  330. package/src/plugins/builtin/revenue-breakdown/headless.ts +4 -1
  331. package/src/plugins/builtin/revenue-breakdown/pane.tsx +7 -4
  332. package/src/plugins/builtin/reverse-dcf/headless.ts +5 -1
  333. package/src/plugins/builtin/reverse-dcf/pane.tsx +1 -1
  334. package/src/plugins/builtin/risk-factors/data.ts +23 -9
  335. package/src/plugins/builtin/risk-factors/headless.ts +5 -2
  336. package/src/plugins/builtin/risk-factors/pane.tsx +6 -5
  337. package/src/plugins/builtin/seasonality/pane.tsx +1 -1
  338. package/src/plugins/builtin/sec/index.tsx +5 -5
  339. package/src/plugins/builtin/sectors/client.ts +10 -2
  340. package/src/plugins/builtin/sectors/headless.ts +35 -6
  341. package/src/plugins/builtin/sectors/index.tsx +18 -1
  342. package/src/plugins/builtin/sectors/sector-model.ts +150 -41
  343. package/src/plugins/builtin/shared/command-tab.ts +51 -0
  344. package/src/plugins/builtin/shared/headless-market-data.ts +33 -1
  345. package/src/plugins/builtin/shared/members-menu.tsx +4 -4
  346. package/src/plugins/builtin/shared/report-freshness.ts +50 -2
  347. package/src/plugins/builtin/shared/ticker-request.ts +25 -1
  348. package/src/plugins/builtin/shared/use-quote-board.ts +25 -5
  349. package/src/plugins/builtin/shared/volatility/options.ts +1 -46
  350. package/src/plugins/builtin/short-interest/index.tsx +19 -4
  351. package/src/plugins/builtin/short-interest/surface.tsx +4 -4
  352. package/src/plugins/builtin/short-volume/index.tsx +1 -10
  353. package/src/plugins/builtin/supply-chain/model.ts +1 -1
  354. package/src/plugins/builtin/ticker-detail/headless.ts +43 -21
  355. package/src/plugins/builtin/ticker-detail/pane.tsx +4 -5
  356. package/src/plugins/builtin/ticker-detail/quote-monitor/card.tsx +94 -6
  357. package/src/plugins/builtin/treasury-auctions/cache.ts +5 -2
  358. package/src/plugins/builtin/treasury-auctions/client.ts +22 -8
  359. package/src/plugins/builtin/treasury-auctions/headless.ts +40 -4
  360. package/src/plugins/builtin/treasury-auctions/index.tsx +11 -9
  361. package/src/plugins/builtin/treasury-auctions/model.ts +197 -30
  362. package/src/plugins/builtin/treasury-auctions/pane.tsx +35 -11
  363. package/src/plugins/builtin/treasury-auctions/types.ts +11 -1
  364. package/src/plugins/builtin/vol-surface/charts.tsx +1 -3
  365. package/src/plugins/builtin/vol-surface/client.ts +6 -2
  366. package/src/plugins/builtin/vol-surface/evidence.ts +11 -6
  367. package/src/plugins/builtin/vol-surface/headless.ts +124 -20
  368. package/src/plugins/builtin/vol-surface/model.ts +23 -11
  369. package/src/plugins/builtin/vol-surface/pane.tsx +38 -27
  370. package/src/plugins/builtin/vol-surface/tables.ts +124 -0
  371. package/src/plugins/builtin/world-indices/client.ts +22 -4
  372. package/src/plugins/builtin/world-indices/headless.ts +54 -27
  373. package/src/plugins/builtin/world-indices/model.ts +4 -2
  374. package/src/plugins/builtin/world-indices/table.tsx +13 -2
  375. package/src/plugins/builtin/world-venue-map/geo-series.ts +1 -1
  376. package/src/plugins/builtin/world-venue-map/index.ts +1 -1
  377. package/src/plugins/builtin/yield-curve/index.tsx +1 -1
  378. package/src/plugins/builtin-editorial.ts +126 -0
  379. package/src/plugins/catalog-backend.ts +16 -9
  380. package/src/plugins/catalog-browser.ts +127 -63
  381. package/src/plugins/catalog-manifest.ts +73 -40
  382. package/src/plugins/catalog-ui.ts +26 -6
  383. package/src/plugins/extracted-plugins.ts +7 -1
  384. package/src/plugins/ownership.ts +150 -7
  385. package/src/plugins/plugin-functions.ts +54 -0
  386. package/src/plugins/plugin-off.ts +36 -0
  387. package/src/plugins/registry/host-actions.ts +16 -0
  388. package/src/plugins/registry/index.ts +84 -24
  389. package/src/plugins/registry/plugin-state.ts +25 -1
  390. package/src/plugins/runtime/context.tsx +29 -0
  391. package/src/react/input.ts +48 -1
  392. package/src/remote/app-host.tsx +5 -0
  393. package/src/remote/controller.ts +3 -53
  394. package/src/remote/matching.ts +69 -0
  395. package/src/remote/schema.ts +1 -1
  396. package/src/remote/semantic-tree.tsx +14 -0
  397. package/src/remote/types.ts +2 -0
  398. package/src/renderers/dom/desktop/icons.tsx +14 -0
  399. package/src/renderers/dom/desktop/query-bar.tsx +59 -32
  400. package/src/renderers/dom/host/box.tsx +1 -1
  401. package/src/renderers/dom/host/drag-shield.ts +17 -6
  402. package/src/renderers/dom/host/live-frame.ts +10 -2
  403. package/src/renderers/dom/input-host.tsx +6 -1
  404. package/src/renderers/dom/styles.css +13 -0
  405. package/src/renderers/electrobun/bun/desktop/backend.ts +5 -1
  406. package/src/renderers/electrobun/bun/desktop/detached-windows.ts +12 -1
  407. package/src/renderers/electrobun/bun/desktop/initialization.ts +2 -1
  408. package/src/renderers/electrobun/shared/protocol.ts +2 -0
  409. package/src/renderers/electrobun/view/cli-pane-shot-entry.tsx +1 -1
  410. package/src/renderers/electrobun/view/cli-pane-shot-frame.tsx +101 -5
  411. package/src/renderers/electrobun/view/main.tsx +4 -1
  412. package/src/renderers/opentui/input-host.tsx +6 -1
  413. package/src/renderers/opentui/start.tsx +9 -0
  414. package/src/shares/portable-layout.ts +16 -6
  415. package/src/sources/gloomberb-cloud/index.ts +19 -10
  416. package/src/sources/gloomberb-cloud/normalizers.ts +4 -1
  417. package/src/sources/listing-symbols.ts +11 -5
  418. package/src/sources/provider-errors.ts +88 -3
  419. package/src/sources/provider-router/cached-routes.ts +8 -4
  420. package/src/sources/provider-router/financial-routes.ts +11 -5
  421. package/src/sources/provider-router/financials.ts +42 -15
  422. package/src/sources/provider-router/history.ts +27 -11
  423. package/src/sources/provider-router/index.ts +1 -1
  424. package/src/sources/provider-router/primary.ts +23 -5
  425. package/src/sources/sec-edgar.ts +68 -8
  426. package/src/sync/core-contributors.ts +4 -3
  427. package/src/test-support/cli-context.ts +2 -1
  428. package/src/test-support/data-provider.ts +34 -0
  429. package/src/test-support/shell-pane-keys.tsx +1 -0
  430. package/src/theme/series-colors.ts +46 -0
  431. package/src/theme/themes.ts +149 -0
  432. package/src/tickers/search/index.ts +22 -2
  433. package/src/tickers/search/ranking.ts +45 -1
  434. package/src/tickers/search/types.ts +3 -1
  435. package/src/time-series/resolve.ts +1 -14
  436. package/src/types/config.ts +61 -1
  437. package/src/types/headless.ts +11 -0
  438. package/src/types/instrument.ts +8 -0
  439. package/src/types/plugin.ts +49 -3
  440. package/src/ui/host.tsx +8 -4
  441. package/src/ui/index.tsx +2 -0
  442. package/src/utils/cli-output.ts +14 -1
  443. package/src/utils/exchanges.ts +13 -0
  444. package/src/utils/format.ts +2 -1
  445. package/src/utils/fx-market-hours.ts +34 -0
  446. package/src/utils/option-expiry.ts +126 -0
  447. package/src/utils/price-history.ts +39 -6
  448. package/src/utils/rpc-timeout-error.ts +6 -2
  449. package/src/utils/sec-eps-basis.ts +159 -30
  450. package/src/utils/sec.ts +38 -34
  451. package/src/utils/throttled-fetch.ts +51 -22
@@ -21,6 +21,9 @@ export interface FunctionHelpKey {
21
21
  label: string;
22
22
  }
23
23
 
24
+ /** A function Free cannot fully open: Pro only, or a limited preview on Free. */
25
+ export type FunctionAccess = "pro" | "preview";
26
+
24
27
  /** How fresh the function's data is on each plan, in the words a pane footer uses. */
25
28
  export interface FunctionFreshness {
26
29
  free: string;
@@ -36,14 +39,21 @@ export interface FunctionHelp {
36
39
  keys: readonly FunctionHelpKey[];
37
40
  /** Null when the function shows no market data (settings, your own notes). */
38
41
  data: FunctionFreshness | null;
42
+ /**
43
+ * What Free gets: `pro` when only Pro opens it, `preview` when Free sees a
44
+ * limited preview of the same data. Absent when Free gets the whole
45
+ * function, even where Pro makes it fresher.
46
+ */
47
+ access?: FunctionAccess;
39
48
  /** The Bloomberg mnemonics it stands in for; empty when Bloomberg has none. */
40
49
  bloomberg: readonly string[];
41
- /** The docs entry when it is filed under another mnemonic (BTST under BT). */
50
+ /** The docs entry when it is filed under another mnemonic (BTST under BT), or the full URL of a page of its own. */
42
51
  docs?: string;
43
52
  }
44
53
 
45
- /** The docs page's anchor for a mnemonic, as the page builds heading ids. */
54
+ /** The docs page's anchor for a mnemonic, as the page builds heading ids, or a full docs URL as is. */
46
55
  export function functionDocsUrl(code: string): string {
56
+ if (code.startsWith("https://")) return code;
47
57
  const anchor = code.toLowerCase().replace(/[^a-z0-9]+/g, "-").replace(/^-+|-+$/g, "");
48
58
  return anchor ? `${FUNCTION_DOCS_URL}#${anchor}` : FUNCTION_DOCS_URL;
49
59
  }
@@ -222,8 +232,9 @@ export const FUNCTION_HELP: Readonly<Record<string, FunctionHelp>> = {
222
232
  bloomberg: ["EQS"],
223
233
  },
224
234
  OMON: {
225
- summary: "Calls and puts by expiry with bid, ask, volume, open interest, implied volatility and Greeks.",
226
- usage: ["OMON NVDA"],
235
+ summary: "Calls and puts by expiry with bid, ask, spread, volume, open interest, implied volatility, Greeks, extrinsic per year and a put's cost as a percent of spot. "
236
+ + "The Strikes filter lists every strike, a count either side of the money, or a delta band such as .70 to .90 for deep in-the-money LEAPS.",
237
+ usage: ["OMON NVDA", "gloomberb fn OMON NVDA --expiration 2028-01-21"],
227
238
  keys: [key("c", "alc"), key("a", "dd to OSA"), key("s", "urface")],
228
239
  data: OPTIONS,
229
240
  bloomberg: ["OMON"],
@@ -251,21 +262,23 @@ export const FUNCTION_HELP: Readonly<Record<string, FunctionHelp>> = {
251
262
  bloomberg: ["OVME", "OVML"],
252
263
  },
253
264
  OSA: {
254
- summary: "Build a multi-leg options position and value it at any spot, date and vol shift: payoff, P&L grid, breakevens and Greeks. European pricing, so no early exercise.",
255
- usage: ["OSA AAPL"],
265
+ summary: "Build a multi-leg options position and value it at any spot, date and vol shift: payoff, P&L grid, breakevens and Greeks. European pricing, so no early exercise. "
266
+ + "With a NAV and a budget in bps it sizes the position as a hedge: contracts, premium, notional protected and coverage of an equity sleeve.",
267
+ usage: ["OSA AAPL", "gloomberb fn OSA AAPL --strategy vertical --expiration 2027-01-15",
268
+ "gloomberb fn OSA SPY --strategy put --strike 700 --expiration 2027-01-15 --nav 100m --budget-bps 50 --sleeve 100m"],
256
269
  keys: [key("a", "dd leg"), key("c", "hain"), key("d", "ate"), key("v", "ol shift")],
257
270
  data: OPTIONS,
258
271
  bloomberg: ["OSA"],
259
272
  },
260
273
  OVDV: {
261
274
  summary: "The implied volatility surface fitted from option quotes: 3D sheet, table, smiles, ATM term structure, 25-delta skew and forwards, live or on stored daily closes.",
262
- usage: ["OVDV NVDA"],
275
+ usage: ["OVDV NVDA", "gloomberb fn OVDV NVDA --tab skew --expiration 2027-01-15"],
263
276
  keys: [key("v", "iew"), key("c", "hain"), key("m", "ore expiries"), key("t", " stored dates")],
264
277
  data: { free: `${DELAYED}; stored dates at the close`, pro: "Real-time; stored dates at the close" },
265
278
  bloomberg: ["OVDV"],
266
279
  },
267
280
  HIVG: {
268
- summary: "Daily 30- and 90-day at-the-money implied vol since February 2024 against realized vol, with each measure's 52-week rank and percentile.",
281
+ summary: "Daily 30-day, 90-day and one-year at-the-money implied vol since February 2024 against realized vol, with each measure's 52-week rank and percentile.",
269
282
  usage: ["HIVG AAPL"],
270
283
  keys: [key("s", "urface")],
271
284
  data: IV_DAILY,
@@ -322,7 +335,7 @@ export const FUNCTION_HELP: Readonly<Record<string, FunctionHelp>> = {
322
335
  bloomberg: [],
323
336
  },
324
337
  VCA: {
325
- summary: "IV rank, term slope, skew and IV against realized vol for up to 60 US tickers, flagged rich or cheap against each name's own year. Alone it screens index and sector ETFs.",
338
+ summary: "IV rank, one-year IV and its percentile, term slope, skew and IV against realized vol for up to 60 US tickers, flagged rich or cheap against each name's own year. Alone it screens index and sector ETFs.",
326
339
  usage: ["VCA", "VCA NVDA, AAPL, TSLA"],
327
340
  keys: [OPEN],
328
341
  data: IV_DAILY,
@@ -386,7 +399,7 @@ export const FUNCTION_HELP: Readonly<Record<string, FunctionHelp>> = {
386
399
  bloomberg: ["DVD"],
387
400
  },
388
401
  SI: {
389
- summary: "FINRA short interest settlements with shares short, days to cover and average daily volume over time.",
402
+ summary: "FINRA short interest settlements with shares short, days to cover and average daily volume over time. Daily volume is the other tab.",
390
403
  usage: ["SI AAPL"],
391
404
  keys: [key("v", "iew"), STEP],
392
405
  data: same("Twice a month, as FINRA publishes"),
@@ -400,9 +413,9 @@ export const FUNCTION_HELP: Readonly<Record<string, FunctionHelp>> = {
400
413
  bloomberg: [],
401
414
  },
402
415
  SIV: {
403
- summary: "FINRA daily off-exchange short volume as a share of volume, against its one-year range. Not short interest; SI has that.",
416
+ summary: "The short interest pane on Daily volume: FINRA off-exchange short volume as a share of volume, against its one-year range.",
404
417
  usage: ["SIV TSLA"],
405
- keys: [STEP, OPEN_SOURCE],
418
+ keys: [key("v", "iew"), STEP, OPEN_SOURCE],
406
419
  data: same("Daily, the evening after each session"),
407
420
  bloomberg: [],
408
421
  },
@@ -411,6 +424,7 @@ export const FUNCTION_HELP: Readonly<Record<string, FunctionHelp>> = {
411
424
  usage: ["DIAG NVDA"],
412
425
  keys: [OPEN_SOURCE],
413
426
  data: { free: "A preview of the latest report, verified email", pro: "The full report, rerun on demand" },
427
+ access: "preview",
414
428
  bloomberg: [],
415
429
  },
416
430
  RISK: {
@@ -418,6 +432,7 @@ export const FUNCTION_HELP: Readonly<Record<string, FunctionHelp>> = {
418
432
  usage: ["RISK TSLA"],
419
433
  keys: [key("y", "ear"), key("o", "pen filing")],
420
434
  data: pro(AS_FILED.pro),
435
+ access: "pro",
421
436
  bloomberg: [],
422
437
  },
423
438
  EXEC: {
@@ -425,6 +440,7 @@ export const FUNCTION_HELP: Readonly<Record<string, FunctionHelp>> = {
425
440
  usage: ["EXEC NVDA"],
426
441
  keys: [key("y", "ear"), key("o", "pen filing")],
427
442
  data: pro(AS_FILED.pro),
443
+ access: "pro",
428
444
  bloomberg: ["MGMT"],
429
445
  },
430
446
  EK: {
@@ -432,6 +448,7 @@ export const FUNCTION_HELP: Readonly<Record<string, FunctionHelp>> = {
432
448
  usage: ["EK NVDA"],
433
449
  keys: [key("o", "pen filing")],
434
450
  data: pro(AS_FILED.pro),
451
+ access: "pro",
435
452
  bloomberg: ["CF"],
436
453
  },
437
454
  CALLS: {
@@ -439,6 +456,7 @@ export const FUNCTION_HELP: Readonly<Record<string, FunctionHelp>> = {
439
456
  usage: ["CALLS", "CALLS NVDA"],
440
457
  keys: [OPEN, key("/", "find"), OPEN_SOURCE],
441
458
  data: pro("Within hours of the call"),
459
+ access: "pro",
442
460
  bloomberg: ["EVT"],
443
461
  },
444
462
  JOBS: {
@@ -446,6 +464,7 @@ export const FUNCTION_HELP: Readonly<Record<string, FunctionHelp>> = {
446
464
  usage: ["JOBS", "JOBS NVDA"],
447
465
  keys: [key("1-4", " section"), key("o", "pen role"), key("c", "areers site")],
448
466
  data: pro("Daily"),
467
+ access: "pro",
449
468
  bloomberg: [],
450
469
  },
451
470
  SRCH: {
@@ -453,6 +472,7 @@ export const FUNCTION_HELP: Readonly<Record<string, FunctionHelp>> = {
453
472
  usage: ["SRCH data center capex"],
454
473
  keys: [SEARCH, key("Ctrl+S", " save search"), key("a", "lerts")],
455
474
  data: pro("As calls, stories and filings arrive"),
475
+ access: "pro",
456
476
  bloomberg: ["NSE"],
457
477
  },
458
478
  COVN: {
@@ -460,6 +480,7 @@ export const FUNCTION_HELP: Readonly<Record<string, FunctionHelp>> = {
460
480
  usage: ["COVN FICO"],
461
481
  keys: [TABS, OPEN, OPEN_SOURCE, key("f", "a"), key("m", "aturities")],
462
482
  data: { free: "As filed; three supported rows per section", pro: "As filed; all covenants, evidence and revisions" },
483
+ access: "preview",
463
484
  bloomberg: ["CAST"],
464
485
  },
465
486
  CRDOC: {
@@ -467,6 +488,7 @@ export const FUNCTION_HELP: Readonly<Record<string, FunctionHelp>> = {
467
488
  usage: ["CRDOC FICO", "COVN AAPL"],
468
489
  keys: [TABS, OPEN, OPEN_SOURCE, key("d", "es"), key("f", "a"), key("m", "aturities"), key("c", "ds")],
469
490
  data: { free: "As filed; three rows per section with supporting evidence", pro: "As filed; all stored terms, revisions and risk screens" },
491
+ access: "preview",
470
492
  bloomberg: ["CAST", "DDIS"],
471
493
  },
472
494
  ATTN: {
@@ -474,6 +496,7 @@ export const FUNCTION_HELP: Readonly<Record<string, FunctionHelp>> = {
474
496
  usage: ["ATTN", "ATTN 6758:JPX"],
475
497
  keys: [OPEN, key("e", "vidence"), key("d", "es"), key("g", "raph"), key("n", "ews")],
476
498
  data: { free: "Three published rows per section and the latest history point", pro: "All published rows and hourly history; minimum one-hour publication lag" },
499
+ access: "preview",
477
500
  bloomberg: [],
478
501
  },
479
502
  HIRE: {
@@ -481,6 +504,7 @@ export const FUNCTION_HELP: Readonly<Record<string, FunctionHelp>> = {
481
504
  usage: ["HIRE", "HIRE NET", "HIRE 0700:HKEX"],
482
505
  keys: [TABS, OPEN, key("e", "vidence"), key("o", "pen source"), key("d", "es"), key("g", "raph")],
483
506
  data: { free: "Latest values and three rows per section", pro: "Weekly history, all stored observations and evidence" },
507
+ access: "preview",
484
508
  bloomberg: [],
485
509
  },
486
510
  APPS: {
@@ -488,6 +512,7 @@ export const FUNCTION_HELP: Readonly<Record<string, FunctionHelp>> = {
488
512
  usage: ["APPS", "APPS META", "APPS 0700:HKEX"],
489
513
  keys: [TABS, OPEN, key("e", "vidence"), key("o", "pen source"), key("d", "es"), key("g", "raph")],
490
514
  data: { free: "Latest values and three rows per section", pro: "Daily observations, full history, countries and evidence" },
515
+ access: "preview",
491
516
  bloomberg: [],
492
517
  },
493
518
  CATL: {
@@ -495,6 +520,7 @@ export const FUNCTION_HELP: Readonly<Record<string, FunctionHelp>> = {
495
520
  usage: ["CATL", "CATL PFE", "CATL NOVN:SIX"],
496
521
  keys: [TABS, OPEN, OPEN_SOURCE, key("a", "lert"), key("d", "es")],
497
522
  data: { free: "Three events with primary-source evidence", pro: "All stored events, revision history and local alerts" },
523
+ access: "preview",
498
524
  bloomberg: [],
499
525
  },
500
526
  LITI: {
@@ -502,6 +528,7 @@ export const FUNCTION_HELP: Readonly<Record<string, FunctionHelp>> = {
502
528
  usage: ["LITI AAPL", "LITI MSFT"],
503
529
  keys: [TABS, OPEN, OPEN_SOURCE, key("t", "o calendar")],
504
530
  data: { free: "Three company events with evidence", pro: "All stored company dockets and history" },
531
+ access: "preview",
505
532
  bloomberg: ["LITI"],
506
533
  },
507
534
  KPIS: {
@@ -509,6 +536,7 @@ export const FUNCTION_HELP: Readonly<Record<string, FunctionHelp>> = {
509
536
  usage: ["KPIS CRM", "KPIS 005930:KRX"],
510
537
  keys: [TABS, OPEN, key("e", "vidence"), OPEN_SOURCE],
511
538
  data: { free: "Pro dataset; fixed latest preview with evidence", pro: "As disclosed; all stored observations and history" },
539
+ access: "preview",
512
540
  bloomberg: [],
513
541
  },
514
542
  GUIDE: {
@@ -516,6 +544,7 @@ export const FUNCTION_HELP: Readonly<Record<string, FunctionHelp>> = {
516
544
  usage: ["GUIDE DAL", "GUIDE CRM"],
517
545
  keys: [TABS, OPEN, key("e", "vidence"), OPEN_SOURCE],
518
546
  data: { free: "Pro dataset; fixed latest preview with evidence", pro: "As issued; full guidance history and actual matches" },
547
+ access: "preview",
519
548
  bloomberg: [],
520
549
  },
521
550
  EXPO: {
@@ -523,6 +552,7 @@ export const FUNCTION_HELP: Readonly<Record<string, FunctionHelp>> = {
523
552
  usage: ["EXPO AAPL=60% NVDA=40%", "EXPO PORT:portfolio-id", "EXPO WATCH:watchlist-id"],
524
553
  keys: [TABS, OPEN, key("s", "cenario and holdings"), key("e", "vidence"), key("a", "ll company disclosures"), key("v", "isibility"), key("o", "pen source")],
525
554
  data: { free: "One holding and one-hop evidence preview", pro: "Full holdings and up to four-hop paths, as filed" },
555
+ access: "preview",
526
556
  bloomberg: ["PORT", "SPLC"],
527
557
  },
528
558
  SPLC: {
@@ -530,6 +560,7 @@ export const FUNCTION_HELP: Readonly<Record<string, FunctionHelp>> = {
530
560
  usage: ["SPLC NVDA", "SUPPLY AAPL", "SPLC 005930.KS", "SPLC 8035.T"],
531
561
  keys: [OPEN, key("e", "vidence"), key("d", "es"), key("g", "raph")],
532
562
  data: { free: "Three relationships per role with evidence and a one-hop graph preview", pro: "Full evidence tiers, one-to-four-hop graphs and ranked paths" },
563
+ access: "preview",
533
564
  bloomberg: ["SPLC"],
534
565
  },
535
566
  AWARDS: {
@@ -537,6 +568,7 @@ export const FUNCTION_HELP: Readonly<Record<string, FunctionHelp>> = {
537
568
  usage: ["AWARDS", "AWARDS LMT", "AWARDS BA.:LSE"],
538
569
  keys: [TABS, OPEN, SEARCH, key("e", "vidence"), key("o", "pen source"), key("d", "es"), key("f", "a"), key("g", "raph"), key("s", "plc"), key("c", "alendar")],
539
570
  data: { free: "Pro preview: three rows per section", pro: "All collected awards, history, revisions and relationships" },
571
+ access: "preview",
540
572
  bloomberg: [],
541
573
  },
542
574
  SEG: {
@@ -544,6 +576,7 @@ export const FUNCTION_HELP: Readonly<Record<string, FunctionHelp>> = {
544
576
  usage: ["SEG AAPL"],
545
577
  keys: [],
546
578
  data: { free: "First two lines, about five weeks after each filing", pro: "Every line, about five weeks after each filing" },
579
+ access: "preview",
547
580
  bloomberg: [],
548
581
  },
549
582
  TAS: {
@@ -591,7 +624,7 @@ export const FUNCTION_HELP: Readonly<Record<string, FunctionHelp>> = {
591
624
  ASKG: {
592
625
  summary: "Ask a question about what is on screen and watch the tools Gloom runs to answer it.",
593
626
  usage: ["ASKG why is NVDA down today"],
594
- keys: [key("n", "ew conversation"), key("t", "ickers"), key("o", "pen pane")],
627
+ keys: [key("n", "ew conversation"), key("g", "ood answer"), key("b", "ad answer"), key("t", "ickers"), key("o", "pen pane")],
595
628
  data: null,
596
629
  bloomberg: ["ASKB"],
597
630
  },
@@ -691,7 +724,7 @@ export const FUNCTION_HELP: Readonly<Record<string, FunctionHelp>> = {
691
724
  bloomberg: ["IMAP"],
692
725
  },
693
726
  FXC: {
694
- summary: "A cross-rate matrix for the major currencies, or for any of 45 chosen in its settings.",
727
+ summary: "A cross-rate matrix for the major currencies, or for any of 45 chosen in its settings or with --currencies from the command line (gloomberb fn FXC --currencies USD,ZAR,NGN).",
695
728
  usage: ["FXC"],
696
729
  keys: [],
697
730
  data: FX,
@@ -702,6 +735,7 @@ export const FUNCTION_HELP: Readonly<Record<string, FunctionHelp>> = {
702
735
  usage: ["PERP", "PERP BTC", "PERP TSLA"],
703
736
  keys: [TABS, OPEN, SEARCH, key("e", "vidence"), key("a", "lert")],
704
737
  data: { free: "A fixed preview and any one market's latest values", pro: "Every market, full rankings and stored history; source timestamps retained" },
738
+ access: "preview",
705
739
  bloomberg: [],
706
740
  },
707
741
  CRYP: {
@@ -751,6 +785,7 @@ export const FUNCTION_HELP: Readonly<Record<string, FunctionHelp>> = {
751
785
  usage: ["POWER", "POWER NEE"],
752
786
  keys: [SEARCH, key("o", "pen source"), key("d", "es"), key("f", "a"), key("g", "raph"), key("s", "plc"), key("c", "ompute"), key("t", "BO")],
753
787
  data: { free: "Three rows per section; limited history", pro: "Snapshots as public registers update; coverage by region" },
788
+ access: "preview",
754
789
  bloomberg: [],
755
790
  },
756
791
  GPU: {
@@ -758,6 +793,7 @@ export const FUNCTION_HELP: Readonly<Record<string, FunctionHelp>> = {
758
793
  usage: ["GPU", "GPU H100", "GPU B200"],
759
794
  keys: [key("t", "BO")],
760
795
  data: same("Hourly asks and AWS spot; other published prices every 6 or 24 hours"),
796
+ access: "preview",
761
797
  bloomberg: [],
762
798
  },
763
799
  NGS: {
@@ -794,6 +830,7 @@ export const FUNCTION_HELP: Readonly<Record<string, FunctionHelp>> = {
794
830
  usage: ["FLOW"],
795
831
  keys: [OPEN],
796
832
  data: pro(REAL_TIME),
833
+ access: "pro",
797
834
  bloomberg: ["FLOW"],
798
835
  },
799
836
  HALT: {
@@ -876,8 +913,8 @@ export const FUNCTION_HELP: Readonly<Record<string, FunctionHelp>> = {
876
913
  bloomberg: ["CRD"],
877
914
  },
878
915
  AUCT: {
879
- summary: "Bill, note, bond and TIPS auction results: high rate, bid-to-cover, indirect share and size, with the auctions announced next.",
880
- usage: ["AUCT", "AUCT 10-year"],
916
+ summary: "Bill, note, bond and TIPS auction results: high rate, stop-out versus average, bid-to-cover, indirect, direct and dealer takedown and size, with the auctions announced next. Searchable by benchmark (10Y) or CUSIP; history reaches back 10 years.",
917
+ usage: ["AUCT", "AUCT 10Y", "AUCT 91282CRF0"],
881
918
  keys: [SEARCH, key("f", "ilter"), OPEN],
882
919
  data: same("Daily, after each auction"),
883
920
  bloomberg: ["AUCT"],
@@ -897,16 +934,16 @@ export const FUNCTION_HELP: Readonly<Record<string, FunctionHelp>> = {
897
934
  bloomberg: ["CDS"],
898
935
  },
899
936
  CDX: {
900
- summary: "CDX IG, HY and EM with iTraxx Main and Crossover on the run: the 5Y level, 1D and 1W moves, 1Y percentile and the day's print count. IG and iTraxx in spread, HY and EM in price.",
937
+ summary: "CDX IG, HY and EM with iTraxx Main and Crossover on the run: the 5Y level, 1D and 1W moves, 1Y percentile and the day's print count. IG and iTraxx in spread, HY and EM in price. Sovereign CDS is the other tab.",
901
938
  usage: ["CDX"],
902
- keys: [OPEN],
939
+ keys: [TABS, OPEN],
903
940
  data: same("Delayed, as trades are disseminated"),
904
941
  bloomberg: ["CDX"],
905
942
  },
906
943
  SOVR: {
907
- summary: "Sovereign 5Y CDS ranked by the month's move, beside the local currency's move against the dollar, with each country's year of history.",
944
+ summary: "The CDS pane on Sovereign: 5Y CDS ranked by the month's move, beside the local currency's move against the dollar, with each country's year of history.",
908
945
  usage: ["SOVR"],
909
- keys: [OPEN],
946
+ keys: [TABS, OPEN],
910
947
  data: same("Delayed, as trades are disseminated"),
911
948
  bloomberg: ["SOVR", "WCDS"],
912
949
  },
@@ -1127,6 +1164,14 @@ export const FUNCTION_HELP: Readonly<Record<string, FunctionHelp>> = {
1127
1164
  data: null,
1128
1165
  bloomberg: [],
1129
1166
  },
1167
+ MCP: {
1168
+ summary: "Connects Claude Code, Codex, Cursor or any MCP client to Gloom's research tools: the command to copy, or a key to create.",
1169
+ usage: ["MCP"],
1170
+ keys: [key("c", "opy"), key("←/→", " client"), key("k", "ey")],
1171
+ data: null,
1172
+ bloomberg: [],
1173
+ docs: "https://gloom.sh/docs/mcp",
1174
+ },
1130
1175
  BR: {
1131
1176
  summary: "Broker profiles, account sync and connection status. Every broker is a plugin you install first.",
1132
1177
  usage: ["BR"],
@@ -1179,9 +1224,9 @@ export const FUNCTION_HELP: Readonly<Record<string, FunctionHelp>> = {
1179
1224
  bloomberg: [],
1180
1225
  },
1181
1226
  PL: {
1182
- summary: "The plugin directory: install from GitHub, and enable or disable the plugins you have.",
1227
+ summary: "What Gloomberb is made of: switch built-ins on and off, one by one or with a starter pack, and install plugins from GitHub.",
1183
1228
  usage: ["PL"],
1184
- keys: [key("i", "nstall"), key("e", "nable"), key("s", "etup"), SEARCH],
1229
+ keys: [key("e", "nable"), key("a", " packs"), key("i", "nstall"), SEARCH],
1185
1230
  data: null,
1186
1231
  bloomberg: [],
1187
1232
  },
@@ -18,7 +18,7 @@ import type {
18
18
  HeadlessSeriesResult,
19
19
  HeadlessSnapshotResult,
20
20
  } from "../../types/plugin";
21
- import { cliStyles, renderSection, renderStats, renderTable } from "../../utils/cli-output";
21
+ import { cliStyles, renderSection, renderStats, renderTable, wrapToTerminal } from "../../utils/cli-output";
22
22
  import { humanizeCliKey } from "../result";
23
23
  import {
24
24
  exportEntriesTable,
@@ -382,6 +382,7 @@ function renderRows(
382
382
  header: humanizeCliKey(column.header),
383
383
  align: column.align,
384
384
  width: column.width,
385
+ shrink: column.shrink,
385
386
  })),
386
387
  rows.map((row) => columns.map((column) => {
387
388
  const value = row[column.key];
@@ -559,8 +560,8 @@ function reportTitle(
559
560
  /** One message stays on the label's line; several each get a line of their own, so none runs into the next. */
560
561
  function renderMessages(label: string, messages: readonly string[]): string[] {
561
562
  return messages.length === 1
562
- ? [cliStyles.warning(`${label}: ${messages[0]}`)]
563
- : [cliStyles.warning(`${label}:`), ...messages.map((message) => ` ${message}`)];
563
+ ? [cliStyles.warning(wrapToTerminal(`${label}: ${messages[0]}`))]
564
+ : [cliStyles.warning(`${label}:`), ...messages.map((message) => wrapToTerminal(` ${message}`))];
564
565
  }
565
566
 
566
567
  /**
@@ -603,7 +604,7 @@ export function renderHeadlessPaneText(
603
604
  }
604
605
  if (result.notes?.length) lines.push("", ...renderMessages("Notes", result.notes));
605
606
  if (result.errors?.length) lines.push("", ...renderMessages("Errors", result.errors));
606
- return [lines.join("\n").trimEnd(), "", cliStyles.muted(formatFreshnessLine(freshness))].join("\n");
607
+ return [lines.join("\n").trimEnd(), "", cliStyles.muted(wrapToTerminal(formatFreshnessLine(freshness)))].join("\n");
607
608
  }
608
609
 
609
610
  function resultRowCount(definition: HeadlessPaneDefinition, result: HeadlessPaneResult): number {
@@ -118,6 +118,7 @@ export async function runPaneScreenshot(args: string[], ctx: CliCommandContext)
118
118
  theme: parsed.theme,
119
119
  scale: parsed.scale,
120
120
  watermark: parsed.watermark,
121
+ statusLine: parsed.status !== false,
121
122
  options: parsed.options,
122
123
  });
123
124
  if (parsed.requireBotSafe && !result.usable) {
@@ -137,7 +138,9 @@ export async function runPaneScreenshot(args: string[], ctx: CliCommandContext)
137
138
  ["Rows", String(data.rowCount)],
138
139
  ["Status", issues.length > 0 ? cliStyles.warning(issues.join(", ")) : cliStyles.success("complete")],
139
140
  ];
141
+ if (data.render.statusLine) stats.push(["Status line", data.render.statusLine]);
140
142
  if (data.unusableReason) stats.push(["Reason", data.unusableReason]);
143
+ if (data.notices?.length) stats.push(["Notes", data.notices.join(" ")]);
141
144
  if (data.unavailableSymbols.length > 0) stats.push(["No data for", data.unavailableSymbols.join(", ")]);
142
145
  if (data.render.emptyStateMarkers.length > 0) stats.push(["Empty states", data.render.emptyStateMarkers.join(", ")]);
143
146
  if (data.render.missingExpectedText.length > 0) stats.push(["Missing text", data.render.missingExpectedText.join(", ")]);
@@ -0,0 +1,133 @@
1
+ import { canonicalExchange, isUsListingExchange } from "../../utils/exchanges";
2
+ import {
3
+ activeUsMarketSession,
4
+ isAlwaysOpenExchange,
5
+ isRegularSessionTime,
6
+ latestRegularSessionClose,
7
+ latestRegularSessionOpen,
8
+ nextRegularSessionOpen,
9
+ } from "../../market-data/market/freshness";
10
+ import { currentFxClosureStart } from "../../utils/fx-market-hours";
11
+ import { zonedDateKey } from "../../utils/zoned-date-time";
12
+ import type { ReportTime } from "../../utils/utc-time";
13
+
14
+ /** Where the venues behind a quote report stand, as a report says it after the delay. */
15
+ type ReportMarketState = "open" | "pre-market" | "after-hours" | "closed";
16
+
17
+ export interface ReportMarket {
18
+ state: ReportMarketState;
19
+ /** While no venue is in its regular session: the next regular open of the first to open, when its calendar is known. */
20
+ reopensAt?: string;
21
+ /** That open's date at its venue, so a Monday open in Sydney reads Monday. */
22
+ reopensOn?: string;
23
+ }
24
+
25
+ /** One dated row of a quote report: the venue it trades on and the session its source reports. */
26
+ export interface SessionObservation {
27
+ exchange: string;
28
+ marketState?: string;
29
+ time: ReportTime | null;
30
+ }
31
+
32
+ interface VenueSession {
33
+ state: ReportMarketState | "always";
34
+ next?: { date: string; open: number };
35
+ /** The latest regular session that has closed: its local date and open. */
36
+ last?: { date: string; open: number | null };
37
+ timeZone?: string;
38
+ }
39
+
40
+ const CLOSED_STATES = new Set(["CLOSED", "PREPRE", "POSTPOST"]);
41
+
42
+ /**
43
+ * A venue's session now, from its calendar (weekends and published holidays),
44
+ * or from the state its source reports when the app has no calendar for it,
45
+ * such as an index publisher or a futures exchange. Null when neither says.
46
+ */
47
+ function venueSession(exchange: string, marketState: string | undefined, now: number): VenueSession | null {
48
+ if (isAlwaysOpenExchange(exchange)) return { state: "always" };
49
+ const next = nextRegularSessionOpen(exchange, now);
50
+ if (next) {
51
+ const { timeZone } = next;
52
+ const latestClose = latestRegularSessionClose(exchange, now);
53
+ const last = latestClose ? { date: latestClose.date, open: latestRegularSessionOpen(exchange, latestClose.close) } : undefined;
54
+ if (isRegularSessionTime(exchange, now)) return { state: "open", timeZone };
55
+ if (isUsListingExchange(exchange)) {
56
+ const today = zonedDateKey(now, timeZone);
57
+ const session = activeUsMarketSession(now);
58
+ if (session === "PRE" && next.date === today) return { state: "pre-market", next, last, timeZone };
59
+ if (session === "POST" && last?.date === today) return { state: "after-hours", next, last, timeZone };
60
+ }
61
+ return { state: "closed", next, last, timeZone };
62
+ }
63
+ if (marketState === "REGULAR") return { state: "open" };
64
+ if (marketState === "PRE") return { state: "pre-market" };
65
+ if (marketState === "POST") return { state: "after-hours" };
66
+ if (marketState && CLOSED_STATES.has(marketState)) return { state: "closed" };
67
+ return null;
68
+ }
69
+
70
+ /** The venue spot FX pairs trade on. It has no session calendar here; its week is in `fx-market-hours`. */
71
+ const FX_VENUE = "CCY";
72
+ const DAY_MS = 24 * 60 * 60_000;
73
+
74
+ /**
75
+ * The newest observation is its venue's latest close: the venue has not
76
+ * opened since, and the print is from that session's day, after its open (an
77
+ * after-hours print of that day counts). Returns that session's local date.
78
+ */
79
+ function closeDateOf(observation: SessionObservation, session: VenueSession, now: number): string | null {
80
+ const time = observation.time;
81
+ if (!time || time.dateOnly) return null;
82
+ // FX closes once a week, Friday 17:00 New York time, and its trading day turns
83
+ // at 17:00: a print from that last day, or a quiet tick over the weekend, is
84
+ // that Friday's close, not the day it happens to be stamped with.
85
+ const weekClose = canonicalExchange(observation.exchange) === FX_VENUE ? currentFxClosureStart(now) : null;
86
+ if (weekClose != null) return time.time >= weekClose - DAY_MS ? zonedDateKey(weekClose - 1, "America/New_York") : null;
87
+ if (session.last && session.timeZone) {
88
+ if (session.last.open != null && time.time < session.last.open) return null;
89
+ return zonedDateKey(time.time, session.timeZone) === session.last.date ? session.last.date : null;
90
+ }
91
+ // No calendar: the source says the session is over, and the print is dated in UTC.
92
+ return session.state === "closed" && !session.last ? new Date(time.time).toISOString().slice(0, 10) : null;
93
+ }
94
+
95
+ /**
96
+ * Where the markets behind a quote report stand now, and whether the newest
97
+ * observation is a close. Null market when the venues disagree (Tokyo open,
98
+ * New York closed), trade around the clock, or none can be placed; a report
99
+ * then says nothing rather than guess.
100
+ */
101
+ export function reportMarketSession(
102
+ observations: readonly SessionObservation[],
103
+ now: number,
104
+ ): { market: ReportMarket | null; closeDate: string | null } {
105
+ const sessions = new Map<string, VenueSession>();
106
+ let newest: { observation: SessionObservation; session: VenueSession } | null = null;
107
+ for (const observation of observations) {
108
+ const exchange = canonicalExchange(observation.exchange);
109
+ if (!exchange) continue;
110
+ const key = `${exchange}:${observation.marketState ?? ""}`;
111
+ const session = sessions.get(key) ?? venueSession(exchange, observation.marketState, now);
112
+ if (!session) continue;
113
+ sessions.set(key, session);
114
+ if (observation.time && (!newest || observation.time.time > (newest.observation.time?.time ?? -Infinity))) {
115
+ newest = { observation, session };
116
+ }
117
+ }
118
+ const states = new Set([...sessions.values()].map((session) => session.state));
119
+ if (states.size !== 1 || states.has("always")) return { market: null, closeDate: null };
120
+ const state = [...states][0] as ReportMarketState;
121
+ const reopen = state === "closed" || state === "pre-market"
122
+ ? [...sessions.values()].reduce<{ date: string; open: number } | null>((first, session) => (
123
+ session.next && (!first || session.next.open < first.open) ? session.next : first
124
+ ), null)
125
+ : null;
126
+ return {
127
+ market: {
128
+ state,
129
+ ...(reopen ? { reopensAt: new Date(reopen.open).toISOString(), reopensOn: reopen.date } : {}),
130
+ },
131
+ closeDate: (state === "closed" || state === "pre-market") && newest ? closeDateOf(newest.observation, newest.session, now) : null,
132
+ };
133
+ }
@@ -32,6 +32,8 @@ export interface ParsedPaneFunctionArgs {
32
32
  scale: number;
33
33
  /** Small label drawn in the pane title bar, e.g. a domain; null draws nothing. */
34
34
  watermark: string | null;
35
+ /** A screenshot carries its dated status line in the pane footer; `--no-status` sets this false. */
36
+ status?: boolean;
35
37
  requireBotSafe: boolean;
36
38
  /** The listing a one-ticker function's argument named, once `applyListingArgument` has resolved it. */
37
39
  listing?: ListingArg;
@@ -67,7 +69,7 @@ export function parseArgumentsOption(value: string): Record<string, string> {
67
69
  return pairs;
68
70
  }
69
71
 
70
- export function parsePaneFunctionArgs(args: string[], globalOptions: { limit?: number } = {}): ParsedPaneFunctionArgs {
72
+ export function parsePaneFunctionArgs(args: string[], globalOptions: { limit?: number; tail?: number } = {}): ParsedPaneFunctionArgs {
71
73
  const positionals: string[] = [];
72
74
  const options: Record<string, string | true> = {};
73
75
  let outputPath: string | null = null;
@@ -76,6 +78,7 @@ export function parsePaneFunctionArgs(args: string[], globalOptions: { limit?: n
76
78
  let theme: string | null = null;
77
79
  let scale = 1;
78
80
  let watermark: string | null = null;
81
+ let status = true;
79
82
  let requireBotSafe = false;
80
83
 
81
84
  for (let index = 0; index < args.length; index += 1) {
@@ -94,6 +97,11 @@ export function parsePaneFunctionArgs(args: string[], globalOptions: { limit?: n
94
97
  const equalsIndex = raw.indexOf("=");
95
98
  const key = equalsIndex >= 0 ? raw.slice(0, equalsIndex) : raw;
96
99
  const inlineValue = equalsIndex >= 0 ? raw.slice(equalsIndex + 1) : undefined;
100
+ // A switch: the token after it is the function's argument, never its value.
101
+ if (normalizeOptionKey(key) === "noStatus" && inlineValue === undefined) {
102
+ status = false;
103
+ continue;
104
+ }
97
105
  const next = args[index + 1];
98
106
  const nextValue = inlineValue === undefined && next && !next.startsWith("--") ? args[++index] : true;
99
107
  const value: string | true = inlineValue ?? nextValue ?? true;
@@ -118,6 +126,7 @@ export function parsePaneFunctionArgs(args: string[], globalOptions: { limit?: n
118
126
  scale = parseScale(value);
119
127
  } else if (normalizedKey === "watermark" && value !== true) {
120
128
  watermark = value.trim() || null;
129
+
121
130
  } else if (normalizedKey === "arguments" && value !== true) {
122
131
  Object.assign(options, parseArgumentsOption(value));
123
132
  } else {
@@ -127,10 +136,12 @@ export function parsePaneFunctionArgs(args: string[], globalOptions: { limit?: n
127
136
 
128
137
  const target = positionals[0]?.trim() ?? "";
129
138
  const arg = positionals.slice(1).join(" ").trim();
130
- // The outer CLI parser consumes --limit before fn/shot sees its arguments.
131
- // Restore it for the pane's own schema and loader, including bounds checks.
139
+ // The outer CLI parser consumes --limit and --tail before fn/shot sees its arguments.
140
+ // Restore them for the pane's own schema and loader, including bounds checks,
141
+ // so a function without a tail option says so instead of ignoring it.
132
142
  if (globalOptions.limit != null) options.limit = String(globalOptions.limit);
133
- return { target, arg, options, outputPath, width, height, theme, scale, watermark, requireBotSafe };
143
+ if (globalOptions.tail != null) options.tail = String(globalOptions.tail);
144
+ return { target, arg, options, outputPath, width, height, theme, scale, watermark, status, requireBotSafe };
134
145
  }
135
146
 
136
147
  export function parsePaneCatalogArgs(args: string[]): ParsedPaneCatalogArgs {