gloomberb 0.16.2 → 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 (527) 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/account-cache.ts +45 -0
  30. package/src/brokers/signed-in/adapter.ts +33 -2
  31. package/src/brokers/signed-in/client.ts +10 -0
  32. package/src/brokers/signed-in/sign-in-dialog.tsx +23 -9
  33. package/src/brokers/signed-in/sign-in.ts +62 -5
  34. package/src/capabilities/registry.ts +8 -1
  35. package/src/capabilities/types.ts +2 -0
  36. package/src/cli/command-options.ts +74 -0
  37. package/src/cli/commands/command-utils.ts +29 -0
  38. package/src/cli/commands/crypto-hints.ts +12 -4
  39. package/src/cli/commands/market.ts +524 -148
  40. package/src/cli/commands/options-chain.ts +172 -0
  41. package/src/cli/commands/options-leaps.ts +422 -0
  42. package/src/cli/commands/overview.ts +223 -42
  43. package/src/cli/commands/search.ts +29 -8
  44. package/src/cli/commands/system.ts +99 -19
  45. package/src/cli/commands/themes.ts +64 -0
  46. package/src/cli/commands/ticker.ts +200 -73
  47. package/src/cli/desktop-pane-shot.ts +100 -16
  48. package/src/cli/errors.ts +25 -2
  49. package/src/cli/freshness.ts +7 -4
  50. package/src/cli/fx-pair.ts +57 -0
  51. package/src/cli/help.ts +40 -7
  52. package/src/cli/history-rows.ts +187 -15
  53. package/src/cli/index-roots.ts +51 -0
  54. package/src/cli/index.ts +21 -13
  55. package/src/cli/listing-arg.ts +211 -3
  56. package/src/cli/not-a-ticker.ts +37 -0
  57. package/src/cli/options.ts +55 -7
  58. package/src/cli/pane-functions/capabilities.ts +13 -2
  59. package/src/cli/pane-functions/catalog.ts +13 -2
  60. package/src/cli/pane-functions/data.ts +36 -5
  61. package/src/cli/pane-functions/dom.ts +89 -28
  62. package/src/cli/pane-functions/freshness.ts +205 -26
  63. package/src/cli/pane-functions/function-help.ts +71 -24
  64. package/src/cli/pane-functions/headless.ts +168 -35
  65. package/src/cli/pane-functions/index.ts +12 -2
  66. package/src/cli/pane-functions/market-session.ts +133 -0
  67. package/src/cli/pane-functions/options.ts +15 -4
  68. package/src/cli/pane-functions/report-notices.ts +63 -0
  69. package/src/cli/pane-functions/report.ts +12 -1
  70. package/src/cli/pane-functions/resolver.ts +32 -8
  71. package/src/cli/pane-functions/screenshot-evidence.ts +2 -0
  72. package/src/cli/pane-functions/screenshot.ts +109 -23
  73. package/src/cli/registry.ts +8 -4
  74. package/src/cli/report-tables.ts +460 -0
  75. package/src/cli/result.ts +63 -16
  76. package/src/cli/row-window.ts +76 -0
  77. package/src/cli/scroll-truncation.ts +34 -0
  78. package/src/components/chart/composite/composite-chart.tsx +43 -4
  79. package/src/components/chart/composite/legend.tsx +39 -6
  80. package/src/components/chart/composite/rasterizer.ts +64 -4
  81. package/src/components/chart/composite/series-cues.ts +71 -0
  82. package/src/components/chart/composite/text-renderer.ts +16 -8
  83. package/src/components/chart/composite/types.ts +3 -0
  84. package/src/components/command-bar/commands/direct/index.ts +9 -1
  85. package/src/components/command-bar/commands/plugin/items.ts +3 -1
  86. package/src/components/command-bar/commands/registry.ts +7 -0
  87. package/src/components/command-bar/layout-items/focused-pane.ts +38 -0
  88. package/src/components/command-bar/pane-templates/workflow.ts +5 -0
  89. package/src/components/command-bar/routes/root/command-items.ts +2 -0
  90. package/src/components/command-bar/routes/root/plugin-turn-on.ts +92 -0
  91. package/src/components/command-bar/routes/root/results.ts +40 -10
  92. package/src/components/command-bar/routes/root/runtime.ts +8 -0
  93. package/src/components/command-bar/routes/root/search-providers.ts +97 -14
  94. package/src/components/command-bar/surface/index.tsx +18 -4
  95. package/src/components/command-bar/theme-picker.tsx +48 -13
  96. package/src/components/command-bar/workflow/ops.ts +5 -3
  97. package/src/components/data-table/export.ts +6 -51
  98. package/src/components/data-table/view.tsx +31 -10
  99. package/src/components/layout/floating-pane.tsx +6 -2
  100. package/src/components/layout/market-summary.ts +23 -9
  101. package/src/components/layout/pane/content.tsx +46 -29
  102. package/src/components/layout/pane/cycle-order.ts +2 -11
  103. package/src/components/layout/pane/header.tsx +2 -1
  104. package/src/components/layout/pane/title.ts +1 -1
  105. package/src/components/layout/presentation.ts +22 -0
  106. package/src/components/layout/shell/active-drag.ts +67 -35
  107. package/src/components/layout/shell/cursor-occlusion.ts +6 -5
  108. package/src/components/layout/shell/drag/index.ts +16 -7
  109. package/src/components/layout/shell/drag/live.ts +193 -0
  110. package/src/components/layout/shell/drag/overlays.tsx +179 -35
  111. package/src/components/layout/shell/drag/runtime.ts +62 -50
  112. package/src/components/layout/shell/drag/slide.ts +10 -0
  113. package/src/components/layout/shell/index.tsx +84 -57
  114. package/src/components/layout/shell/layout-state.ts +5 -11
  115. package/src/components/layout/shell/menu.ts +28 -1
  116. package/src/components/layout/shell/native/pointer-runtime.ts +13 -13
  117. package/src/components/layout/shell/native/surfaces.ts +30 -14
  118. package/src/components/layout/shell/pane/actions.ts +2 -1
  119. package/src/components/layout/shell/pane/layers.tsx +461 -180
  120. package/src/components/layout/shell/pane/management-shortcuts.ts +5 -0
  121. package/src/components/layout/shell/pane/new-layout.ts +116 -0
  122. package/src/components/layout/shell/shortcuts.ts +5 -2
  123. package/src/components/layout/shell/terminal-pointer-runtime.ts +18 -18
  124. package/src/components/layout/shell/visible-layout.ts +44 -1
  125. package/src/components/layout/shell/window-mode/overlays.tsx +12 -4
  126. package/src/components/layout/status-bar.tsx +4 -1
  127. package/src/components/markdown-text.tsx +9 -5
  128. package/src/components/metric-treemap/heat-surface.tsx +27 -8
  129. package/src/components/metric-treemap/heat-tiles.ts +48 -17
  130. package/src/components/onboarding/onboarding-frame.tsx +33 -10
  131. package/src/components/onboarding/onboarding-wizard.tsx +49 -40
  132. package/src/components/onboarding/portfolio-step/positions-panel.tsx +5 -2
  133. package/src/components/onboarding/pro-step-layout.ts +86 -0
  134. package/src/components/onboarding/use-onboarding-upgrade.ts +6 -2
  135. package/src/components/ui/button.tsx +10 -0
  136. package/src/components/ui/data-table/index.tsx +38 -0
  137. package/src/components/ui/data-table/types.ts +8 -1
  138. package/src/components/ui/data-table/visible-range.ts +2 -0
  139. package/src/components/ui/icon.tsx +11 -2
  140. package/src/components/ui/index.ts +1 -1
  141. package/src/core/connection-health.ts +1 -1
  142. package/src/core/state/app/layout-reducer.ts +89 -3
  143. package/src/core/state/app/state.ts +8 -5
  144. package/src/core/state/app/types.ts +13 -2
  145. package/src/data/config/layout.ts +55 -21
  146. package/src/data/config/store/fold-panes.ts +149 -0
  147. package/src/data/config/store/migrations.ts +7 -0
  148. package/src/data/config/store/node.ts +27 -6
  149. package/src/data/config/store/normalize.ts +37 -3
  150. package/src/data/json-persistence.ts +17 -3
  151. package/src/data/json-storage.ts +2 -0
  152. package/src/data/memory-resource-store.ts +46 -0
  153. package/src/i18n/es.ts +14 -1
  154. package/src/i18n/ja.ts +14 -1
  155. package/src/i18n/ko.ts +14 -1
  156. package/src/i18n/zh-cn.ts +14 -1
  157. package/src/i18n/zh-tw.ts +14 -1
  158. package/src/layout/desks.ts +1 -2
  159. package/src/layout/pane-layout-move.ts +264 -0
  160. package/src/layout/pane-manager/hidden-panes.ts +160 -0
  161. package/src/layout/pane-manager/index.ts +1 -0
  162. package/src/market-data/coordinator/entries.ts +7 -1
  163. package/src/market-data/coordinator/quotes.ts +2 -2
  164. package/src/market-data/market/freshness.ts +156 -11
  165. package/src/market-data/market/status.ts +40 -0
  166. package/src/market-data/options-alternatives.ts +69 -0
  167. package/src/market-data/quotes/contributions.ts +19 -2
  168. package/src/market-data/quotes/freshness.ts +5 -0
  169. package/src/market-data/quotes/metadata.ts +16 -0
  170. package/src/market-data/quotes/screener-live-quotes.ts +56 -5
  171. package/src/plugins/builtin/account-management/keyboard.ts +3 -0
  172. package/src/plugins/builtin/account-management/model.ts +1 -0
  173. package/src/plugins/builtin/account-management/navigation.ts +1 -1
  174. package/src/plugins/builtin/account-management/pane.tsx +31 -4
  175. package/src/plugins/builtin/alerts/quotes.ts +3 -0
  176. package/src/plugins/builtin/analytics/pane-model.ts +10 -6
  177. package/src/plugins/builtin/analytics/risk-headless.ts +3 -1
  178. package/src/plugins/builtin/analytics/risk-model.ts +37 -8
  179. package/src/plugins/builtin/analytics/risk-pane.tsx +8 -4
  180. package/src/plugins/builtin/attention/pane.tsx +1 -1
  181. package/src/plugins/builtin/backtest/pane.tsx +1 -1
  182. package/src/plugins/builtin/broker-manager/detail.tsx +4 -0
  183. package/src/plugins/builtin/broker-manager/index.tsx +7 -3
  184. package/src/plugins/builtin/broker-manager/model.ts +8 -0
  185. package/src/plugins/builtin/broker-manager/pane-actions.tsx +8 -2
  186. package/src/plugins/builtin/broker-manager/sign-in-end.ts +82 -0
  187. package/src/plugins/builtin/broker-manager/table.ts +5 -0
  188. package/src/plugins/builtin/builtin-plugin-meta.ts +121 -11
  189. package/src/plugins/builtin/catalysts/detail.tsx +1 -1
  190. package/src/plugins/builtin/chart-composer/pane.tsx +1 -1
  191. package/src/plugins/builtin/chat/channels.ts +34 -36
  192. package/src/plugins/builtin/chat/command-bar.ts +138 -0
  193. package/src/plugins/builtin/chat/composer-commands.ts +21 -1
  194. package/src/plugins/builtin/chat/content/composer-runtime.ts +11 -1
  195. package/src/plugins/builtin/chat/content/footer.tsx +5 -3
  196. package/src/plugins/builtin/chat/content/index.tsx +21 -1
  197. package/src/plugins/builtin/chat/content/mentions.ts +2 -1
  198. package/src/plugins/builtin/chat/content/user-map.ts +3 -1
  199. package/src/plugins/builtin/chat/controller/index.ts +48 -0
  200. package/src/plugins/builtin/chat/conversations.ts +256 -0
  201. package/src/plugins/builtin/chat/discord-command.ts +91 -0
  202. package/src/plugins/builtin/chat/edit-window.ts +12 -6
  203. package/src/plugins/builtin/chat/ghost-user.ts +14 -0
  204. package/src/plugins/builtin/chat/index.tsx +40 -2
  205. package/src/plugins/builtin/chat/layout.ts +2 -0
  206. package/src/plugins/builtin/chat/message/desktop.tsx +2 -1
  207. package/src/plugins/builtin/chat/message/header.tsx +24 -15
  208. package/src/plugins/builtin/chat/message/profile-popover.tsx +2 -1
  209. package/src/plugins/builtin/chat/message/render-state.ts +3 -0
  210. package/src/plugins/builtin/chat/pane-requests.ts +60 -0
  211. package/src/plugins/builtin/chat/pane-state.ts +32 -2
  212. package/src/plugins/builtin/chat/pane.tsx +8 -0
  213. package/src/plugins/builtin/cloud/askg/controller.ts +112 -4
  214. package/src/plugins/builtin/cloud/askg/conversation-store.ts +21 -0
  215. package/src/plugins/builtin/cloud/askg/manifest.ts +1 -0
  216. package/src/plugins/builtin/cloud/askg/model.ts +129 -70
  217. package/src/plugins/builtin/cloud/askg/pane.tsx +772 -377
  218. package/src/plugins/builtin/cloud/askg/protocol.ts +40 -2
  219. package/src/plugins/builtin/cloud/askg/tool-display.ts +437 -0
  220. package/src/plugins/builtin/cloud/askg/tool-timeline.tsx +403 -0
  221. package/src/plugins/builtin/cloud/company-picker.tsx +1 -9
  222. package/src/plugins/builtin/cloud/mcp-connect/command.ts +24 -0
  223. package/src/plugins/builtin/cloud/mcp-connect/dialog.tsx +360 -0
  224. package/src/plugins/builtin/cloud/mcp-connect/model.ts +135 -0
  225. package/src/plugins/builtin/cloud/mcp-connect/sections.ts +62 -0
  226. package/src/plugins/builtin/cloud/plugin.tsx +36 -1
  227. package/src/plugins/builtin/cloud/starter-symbols.ts +8 -0
  228. package/src/plugins/builtin/cloud/terminal-relay/acm-tab.tsx +89 -0
  229. package/src/plugins/builtin/cloud/terminal-relay/client.ts +97 -0
  230. package/src/plugins/builtin/cloud/terminal-relay/connect-section.tsx +57 -0
  231. package/src/plugins/builtin/cloud/terminal-relay/engine.ts +666 -0
  232. package/src/plugins/builtin/cloud/terminal-relay/grants.ts +137 -0
  233. package/src/plugins/builtin/cloud/terminal-relay/host.tsx +81 -0
  234. package/src/plugins/builtin/cloud/terminal-relay/indicator.tsx +82 -0
  235. package/src/plugins/builtin/cloud/terminal-relay/manifest.ts +234 -0
  236. package/src/plugins/builtin/cloud/terminal-relay/policy.ts +153 -0
  237. package/src/plugins/builtin/cloud/terminal-relay/prompts.tsx +168 -0
  238. package/src/plugins/builtin/cloud/terminal-relay/redact.ts +73 -0
  239. package/src/plugins/builtin/cloud/terminal-relay/summary.ts +62 -0
  240. package/src/plugins/builtin/cloud/upgrade-dialog.tsx +26 -2
  241. package/src/plugins/builtin/cloud/upgrade-personalization.ts +57 -0
  242. package/src/plugins/builtin/cloud/upgrade-tickers.ts +124 -0
  243. package/src/plugins/builtin/comment-letters/client.ts +1 -3
  244. package/src/plugins/builtin/company-attention/pane.tsx +1 -1
  245. package/src/plugins/builtin/company-kpis/client.ts +23 -8
  246. package/src/plugins/builtin/company-kpis/headless.ts +3 -1
  247. package/src/plugins/builtin/company-kpis/pane.tsx +15 -7
  248. package/src/plugins/builtin/company-kpis/screenshot-evidence.ts +10 -3
  249. package/src/plugins/builtin/composite-plugins.ts +107 -64
  250. package/src/plugins/builtin/credit-boards/cdx-pane.tsx +4 -4
  251. package/src/plugins/builtin/credit-boards/index.tsx +21 -21
  252. package/src/plugins/builtin/credit-boards/model.ts +0 -1
  253. package/src/plugins/builtin/credit-boards/pane.tsx +30 -0
  254. package/src/plugins/builtin/credit-boards/sovr-pane.tsx +4 -4
  255. package/src/plugins/builtin/debt-maturities/client.ts +37 -9
  256. package/src/plugins/builtin/debt-maturities/headless.ts +3 -1
  257. package/src/plugins/builtin/debt-maturities/pane.tsx +5 -4
  258. package/src/plugins/builtin/dividend-yield/index.tsx +1 -1
  259. package/src/plugins/builtin/dividend-yield/pane.tsx +1 -1
  260. package/src/plugins/builtin/earnings-calls/data.ts +28 -7
  261. package/src/plugins/builtin/earnings-calls/headless.ts +3 -2
  262. package/src/plugins/builtin/earnings-calls/pane.tsx +10 -5
  263. package/src/plugins/builtin/econ/calendar-model.ts +42 -17
  264. package/src/plugins/builtin/econ/detail-view.tsx +2 -2
  265. package/src/plugins/builtin/econ/index.tsx +68 -22
  266. package/src/plugins/builtin/econ-statistics/headless.ts +12 -2
  267. package/src/plugins/builtin/econ-statistics/pane.tsx +1 -1
  268. package/src/plugins/builtin/econ-statistics/view.ts +17 -0
  269. package/src/plugins/builtin/executives/data.ts +17 -6
  270. package/src/plugins/builtin/executives/pane.tsx +16 -7
  271. package/src/plugins/builtin/filing-events/pane.tsx +22 -5
  272. package/src/plugins/builtin/fx-matrix/freshness.ts +65 -0
  273. package/src/plugins/builtin/fx-matrix/index.tsx +22 -1
  274. package/src/plugins/builtin/fx-matrix/pairs.ts +1 -1
  275. package/src/plugins/builtin/fx-matrix/settings.ts +42 -2
  276. package/src/plugins/builtin/gpu/headless.ts +9 -3
  277. package/src/plugins/builtin/gpu/model.ts +14 -5
  278. package/src/plugins/builtin/help/index.tsx +1 -0
  279. package/src/plugins/builtin/holders/beneficial-client.ts +29 -7
  280. package/src/plugins/builtin/holders/beneficial-view.tsx +7 -3
  281. package/src/plugins/builtin/holders/client.ts +3 -6
  282. package/src/plugins/builtin/holders/format.ts +31 -1
  283. package/src/plugins/builtin/holders/headless.ts +32 -6
  284. package/src/plugins/builtin/holders/pane.tsx +25 -13
  285. package/src/plugins/builtin/holders/report-header.ts +46 -5
  286. package/src/plugins/builtin/insider/index.tsx +4 -4
  287. package/src/plugins/builtin/iv-history/charts.tsx +21 -7
  288. package/src/plugins/builtin/iv-history/client.ts +12 -2
  289. package/src/plugins/builtin/iv-history/format.ts +33 -2
  290. package/src/plugins/builtin/iv-history/headless.ts +22 -10
  291. package/src/plugins/builtin/iv-history/index.tsx +3 -3
  292. package/src/plugins/builtin/iv-history/model.ts +61 -13
  293. package/src/plugins/builtin/iv-history/pane.tsx +11 -3
  294. package/src/plugins/builtin/iv-history/screen-pane.tsx +42 -18
  295. package/src/plugins/builtin/jobs/pane.tsx +1 -1
  296. package/src/plugins/builtin/kelly-sizer/headless.ts +149 -0
  297. package/src/plugins/builtin/kelly-sizer/history.ts +80 -0
  298. package/src/plugins/builtin/kelly-sizer/index.tsx +2 -0
  299. package/src/plugins/builtin/kelly-sizer/pane.tsx +121 -45
  300. package/src/plugins/builtin/kelly-sizer/portfolio.ts +25 -0
  301. package/src/plugins/builtin/kelly-sizer/sections.tsx +14 -0
  302. package/src/plugins/builtin/kelly-sizer/types.ts +9 -1
  303. package/src/plugins/builtin/layout-manager/index.tsx +9 -1
  304. package/src/plugins/builtin/macro-day/client.ts +24 -0
  305. package/src/plugins/builtin/macro-day/headless.ts +11 -8
  306. package/src/plugins/builtin/macro-day/index.tsx +3 -0
  307. package/src/plugins/builtin/macro-day/model.ts +11 -6
  308. package/src/plugins/builtin/macro-day/pane.tsx +12 -8
  309. package/src/plugins/builtin/macro-day/release-table.ts +40 -0
  310. package/src/plugins/builtin/macro-day/releases.ts +62 -44
  311. package/src/plugins/builtin/market-heatmap/data.ts +25 -5
  312. package/src/plugins/builtin/market-heatmap/evidence.ts +90 -0
  313. package/src/plugins/builtin/market-heatmap/index.tsx +144 -63
  314. package/src/plugins/builtin/market-heatmap/model.ts +94 -3
  315. package/src/plugins/builtin/market-heatmap/portfolio.ts +12 -2
  316. package/src/plugins/builtin/market-movers/headless.ts +31 -4
  317. package/src/plugins/builtin/market-movers/index.tsx +8 -1
  318. package/src/plugins/builtin/market-movers/model.ts +71 -17
  319. package/src/plugins/builtin/market-movers/table.ts +50 -23
  320. package/src/plugins/builtin/members/pane.tsx +10 -0
  321. package/src/plugins/builtin/news/headless.ts +9 -2
  322. package/src/plugins/builtin/news/wire/news/footer.ts +10 -0
  323. package/src/plugins/builtin/openfda/client.ts +1 -1
  324. package/src/plugins/builtin/options/carry.ts +95 -0
  325. package/src/plugins/builtin/options/index.tsx +58 -5
  326. package/src/plugins/builtin/options/strike-window.ts +183 -0
  327. package/src/plugins/builtin/options/table.ts +55 -3
  328. package/src/plugins/builtin/options/types.ts +8 -1
  329. package/src/plugins/builtin/options/view.tsx +161 -12
  330. package/src/plugins/builtin/options-positioning/headless.ts +4 -2
  331. package/src/plugins/builtin/options-scenario/charts.tsx +2 -2
  332. package/src/plugins/builtin/options-scenario/client.ts +73 -17
  333. package/src/plugins/builtin/options-scenario/headless.ts +71 -24
  334. package/src/plugins/builtin/options-scenario/hedge.ts +284 -0
  335. package/src/plugins/builtin/options-scenario/index.tsx +9 -2
  336. package/src/plugins/builtin/options-scenario/model.ts +33 -0
  337. package/src/plugins/builtin/options-scenario/pane.tsx +40 -16
  338. package/src/plugins/builtin/pe-band/model.ts +2 -2
  339. package/src/plugins/builtin/pe-band/report-dates.ts +11 -7
  340. package/src/plugins/builtin/perps/equity-row.tsx +8 -5
  341. package/src/plugins/builtin/perps/model.ts +16 -5
  342. package/src/plugins/builtin/perps/pane.tsx +1 -1
  343. package/src/plugins/builtin/plugin-marketplace/model.ts +64 -21
  344. package/src/plugins/builtin/plugin-marketplace/packs.ts +118 -0
  345. package/src/plugins/builtin/plugin-marketplace/pane.tsx +344 -32
  346. package/src/plugins/builtin/plugin-marketplace/store.ts +7 -1
  347. package/src/plugins/builtin/plugin-module.ts +87 -4
  348. package/src/plugins/builtin/portfolio-list/account-metrics.ts +16 -1
  349. package/src/plugins/builtin/portfolio-list/allocation.ts +3 -0
  350. package/src/plugins/builtin/portfolio-list/cached-account.ts +18 -9
  351. package/src/plugins/builtin/portfolio-list/cli/portfolio-command.ts +71 -36
  352. package/src/plugins/builtin/portfolio-list/cli/render.ts +89 -18
  353. package/src/plugins/builtin/portfolio-list/cli/shared.ts +2 -16
  354. package/src/plugins/builtin/portfolio-list/headless.ts +40 -7
  355. package/src/plugins/builtin/portfolio-list/pane/index.tsx +7 -4
  356. package/src/plugins/builtin/portfolio-list/summary/index.tsx +22 -4
  357. package/src/plugins/builtin/portfolio-list/summary/live-accounts.ts +11 -1
  358. package/src/plugins/builtin/realized-vol/headless.ts +3 -0
  359. package/src/plugins/builtin/realized-vol/pane.tsx +1 -1
  360. package/src/plugins/builtin/research/corporate-actions-pane.tsx +2 -2
  361. package/src/plugins/builtin/research/equity-diagnostic-pane.tsx +1 -1
  362. package/src/plugins/builtin/research/relative-valuation-model.ts +7 -3
  363. package/src/plugins/builtin/revenue-breakdown/client.ts +13 -6
  364. package/src/plugins/builtin/revenue-breakdown/headless.ts +4 -1
  365. package/src/plugins/builtin/revenue-breakdown/pane.tsx +7 -4
  366. package/src/plugins/builtin/reverse-dcf/headless.ts +5 -1
  367. package/src/plugins/builtin/reverse-dcf/model.ts +2 -1
  368. package/src/plugins/builtin/reverse-dcf/pane.tsx +1 -1
  369. package/src/plugins/builtin/risk-factors/data.ts +23 -9
  370. package/src/plugins/builtin/risk-factors/headless.ts +5 -2
  371. package/src/plugins/builtin/risk-factors/pane.tsx +6 -5
  372. package/src/plugins/builtin/seasonality/pane.tsx +1 -1
  373. package/src/plugins/builtin/sec/index.tsx +5 -5
  374. package/src/plugins/builtin/sectors/client.ts +10 -2
  375. package/src/plugins/builtin/sectors/headless.ts +35 -6
  376. package/src/plugins/builtin/sectors/index.tsx +18 -1
  377. package/src/plugins/builtin/sectors/sector-model.ts +150 -41
  378. package/src/plugins/builtin/shared/command-tab.ts +51 -0
  379. package/src/plugins/builtin/shared/headless-market-data.ts +33 -1
  380. package/src/plugins/builtin/shared/members-menu.tsx +260 -0
  381. package/src/plugins/builtin/shared/report-freshness.ts +50 -2
  382. package/src/plugins/builtin/shared/ticker-request.ts +25 -1
  383. package/src/plugins/builtin/shared/use-quote-board.ts +25 -5
  384. package/src/plugins/builtin/shared/volatility/options.ts +1 -46
  385. package/src/plugins/builtin/short-interest/index.tsx +19 -4
  386. package/src/plugins/builtin/short-interest/surface.tsx +4 -4
  387. package/src/plugins/builtin/short-volume/index.tsx +1 -10
  388. package/src/plugins/builtin/short-volume/pane.tsx +1 -1
  389. package/src/plugins/builtin/social-mentions/pane.tsx +1 -1
  390. package/src/plugins/builtin/supply-chain/model.ts +1 -1
  391. package/src/plugins/builtin/themes/pane.tsx +3 -0
  392. package/src/plugins/builtin/ticker-detail/financials/aggregation.ts +4 -0
  393. package/src/plugins/builtin/ticker-detail/financials/model.ts +25 -2
  394. package/src/plugins/builtin/ticker-detail/headless.ts +63 -25
  395. package/src/plugins/builtin/ticker-detail/overview/model.ts +9 -4
  396. package/src/plugins/builtin/ticker-detail/overview-tab.tsx +3 -2
  397. package/src/plugins/builtin/ticker-detail/pane.tsx +4 -5
  398. package/src/plugins/builtin/ticker-detail/quote-monitor/card.tsx +94 -6
  399. package/src/plugins/builtin/treasury-auctions/cache.ts +5 -2
  400. package/src/plugins/builtin/treasury-auctions/client.ts +22 -8
  401. package/src/plugins/builtin/treasury-auctions/headless.ts +40 -4
  402. package/src/plugins/builtin/treasury-auctions/index.tsx +11 -9
  403. package/src/plugins/builtin/treasury-auctions/model.ts +197 -30
  404. package/src/plugins/builtin/treasury-auctions/pane.tsx +35 -11
  405. package/src/plugins/builtin/treasury-auctions/types.ts +11 -1
  406. package/src/plugins/builtin/vol-surface/charts.tsx +1 -3
  407. package/src/plugins/builtin/vol-surface/client.ts +6 -2
  408. package/src/plugins/builtin/vol-surface/evidence.ts +11 -6
  409. package/src/plugins/builtin/vol-surface/headless.ts +124 -20
  410. package/src/plugins/builtin/vol-surface/model.ts +23 -11
  411. package/src/plugins/builtin/vol-surface/pane.tsx +38 -27
  412. package/src/plugins/builtin/vol-surface/tables.ts +124 -0
  413. package/src/plugins/builtin/world-indices/client.ts +22 -4
  414. package/src/plugins/builtin/world-indices/headless.ts +54 -27
  415. package/src/plugins/builtin/world-indices/model.ts +4 -2
  416. package/src/plugins/builtin/world-indices/table.tsx +13 -2
  417. package/src/plugins/builtin/world-venue-map/basemap-layer.tsx +2 -0
  418. package/src/plugins/builtin/world-venue-map/basemap.ts +18 -0
  419. package/src/plugins/builtin/world-venue-map/country-labels.ts +78 -0
  420. package/src/plugins/builtin/world-venue-map/geo-series.ts +1 -1
  421. package/src/plugins/builtin/world-venue-map/geo-svg.tsx +2 -1
  422. package/src/plugins/builtin/world-venue-map/index.ts +6 -6
  423. package/src/plugins/builtin/world-venue-map/layered-pane.tsx +27 -14
  424. package/src/plugins/builtin/world-venue-map/layers.ts +68 -10
  425. package/src/plugins/builtin/world-venue-map/map.tsx +198 -62
  426. package/src/plugins/builtin/world-venue-map/model.ts +16 -0
  427. package/src/plugins/builtin/world-venue-map/natural-earth/index.chunk.ts +3 -0
  428. package/src/plugins/builtin/world-venue-map/natural-earth/labels.chunk.ts +244 -0
  429. package/src/plugins/builtin/world-venue-map/pane.tsx +16 -10
  430. package/src/plugins/builtin/yield-curve/index.tsx +1 -1
  431. package/src/plugins/builtin-editorial.ts +126 -0
  432. package/src/plugins/catalog-backend.ts +16 -9
  433. package/src/plugins/catalog-browser.ts +127 -63
  434. package/src/plugins/catalog-manifest.ts +73 -40
  435. package/src/plugins/catalog-ui.ts +26 -6
  436. package/src/plugins/extracted-plugins.ts +7 -1
  437. package/src/plugins/ownership.ts +150 -7
  438. package/src/plugins/plugin-functions.ts +54 -0
  439. package/src/plugins/plugin-off.ts +36 -0
  440. package/src/plugins/registry/host-actions.ts +16 -0
  441. package/src/plugins/registry/index.ts +84 -24
  442. package/src/plugins/registry/plugin-state.ts +25 -1
  443. package/src/plugins/runtime/context.tsx +29 -0
  444. package/src/react/input.ts +48 -1
  445. package/src/remote/app-host.tsx +5 -0
  446. package/src/remote/controller.ts +3 -53
  447. package/src/remote/matching.ts +69 -0
  448. package/src/remote/schema.ts +1 -1
  449. package/src/remote/semantic-tree.tsx +14 -0
  450. package/src/remote/types.ts +2 -0
  451. package/src/renderers/browser/app-services.ts +3 -1
  452. package/src/renderers/dom/data-table/dom.ts +31 -0
  453. package/src/renderers/dom/data-table/index.tsx +5 -0
  454. package/src/renderers/dom/desktop/icons.tsx +14 -0
  455. package/src/renderers/dom/desktop/query-bar.tsx +59 -32
  456. package/src/renderers/dom/host/box.tsx +113 -17
  457. package/src/renderers/dom/host/drag-shield.ts +35 -0
  458. package/src/renderers/dom/host/live-frame.ts +62 -0
  459. package/src/renderers/dom/host/mouse.ts +8 -1
  460. package/src/renderers/dom/host/scroll-box.tsx +6 -5
  461. package/src/renderers/dom/host/tabs.tsx +3 -2
  462. package/src/renderers/dom/input-host.tsx +6 -1
  463. package/src/renderers/dom/styles.css +26 -5
  464. package/src/renderers/electrobun/bun/desktop/backend-requests.ts +7 -0
  465. package/src/renderers/electrobun/bun/desktop/backend.ts +7 -1
  466. package/src/renderers/electrobun/bun/desktop/detached-windows.ts +12 -1
  467. package/src/renderers/electrobun/bun/desktop/initialization.ts +15 -1
  468. package/src/renderers/electrobun/shared/protocol.ts +12 -1
  469. package/src/renderers/electrobun/view/cli-pane-shot-entry.tsx +4 -1
  470. package/src/renderers/electrobun/view/cli-pane-shot-frame.tsx +101 -5
  471. package/src/renderers/electrobun/view/host/native.ts +0 -10
  472. package/src/renderers/electrobun/view/host/window-move.ts +28 -0
  473. package/src/renderers/electrobun/view/main.tsx +4 -1
  474. package/src/renderers/electrobun/view/remote/persistence.ts +15 -2
  475. package/src/renderers/electrobun/view/ui-host.tsx +2 -5
  476. package/src/renderers/opentui/input-host.tsx +6 -1
  477. package/src/renderers/opentui/start.tsx +9 -0
  478. package/src/renderers/opentui/ui-host.tsx +7 -1
  479. package/src/shares/portable-layout.ts +16 -6
  480. package/src/sources/gloomberb-cloud/index.ts +19 -10
  481. package/src/sources/gloomberb-cloud/normalizers.ts +20 -21
  482. package/src/sources/listing-symbols.ts +11 -5
  483. package/src/sources/provider-errors.ts +88 -3
  484. package/src/sources/provider-router/batches.ts +3 -3
  485. package/src/sources/provider-router/cached-routes.ts +8 -4
  486. package/src/sources/provider-router/financial-routes.ts +13 -7
  487. package/src/sources/provider-router/financials.ts +106 -16
  488. package/src/sources/provider-router/history.ts +27 -11
  489. package/src/sources/provider-router/index.ts +1 -1
  490. package/src/sources/provider-router/primary.ts +24 -6
  491. package/src/sources/sec-edgar.ts +68 -8
  492. package/src/state/pane-scroll-registry.tsx +67 -35
  493. package/src/sync/core-contributors.ts +4 -3
  494. package/src/test-support/cli-context.ts +2 -1
  495. package/src/test-support/data-provider.ts +34 -0
  496. package/src/test-support/margin-account.ts +108 -0
  497. package/src/test-support/shell-pane-keys.tsx +1 -0
  498. package/src/theme/series-colors.ts +46 -0
  499. package/src/theme/themes.ts +149 -0
  500. package/src/tickers/search/index.ts +22 -2
  501. package/src/tickers/search/ranking.ts +45 -1
  502. package/src/tickers/search/types.ts +3 -1
  503. package/src/time-series/resolution.ts +15 -0
  504. package/src/time-series/resolve.ts +1 -14
  505. package/src/types/config.ts +61 -1
  506. package/src/types/financials.ts +32 -3
  507. package/src/types/headless.ts +11 -0
  508. package/src/types/instrument.ts +8 -0
  509. package/src/types/plugin.ts +49 -3
  510. package/src/ui/host.tsx +16 -0
  511. package/src/ui/index.tsx +10 -3
  512. package/src/ui/scroll-box-axis.ts +26 -0
  513. package/src/utils/cli-output.ts +14 -1
  514. package/src/utils/currency-units.ts +8 -3
  515. package/src/utils/depositary-receipt.ts +54 -10
  516. package/src/utils/display-number.ts +63 -0
  517. package/src/utils/exchanges.ts +13 -0
  518. package/src/utils/format.ts +2 -1
  519. package/src/utils/fundamentals.ts +17 -1
  520. package/src/utils/fx-market-hours.ts +34 -0
  521. package/src/utils/option-expiry.ts +126 -0
  522. package/src/utils/price-history-integrity.ts +19 -6
  523. package/src/utils/price-history.ts +39 -6
  524. package/src/utils/rpc-timeout-error.ts +6 -2
  525. package/src/utils/sec-eps-basis.ts +159 -30
  526. package/src/utils/sec.ts +38 -34
  527. package/src/utils/throttled-fetch.ts +51 -22
@@ -25,6 +25,7 @@ import {
25
25
  type ParsedPaneFunctionArgs,
26
26
  } from "./options";
27
27
  import {
28
+ capabilityHasOption,
28
29
  capabilityPaneSettings,
29
30
  getHeadlessPaneDefinition,
30
31
  getPaneFunctionCapability,
@@ -46,6 +47,8 @@ export interface ResolvedPaneFunction {
46
47
  optionSettings: Record<string, unknown>;
47
48
  capability: PaneFunctionCapability;
48
49
  options: NormalizedPaneFunctionOptions;
50
+ /** `--section` of a report: the table `--csv` and `--ndjson` write, when the function has no `section` option of its own. */
51
+ tableSection?: string | true;
49
52
  }
50
53
 
51
54
  async function buildPaneInstance(
@@ -126,12 +129,28 @@ export async function applyListingArgument(
126
129
  return { ...args, arg: listing.key, options, listing };
127
130
  }
128
131
 
132
+ /**
133
+ * `--section` picks one table of a report's `--csv` or `--ndjson` output. A
134
+ * function that has a `section` option of its own (CALLS: which part of a
135
+ * transcript) keeps the flag; its report is one table, so there is nothing to
136
+ * pick there.
137
+ */
138
+ function takeTableSection(
139
+ capability: PaneFunctionCapability,
140
+ options: ParsedPaneFunctionArgs["options"],
141
+ ): { options: ParsedPaneFunctionArgs["options"]; tableSection?: string | true } {
142
+ if (!("section" in options) || capabilityHasOption(capability, "section")) return { options };
143
+ const { section, ...rest } = options;
144
+ return { options: rest, tableSection: section };
145
+ }
146
+
129
147
  export async function resolvePaneFunction(
130
148
  registry: PaneFunctionCatalog,
131
149
  context: MarketContext,
132
- args: ParsedPaneFunctionArgs,
133
- resolutionSettings: { strictHeadlessOptions?: boolean } = {},
150
+ parsedArgs: ParsedPaneFunctionArgs,
151
+ resolutionSettings: { strictHeadlessOptions?: boolean; tableSection?: boolean } = {},
134
152
  ): Promise<ResolvedPaneFunction> {
153
+ let args = parsedArgs;
135
154
  if (!args.target) {
136
155
  throw new Error("Usage: gloomberb fn <function-or-pane> [argument] [--key value]");
137
156
  }
@@ -152,15 +171,19 @@ export async function resolvePaneFunction(
152
171
  const createOptions = buildCreateOptions(template, args.arg);
153
172
  const headless = getHeadlessPaneDefinition(template, pane);
154
173
  const capability = getPaneFunctionCapability(template, pane);
174
+ let tableSection: string | true | undefined;
175
+ if (resolutionSettings.tableSection) {
176
+ const taken = takeTableSection(capability, args.options);
177
+ args = { ...args, options: taken.options };
178
+ tableSection = taken.tableSection;
179
+ }
155
180
  const normalizedOptions = normalizeCapabilityOptions(capability, args.options, {
156
181
  strict: args.requireBotSafe || (!!headless && resolutionSettings.strictHeadlessOptions === true),
157
182
  });
158
- const settings = capability.botSafe
159
- ? {
160
- ...optionSettings(args.options),
161
- ...capabilityPaneSettings(capability, normalizedOptions),
162
- }
163
- : optionSettings(args.options);
183
+ const settings = {
184
+ ...optionSettings(args.options),
185
+ ...capabilityPaneSettings(capability, normalizedOptions),
186
+ };
164
187
  if (args.requireBotSafe) {
165
188
  validateTickerCardinality(capability, createOptions);
166
189
  }
@@ -177,6 +200,7 @@ export async function resolvePaneFunction(
177
200
  optionSettings: settings,
178
201
  capability,
179
202
  options: normalizedOptions,
203
+ ...(tableSection !== undefined ? { tableSection } : {}),
180
204
  };
181
205
  resolved.instance = await buildPaneInstance(resolved, context, args.arg);
182
206
  return resolved;
@@ -18,6 +18,7 @@ import { scenarioScreenshotEvidence } from "../../plugins/builtin/options-scenar
18
18
  import { realizedVolScreenshotEvidence } from "../../plugins/builtin/realized-vol/evidence";
19
19
  import { volSurfaceScreenshotEvidence } from "../../plugins/builtin/vol-surface/evidence";
20
20
  import { volatilityScreenshotEvidence } from "../../plugins/builtin/volatility/evidence";
21
+ import { marketHeatmapScreenshotEvidence } from "../../plugins/builtin/market-heatmap/evidence";
21
22
  import { worldMapScreenshotEvidence } from "../../plugins/builtin/world-venue-map/evidence";
22
23
 
23
24
  /** The envelope every pane's rendered chart-data evidence carries. */
@@ -95,6 +96,7 @@ const PANE_SCREENSHOT_EVIDENCE: readonly PaneScreenshotEvidenceHook[] = [
95
96
  volSurfaceScreenshotEvidence,
96
97
  volatilityScreenshotEvidence,
97
98
  worldMapScreenshotEvidence,
99
+ marketHeatmapScreenshotEvidence,
98
100
  ];
99
101
 
100
102
  export function paneScreenshotEvidenceHook(resolved: ResolvedPaneFunction): PaneScreenshotEvidenceHook | null {
@@ -1,4 +1,5 @@
1
1
  import { fetchTape } from "../../plugins/builtin/time-sales/client";
2
+ import { isOptionsUnavailableError } from "../../market-data/options-alternatives";
2
3
  import type { TapeCapture } from "../../plugins/builtin/time-sales/snapshot-client";
3
4
  import { apiClient } from "../../api-client";
4
5
  import { snapshotInstrumentKey, type SnapshotMarketData } from "../../market-data/snapshot-provider";
@@ -9,7 +10,7 @@ import { dirname, resolve } from "path";
9
10
  import { mkdir } from "fs/promises";
10
11
  import type { PaneRuntimeState } from "../../core/state/app/state";
11
12
  import { CHART_COMPOSER_PANE_ID, type AppConfig } from "../../types/config";
12
- import type { OptionsChain, PricePoint, TickerFinancials } from "../../types/financials";
13
+ import type { OptionsChain, PricePoint, Quote, TickerFinancials } from "../../types/financials";
13
14
  import type { TickerRecord } from "../../types/ticker";
14
15
  import { slugifyName } from "../../utils/slugify";
15
16
  import {
@@ -18,7 +19,7 @@ import {
18
19
  type HttpProxyRequestEnvelope,
19
20
  type HttpProxyResponseEnvelope,
20
21
  } from "../../utils/http-proxy-response";
21
- import { getTheme, getThemeIds } from "../../theme/themes";
22
+ import { requireThemeId } from "../commands/themes";
22
23
  import { isRecord } from "../../utils/guards";
23
24
 
24
25
  const DEFAULT_SHOT_DEVICE_SCALE_FACTOR = 2;
@@ -74,6 +75,7 @@ import type { ResolvedSeries } from "../../time-series/types";
74
75
  import { getQuoteMonitorPaneSettings } from "../../plugins/builtin/ticker-detail/settings";
75
76
  import { accessGateSentence } from "./access-gate";
76
77
  import { findCollection } from "../../plugins/builtin/portfolio-list/cli/render";
78
+ import { peekCachedBrokerAccounts } from "../../plugins/builtin/portfolio-list/cached-account";
77
79
  import {
78
80
  paneEvidenceMismatches,
79
81
  paneScreenshotEvidenceHook,
@@ -85,6 +87,7 @@ import {
85
87
  clipPriceHistoryToRange,
86
88
  createFallbackTicker,
87
89
  fetchTickerFinancials,
90
+ loadBrokerMarkedHolding,
88
91
  isFinancialAnalysisFunction,
89
92
  readsDailyReturns,
90
93
  withShotDailyReturns,
@@ -92,6 +95,9 @@ import {
92
95
  withShotPriceHistory,
93
96
  withShotSeasonalityHistory,
94
97
  } from "./data";
98
+ import { renderedReportFreshness, renderedReportNotices, renderedReportObservations } from "./report-notices";
99
+ import { deriveRenderedFreshness, statusLineVariants, type ReportFreshness } from "./freshness";
100
+ import { quotesFreshness } from "../freshness";
95
101
  import {
96
102
  financialRatioRenderMismatches,
97
103
  financialRatioShotEvidence,
@@ -425,6 +431,10 @@ export interface PaneScreenshotResult {
425
431
  usable: boolean;
426
432
  unusableReason: string | null;
427
433
  dataEvidence: PaneScreenshotDataEvidence | null;
434
+ /** What the pane says its view leaves out, such as OMON's "21 of 145 strikes". */
435
+ notices?: string[];
436
+ /** How current the captured data is, as the capture's status line says it; absent with `--no-status`. */
437
+ freshness?: ReportFreshness;
428
438
  outputPath: string;
429
439
  render: DesktopPaneShotRenderResult & {
430
440
  expectedText: string[];
@@ -492,7 +502,7 @@ export async function buildDesktopShotPayload(
492
502
  };
493
503
  const config = stripDesktopShotCredentials<AppConfig>({
494
504
  ...context.config,
495
- ...(theme ? { theme: resolveShotTheme(theme) } : {}),
505
+ ...(theme ? { theme: requireThemeId(theme) } : {}),
496
506
  layout,
497
507
  layouts: [{
498
508
  name: "CLI Shot",
@@ -524,7 +534,7 @@ export async function buildDesktopShotPayload(
524
534
  shotInstance = { ...shotInstance, settings: { ...shotInstance.settings, ...prepared.settings } };
525
535
  for (const [symbol, data] of prepared.financials ?? []) {
526
536
  financials.push([symbol, data]);
527
- tickers.push(createFallbackTicker(symbol, data, context));
537
+ tickers.push(await createFallbackTicker(symbol, data, context));
528
538
  }
529
539
  } else if (resolved.pane.id === "analytics") {
530
540
  const loaded = await loadResolvedHeadlessPaneModel(resolved, context, rawArg);
@@ -550,13 +560,23 @@ export async function buildDesktopShotPayload(
550
560
  if (!target.instrument) financials.push([label, data]);
551
561
  const { symbol } = parsePublicTickerKey(key);
552
562
  const ticker = await context.store.loadTicker(key) ?? await context.store.loadTicker(symbol);
553
- tickers.push(ticker ?? createFallbackTicker(key, data, context));
563
+ tickers.push(ticker ?? await createFallbackTicker(key, data, context));
554
564
  }
555
565
  intradayHistories.push(...chartModel.snapshot.intradayHistories.map((history) => ({
556
566
  ...history, start: history.start?.toISOString() ?? null, end: history.end?.toISOString() ?? null,
557
567
  })));
558
568
  } else for (const symbol of await collectShotSymbolsWithCollections(resolved, context, rawArg)) {
559
- const entry = await fetchTickerFinancials(context, symbol);
569
+ let entry: Awaited<ReturnType<typeof fetchTickerFinancials>>;
570
+ try {
571
+ entry = await fetchTickerFinancials(context, symbol);
572
+ } catch (error) {
573
+ // The pane values a holding no quote covers, such as an option contract,
574
+ // at the broker's mark. It has no financials to capture.
575
+ const holding = COLLECTION_PANE_IDS.has(resolved.pane.id) ? await loadBrokerMarkedHolding(context, symbol) : null;
576
+ if (!holding) throw error;
577
+ tickers.push(holding);
578
+ continue;
579
+ }
560
580
  const requestedRange = shotPriceHistoryRange(resolved);
561
581
  let data = entry.financials;
562
582
  const exchange = entry.instrument.exchange
@@ -564,7 +584,9 @@ export async function buildDesktopShotPayload(
564
584
  ?? data.quote?.listingExchangeName
565
585
  ?? data.quote?.exchangeName
566
586
  ?? "";
567
- const fiveYearsDaily = resolved.pane.id === "realized-vol" || resolved.pane.id === "iv-history" || resolved.pane.id === "macro-day";
587
+ const fiveYearsDaily = resolved.pane.id === "realized-vol" || resolved.pane.id === "iv-history" || resolved.pane.id === "macro-day"
588
+ // KELLY's History tab reads monthly returns off five years of daily closes.
589
+ || resolved.pane.id === "kelly-sizer";
568
590
  if (fiveYearsDaily || resolved.pane.id === "iv-screen" || resolved.pane.id === "short-watch"
569
591
  || resolved.pane.id === "backtest" || resolved.pane.id === OPTIONS_PANE_ID) {
570
592
  // Generic 5Y snapshots can contain weekly bars. The snapshot provider
@@ -599,15 +621,19 @@ export async function buildDesktopShotPayload(
599
621
  // letting the pane fetch them.
600
622
  data = await withShotPriceHistory(context, symbol, entry.tickerFile, data);
601
623
  }
602
- tickers.push(entry.tickerFile ?? createFallbackTicker(symbol, data, context));
624
+ tickers.push(entry.tickerFile ?? await createFallbackTicker(symbol, data, context));
603
625
  financials.push([symbol, data]);
604
626
  if (resolved.pane.id === "time-sales") {
605
627
  tapeSnapshots.push([entry.instrument.symbol, exchange, await fetchTape(entry.instrument.symbol, exchange)]);
606
628
  }
607
629
  if (includeOptionsChains && context.dataProvider.getOptionsChain) {
630
+ // A future with no chain of its own is the pane's to explain (the listed alternative), not a failed shot.
608
631
  const chain = await context.dataProvider.getOptionsChain(entry.instrument.symbol, exchange, undefined,
609
- context.refresh ? { cacheMode: "refresh" } : undefined);
610
- optionsChains.push([symbol, chain]);
632
+ context.refresh ? { cacheMode: "refresh" } : undefined).catch((error: unknown) => {
633
+ if (isOptionsUnavailableError(error)) return null;
634
+ throw error;
635
+ });
636
+ if (chain) optionsChains.push([symbol, chain]);
611
637
  }
612
638
  }
613
639
  layout.instances[0] = shotInstance;
@@ -625,6 +651,9 @@ export async function buildDesktopShotPayload(
625
651
  deviceScaleFactor,
626
652
  watermark,
627
653
  tickers,
654
+ ...(COLLECTION_PANE_IDS.has(resolved.pane.id)
655
+ ? { brokerAccounts: peekCachedBrokerAccounts(context.config, context.persistence?.resources) }
656
+ : {}),
628
657
  financials,
629
658
  ...(instrumentFinancials?.length ? { instrumentFinancials } : {}),
630
659
  ...(historyVariants?.length ? { historyVariants } : {}),
@@ -662,17 +691,6 @@ async function collectShotSymbolsWithCollections(
662
691
  return [...new Set([...symbols, ...members])];
663
692
  }
664
693
 
665
- function resolveShotTheme(requested: string): string {
666
- const normalized = requested.trim().toLowerCase().replace(/[\s_]+/g, "-");
667
- const ids = getThemeIds();
668
- const match = ids.find((id) => id.toLowerCase() === normalized)
669
- ?? ids.find((id) => getTheme(id).name.toLowerCase().replace(/[\s_]+/g, "-") === normalized);
670
- if (!match) {
671
- throw new Error(`Unknown theme "${requested}". Available themes: ${ids.join(", ")}`);
672
- }
673
- return match;
674
- }
675
-
676
694
  function shotPriceHistoryRange(resolved: ResolvedPaneFunction): TimeRange | null {
677
695
  // Captured history is authoritative, and the generic 5Y capture is weekly.
678
696
  if (resolved.pane.id === "quote-monitor") return getQuoteMonitorPaneSettings(resolved.instance.settings).chartPeriod;
@@ -687,6 +705,60 @@ function shotPriceHistoryRange(resolved: ResolvedPaneFunction): TimeRange | null
687
705
  }
688
706
  }
689
707
 
708
+ /** The bridge, keeping every quote it serves the page: what a pane that loads its own quotes (WEI) shows. */
709
+ function recordBridgedQuotes(bridge: DesktopPaneShotBridge): { bridge: DesktopPaneShotBridge; quotes: Quote[] } {
710
+ const quotes: Quote[] = [];
711
+ const keep = (value: unknown) => {
712
+ if (isRecord(value) && typeof value.symbol === "string" && typeof value.price === "number") quotes.push(value as unknown as Quote);
713
+ };
714
+ return {
715
+ quotes,
716
+ bridge: {
717
+ ...bridge,
718
+ async marketData(operation, args) {
719
+ const result = await bridge.marketData(operation, args);
720
+ if (operation === "getQuote") keep(result);
721
+ if (operation === "getQuotesBatch" && Array.isArray(result)) {
722
+ for (const entry of result) keep(isRecord(entry) ? entry.quote : null);
723
+ }
724
+ return result;
725
+ },
726
+ },
727
+ };
728
+ }
729
+
730
+ /**
731
+ * How current a capture's data is. A pane that says what its data is (its
732
+ * declared status, or a feed it publishes, such as OMON's chain or the news
733
+ * wire's delay) is taken at its word; otherwise the quotes it shows date it,
734
+ * with their delay and where their markets stand; otherwise what the
735
+ * rendered view carries, which may be nothing.
736
+ */
737
+ function shotFreshness(
738
+ resolved: Pick<ResolvedPaneFunction, "pane">,
739
+ payload: Pick<DesktopPaneShotPayload, "financials" | "instrumentFinancials">,
740
+ render: Pick<DesktopPaneShotRenderResult, "semanticUi" | "footerText" | "rows">,
741
+ bridgedQuotes: readonly Quote[],
742
+ now = Date.now(),
743
+ ): ReportFreshness {
744
+ const declared = { ...resolved.pane.reportFreshness, ...renderedReportFreshness(render.semanticUi ?? []) };
745
+ const quotes = [
746
+ ...payload.financials.map(([, financials]) => financials.quote),
747
+ ...(payload.instrumentFinancials ?? []).map(({ financials }) => financials.quote),
748
+ ...bridgedQuotes,
749
+ ];
750
+ // A pane that publishes the observations behind its figures (FXC's rates) dates itself.
751
+ const observed = renderedReportObservations(render.semanticUi ?? []);
752
+ const quoted = declared.status || observed.length > 0
753
+ ? undefined
754
+ : quotesFreshness(quotes, declared.source ? { source: declared.source } : undefined, now);
755
+ return quoted ?? deriveRenderedFreshness(declared, {
756
+ footerText: render.footerText ?? "",
757
+ cellTimes: render.rows.flatMap((row) => row.cells.flatMap((cell) => (cell.instant ? [cell.instant] : []))),
758
+ observed,
759
+ }, now);
760
+ }
761
+
690
762
  export async function renderDesktopShot({
691
763
  resolved,
692
764
  context,
@@ -697,6 +769,7 @@ export async function renderDesktopShot({
697
769
  theme,
698
770
  scale,
699
771
  watermark,
772
+ statusLine = false,
700
773
  options,
701
774
  captureImage = true,
702
775
  }: {
@@ -709,6 +782,8 @@ export async function renderDesktopShot({
709
782
  theme?: string | null;
710
783
  scale?: number;
711
784
  watermark?: string | null;
785
+ /** Draw the dated status line in the capture's footer. Reports and `--no-status` leave it out. */
786
+ statusLine?: boolean;
712
787
  options: Record<string, string | true>;
713
788
  captureImage?: boolean;
714
789
  }): Promise<PaneScreenshotResult> {
@@ -717,6 +792,7 @@ export async function renderDesktopShot({
717
792
  const previousSessionToken = apiClient.getSessionToken();
718
793
  let payload: DesktopPaneShotPayload;
719
794
  let render: DesktopPaneShotRenderResult;
795
+ let freshness: ReportFreshness | undefined;
720
796
  apiClient.setSessionToken(apiProxy.sessionToken);
721
797
  try {
722
798
  payload = await buildDesktopShotPayload(
@@ -730,16 +806,24 @@ export async function renderDesktopShot({
730
806
  scale ?? 1,
731
807
  watermark ?? null,
732
808
  );
809
+ if (statusLine && captureImage) payload.statusLine = true;
810
+ const recorded = recordBridgedQuotes(createDesktopShotBridge(context));
811
+ const shotPayload = payload;
733
812
  render = await renderDesktopPaneScreenshot(payload, outputPath, apiProxy, {
734
813
  captureImage,
735
- bridge: createDesktopShotBridge(context),
814
+ bridge: recorded.bridge,
815
+ statusLine: (rendered) => {
816
+ freshness = shotFreshness(resolved, shotPayload, rendered, recorded.quotes);
817
+ return statusLineVariants(freshness);
818
+ },
736
819
  });
737
820
  } finally {
738
821
  apiClient.setSessionToken(previousSessionToken);
739
822
  }
740
823
  const renderedInstance = payload.config.layout.instances.find(({ instanceId }) => instanceId === payload.paneId);
741
824
  if (renderedInstance) resolved = { ...resolved, instance: renderedInstance };
742
- return assessPaneScreenshot(resolved, payload, render, rawArg, outputPath);
825
+ const assessed = assessPaneScreenshot(resolved, payload, render, rawArg, outputPath);
826
+ return freshness ? { ...assessed, freshness } : assessed;
743
827
  }
744
828
 
745
829
  /** What a rendered capture shows, and whether it is fit to use. */
@@ -803,6 +887,7 @@ export function assessPaneScreenshot(
803
887
  const unusableReason = usable
804
888
  ? null
805
889
  : shotUnusableReasonFor(resolved, payload, render, unavailableSymbols, semanticMismatch);
890
+ const { notices } = renderedReportNotices(render.semanticUi ?? []);
806
891
  return {
807
892
  kind: "pane-screenshot",
808
893
  target: resolved.token,
@@ -823,6 +908,7 @@ export function assessPaneScreenshot(
823
908
  usable,
824
909
  unusableReason,
825
910
  dataEvidence,
911
+ ...(notices.length > 0 ? { notices } : {}),
826
912
  outputPath,
827
913
  render: {
828
914
  ...stripDesktopShotCredentials(render),
@@ -27,6 +27,8 @@ interface RegisteredCliCommand {
27
27
  command: CliCommandDef;
28
28
  ownerId: string;
29
29
  source: "core" | "plugin";
30
+ /** Core or a built-in plugin: its declared options are the only ones it takes. External plugins are not held to theirs. */
31
+ builtin: boolean;
30
32
  }
31
33
 
32
34
  export interface CliCommandRegistry {
@@ -80,6 +82,7 @@ export function buildCliCommandRegistry({
80
82
  command: CliCommandDef,
81
83
  ownerId: string,
82
84
  source: "core" | "plugin",
85
+ builtin: boolean,
83
86
  ) => {
84
87
  const tokens = new Set([
85
88
  validateCommandToken(command.name, ownerId, source),
@@ -95,7 +98,7 @@ export function buildCliCommandRegistry({
95
98
  );
96
99
  }
97
100
 
98
- const entry: RegisteredCliCommand = { command, ownerId, source };
101
+ const entry: RegisteredCliCommand = { command, ownerId, source, builtin };
99
102
  allCommands.push(entry);
100
103
  for (const token of tokens) {
101
104
  allTokens.set(token, entry);
@@ -103,7 +106,7 @@ export function buildCliCommandRegistry({
103
106
  };
104
107
 
105
108
  for (const command of coreCommands) {
106
- registerCommand(command, "core", "core");
109
+ registerCommand(command, "core", "core", true);
107
110
  }
108
111
 
109
112
  const loadablePlugins: GloomPlugin[] = [];
@@ -117,7 +120,7 @@ export function buildCliCommandRegistry({
117
120
  }
118
121
  loadablePlugins.push(entry.plugin);
119
122
  for (const command of entry.plugin.cliCommands ?? []) {
120
- registerCommand(command, entry.plugin.id, "plugin");
123
+ registerCommand(command, entry.plugin.id, "plugin", entry.source === "builtin");
121
124
  }
122
125
  }
123
126
 
@@ -146,6 +149,7 @@ export function createCliCommandContext(
146
149
  ownerId: string,
147
150
  registryOrPlugins: Pick<CliCommandRegistry, "plugins" | "externalPlugins"> | GloomPlugin[],
148
151
  cliOptions: CliGlobalOptions = DEFAULT_CLI_OPTIONS,
152
+ args: readonly string[] = [],
149
153
  ): CliCommandContext {
150
154
  const registry = Array.isArray(registryOrPlugins)
151
155
  ? { plugins: registryOrPlugins, externalPlugins: [] }
@@ -166,7 +170,7 @@ export function createCliCommandContext(
166
170
  renderStats,
167
171
  renderTable,
168
172
  },
169
- printResult: (result, options) => printCliResult(result, cliOptions, options),
173
+ printResult: (result, options) => printCliResult(result, cliOptions, options, args),
170
174
  log: debugLog.createLogger(ownerId === "core" ? "cli" : ownerId),
171
175
  };
172
176
  }