gloomberb 0.18.3 → 0.18.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 (886) hide show
  1. package/README.md +8 -8
  2. package/README.zh-CN.md +11 -11
  3. package/bin/{gloomberb → gloom} +3 -1
  4. package/package.json +6 -2
  5. package/src/account/checkout-handoff.tsx +225 -0
  6. package/src/account/device-signin-dialog.tsx +2 -2
  7. package/src/account/device-signin.ts +2 -2
  8. package/src/account/upgrade-dialog.tsx +1 -1
  9. package/src/api-client/askg.ts +2 -2
  10. package/src/api-client/auth.ts +2 -2
  11. package/src/api-client/central-bank-rates.ts +6 -0
  12. package/src/api-client/collections.ts +5 -1
  13. package/src/api-client/cot.ts +2 -0
  14. package/src/api-client/crypto-etf-flows.ts +37 -0
  15. package/src/api-client/crypto-markets.ts +60 -0
  16. package/src/api-client/data.ts +84 -5
  17. package/src/api-client/doe.ts +15 -0
  18. package/src/api-client/equity-screener.ts +28 -0
  19. package/src/api-client/exchange-announcements.ts +38 -0
  20. package/src/api-client/fund-facts.ts +39 -0
  21. package/src/api-client/futures-curve.ts +9 -1
  22. package/src/api-client/hiring.ts +301 -0
  23. package/src/api-client/index.ts +22 -5
  24. package/src/api-client/market-discovery.ts +14 -0
  25. package/src/api-client/members.ts +6 -0
  26. package/src/api-client/mna.ts +6 -0
  27. package/src/api-client/paths.ts +18 -1
  28. package/src/api-client/request.ts +21 -4
  29. package/src/api-client/short-side-publications.ts +37 -0
  30. package/src/api-client/socket.ts +64 -4
  31. package/src/api-client/swap-curve.ts +35 -0
  32. package/src/api-client/themes.ts +7 -1
  33. package/src/api-client/types.ts +90 -2
  34. package/src/app/pane-runtime/plugin-bindings.ts +9 -2
  35. package/src/app/runtime/desktop-deeplink.ts +5 -5
  36. package/src/app/runtime/plugin-bindings.ts +2 -2
  37. package/src/app/runtime/startup.ts +13 -0
  38. package/src/app/star-prompt/status-line.tsx +2 -2
  39. package/src/architecture/core-builtin-allowlist.json +5 -2
  40. package/src/architecture/ui-literals-allowlist.json +3 -3
  41. package/src/architecture/ui-tokens-allowlist.json +1 -1
  42. package/src/brokers/broker-portfolio-sync.ts +37 -0
  43. package/src/brokers/directory.ts +11 -0
  44. package/src/brokers/logos.ts +3 -1
  45. package/src/brokers/signed-in/adapter.ts +304 -26
  46. package/src/brokers/signed-in/client.ts +14 -2
  47. package/src/brokers/signed-in/connect.ts +10 -2
  48. package/src/brokers/sync-broker-instance.ts +9 -1
  49. package/src/capabilities/chart-series.ts +22 -6
  50. package/src/cli/bank-section.ts +1 -1
  51. package/src/cli/base-converter.ts +23 -14
  52. package/src/cli/central-bank-events.ts +1 -1
  53. package/src/cli/command-options.ts +59 -4
  54. package/src/cli/commands/api.ts +9 -6
  55. package/src/cli/commands/broker.ts +2 -2
  56. package/src/cli/commands/command-utils.ts +2 -2
  57. package/src/cli/commands/crypto-hints.ts +7 -20
  58. package/src/cli/commands/fred-series.ts +4 -2
  59. package/src/cli/commands/keybindings.ts +2 -2
  60. package/src/cli/commands/market.ts +1117 -264
  61. package/src/cli/commands/news-hints.ts +2 -2
  62. package/src/cli/commands/news-search.ts +59 -6
  63. package/src/cli/commands/options-leaps.ts +41 -26
  64. package/src/cli/commands/overview.ts +121 -48
  65. package/src/cli/commands/plugins.ts +9 -9
  66. package/src/cli/commands/remote.ts +13 -10
  67. package/src/cli/commands/search.ts +64 -44
  68. package/src/cli/commands/system.ts +27 -19
  69. package/src/cli/commands/themes.ts +1 -1
  70. package/src/cli/commands/ticker.ts +192 -47
  71. package/src/cli/context.ts +3 -2
  72. package/src/cli/desktop-pane-shot-view.ts +2 -2
  73. package/src/cli/desktop-pane-shot.ts +1 -1
  74. package/src/cli/earnings-calendar.ts +4 -4
  75. package/src/cli/entry.ts +18 -1
  76. package/src/cli/errors.ts +20 -2
  77. package/src/cli/exit-codes.ts +1 -1
  78. package/src/cli/export-source.ts +10 -4
  79. package/src/cli/freshness.ts +2 -8
  80. package/src/cli/fx-forward.ts +130 -0
  81. package/src/cli/fx-pair.ts +10 -9
  82. package/src/cli/glossary.ts +64 -20
  83. package/src/cli/help.ts +19 -13
  84. package/src/cli/history-export.ts +126 -0
  85. package/src/cli/history-rows.ts +196 -43
  86. package/src/cli/index-roots.ts +5 -45
  87. package/src/cli/index.ts +24 -18
  88. package/src/cli/known-gaps.ts +118 -25
  89. package/src/cli/listing-arg.ts +300 -41
  90. package/src/cli/name-entries.ts +30 -18
  91. package/src/cli/native-smoke.ts +2 -0
  92. package/src/cli/not-a-ticker.ts +19 -9
  93. package/src/cli/opentui-libc.ts +5 -0
  94. package/src/cli/options.ts +12 -0
  95. package/src/cli/pane-functions/capabilities.ts +75 -20
  96. package/src/cli/pane-functions/catalog.ts +24 -23
  97. package/src/cli/pane-functions/discovery.ts +1 -1
  98. package/src/cli/pane-functions/dom.ts +10 -7
  99. package/src/cli/pane-functions/financial-ratio-shot.ts +2 -2
  100. package/src/cli/pane-functions/freshness.ts +174 -23
  101. package/src/cli/pane-functions/function-help.ts +66 -27
  102. package/src/cli/pane-functions/headless.ts +24 -11
  103. package/src/cli/pane-functions/index.ts +18 -16
  104. package/src/cli/pane-functions/options.ts +22 -2
  105. package/src/cli/pane-functions/report-notices.ts +12 -4
  106. package/src/cli/pane-functions/report.ts +5 -5
  107. package/src/cli/pane-functions/resolver.ts +47 -10
  108. package/src/cli/pane-functions/screenshot-assessment.ts +322 -0
  109. package/src/cli/pane-functions/screenshot-bridge.ts +152 -0
  110. package/src/cli/pane-functions/screenshot-chart-evidence.ts +396 -0
  111. package/src/cli/pane-functions/screenshot-data-evidence.ts +383 -0
  112. package/src/cli/pane-functions/screenshot-evidence.ts +1 -1
  113. package/src/cli/pane-functions/screenshot-payload.ts +453 -0
  114. package/src/cli/pane-functions/screenshot-render.ts +316 -0
  115. package/src/cli/pane-functions/screenshot-types.ts +162 -0
  116. package/src/cli/pane-functions/shot-options.ts +8 -3
  117. package/src/cli/peso-dollar-rates.ts +79 -0
  118. package/src/cli/quote-answer.ts +38 -3
  119. package/src/cli/report-tables.ts +61 -16
  120. package/src/cli/restore-plugins.ts +29 -14
  121. package/src/cli/result.ts +111 -22
  122. package/src/cli/series-search.ts +5 -5
  123. package/src/cli/statement-filings.ts +19 -0
  124. package/src/cli/suffixed-listing-rows.ts +49 -0
  125. package/src/cli/symbol-args.ts +50 -15
  126. package/src/cli/symbol-cells.ts +120 -0
  127. package/src/cli/symbol-list.ts +198 -68
  128. package/src/cli/symbol-rows.ts +131 -25
  129. package/src/cli/ticker-resolution.ts +108 -11
  130. package/src/cli/treasury-yields.ts +5 -5
  131. package/src/cli/types.ts +2 -0
  132. package/src/cli/uncovered-instrument.ts +3 -3
  133. package/src/cli/unknown-command.ts +6 -6
  134. package/src/components/chart/composite/chart-layout.ts +131 -0
  135. package/src/components/chart/composite/composite-chart.tsx +373 -16
  136. package/src/components/chart/composite/interactions.ts +7 -2
  137. package/src/components/chart/composite/legend.tsx +75 -3
  138. package/src/components/chart/composite/levels.ts +5 -0
  139. package/src/components/chart/composite/panel-gestures.ts +41 -0
  140. package/src/components/chart/composite/panel-labels.ts +2 -1
  141. package/src/components/chart/composite/panel-surface.tsx +305 -11
  142. package/src/components/chart/composite/price-axis-labels.tsx +27 -3
  143. package/src/components/chart/composite/rasterizer.ts +44 -19
  144. package/src/components/chart/composite/scene.ts +16 -4
  145. package/src/components/chart/composite/text-renderer.ts +48 -21
  146. package/src/components/chart/composite/toolbar.tsx +52 -5
  147. package/src/components/chart/composite/types.ts +13 -0
  148. package/src/components/chart/composite/use-composite-chart-keyboard.ts +120 -13
  149. package/src/components/chart/composite/use-composite-value-scales.ts +44 -0
  150. package/src/components/chart/composite/use-composite-viewport.ts +12 -3
  151. package/src/components/chart/composite/value-scale.ts +149 -0
  152. package/src/components/chart/composite/volume-profile-paint.ts +6 -3
  153. package/src/components/chart/core/pointer.ts +2 -0
  154. package/src/components/chart-table/index.ts +2 -0
  155. package/src/components/chart-table/read.tsx +74 -0
  156. package/src/components/command-bar/commands/collection-list.ts +41 -19
  157. package/src/components/command-bar/commands/collection.ts +9 -3
  158. package/src/components/command-bar/commands/direct/index.ts +1 -1
  159. package/src/components/command-bar/commands/direct/runtime.ts +3 -2
  160. package/src/components/command-bar/pane-templates/items.ts +59 -6
  161. package/src/components/command-bar/pane-templates/workflow.ts +10 -1
  162. package/src/components/command-bar/routes/root/plugin-install.ts +1 -1
  163. package/src/components/command-bar/routes/root/provider-search.ts +42 -11
  164. package/src/components/command-bar/routes/root/results.ts +18 -4
  165. package/src/components/command-bar/routes/root/runtime.ts +15 -3
  166. package/src/components/command-bar/routes/root/search-providers.ts +25 -2
  167. package/src/components/command-bar/routes/root/selection.ts +6 -1
  168. package/src/components/command-bar/routes/root/shortcut-feedback.ts +4 -1
  169. package/src/components/command-bar/routes/root/shortcuts.ts +30 -3
  170. package/src/components/command-bar/routes/ticker-search/results.ts +73 -4
  171. package/src/components/command-bar/selection-runtime.ts +50 -10
  172. package/src/components/command-bar/surface/index.tsx +24 -2
  173. package/src/components/command-bar/view-model.ts +7 -0
  174. package/src/components/command-bar/workflow/broker.ts +2 -2
  175. package/src/components/command-bar/workflow/collection-actions.ts +46 -7
  176. package/src/components/command-bar/workflow/collection-ticker.ts +32 -4
  177. package/src/components/command-bar/workflow/fields.ts +8 -2
  178. package/src/components/command-bar/workflow/ops.ts +18 -4
  179. package/src/components/command-bar/workflow/portfolio-position.ts +53 -4
  180. package/src/components/command-bar/workflow/submit.ts +3 -2
  181. package/src/components/command-bar/workflow/tickers.ts +5 -1
  182. package/src/components/company-logo.tsx +39 -0
  183. package/src/components/data-table/sections.ts +4 -2
  184. package/src/components/form-modal/confirm.tsx +2 -1
  185. package/src/components/form-modal/request.ts +5 -0
  186. package/src/components/form-modal/routes.ts +4 -1
  187. package/src/components/index.ts +12 -6
  188. package/src/components/layout/header.tsx +7 -6
  189. package/src/components/layout/market-summary.ts +9 -6
  190. package/src/components/layout/pane/capture-status.ts +1 -1
  191. package/src/components/layout/pane/footer/model.ts +11 -5
  192. package/src/components/layout/shell/chrome.ts +19 -6
  193. package/src/components/layout/shell/index.tsx +2 -1
  194. package/src/components/layout/shell/pane/layers.tsx +19 -1
  195. package/src/components/layout/status-bar.tsx +2 -2
  196. package/src/components/market-board/index.tsx +11 -3
  197. package/src/components/onboarding/onboarding-wizard.tsx +1 -0
  198. package/src/components/onboarding/portfolio-step/broker-setup-panel.tsx +2 -2
  199. package/src/components/onboarding/wizard-broker-sync.ts +4 -1
  200. package/src/components/pane-settings-dialog/desktop.tsx +20 -7
  201. package/src/components/pane-settings-dialog/tui.tsx +17 -9
  202. package/src/components/pane-settings-dialog/value.ts +8 -1
  203. package/src/components/pane-settings-dialog.tsx +44 -13
  204. package/src/components/sign-in-code-panel.tsx +27 -19
  205. package/src/components/ui/column-grid.tsx +48 -4
  206. package/src/components/ui/country-flag-art.tsx +180 -0
  207. package/src/components/ui/country-flag.tsx +118 -12
  208. package/src/components/ui/data-table/opentui/index.tsx +61 -2
  209. package/src/components/ui/data-table/opentui/model.ts +109 -2
  210. package/src/components/ui/data-table/types.ts +1 -1
  211. package/src/components/ui/display.tsx +5 -1
  212. package/src/components/ui/index.ts +3 -1
  213. package/src/components/ui/logo-mark.tsx +11 -2
  214. package/src/components/ui/query-bar.tsx +1 -1
  215. package/src/components/ui/row-notes.ts +79 -0
  216. package/src/core/state/app/layout.ts +4 -4
  217. package/src/data/cached-query.ts +8 -1
  218. package/src/data/config/chart-settings.ts +3 -3
  219. package/src/data/config/home.ts +10 -2
  220. package/src/data/config/layout.ts +4 -1
  221. package/src/data/config/store/node.ts +4 -0
  222. package/src/data/config/store/normalize.ts +13 -3
  223. package/src/data/config/store/portfolio-as-of-column.ts +2 -2
  224. package/src/data/json-storage.ts +2 -0
  225. package/src/data/saved-copies.ts +84 -0
  226. package/src/docs/snapshot.json +65 -32
  227. package/src/i18n/es.ts +29 -12
  228. package/src/i18n/ja.ts +29 -12
  229. package/src/i18n/ko.ts +29 -12
  230. package/src/i18n/zh-cn.ts +29 -12
  231. package/src/i18n/zh-tw.ts +29 -12
  232. package/src/layout/desks.ts +1 -1
  233. package/src/layout/launch-layout.ts +1 -1
  234. package/src/layout/pane-manager/floating-actions.ts +5 -3
  235. package/src/layout/pane-manager/floating.ts +43 -1
  236. package/src/layout/pane-manager/index.ts +2 -0
  237. package/src/layout/selected-ticker.ts +74 -0
  238. package/src/market-data/depositary-pair.ts +251 -0
  239. package/src/market-data/futures-board.ts +1 -1
  240. package/src/market-data/futures-contract.ts +124 -40
  241. package/src/market-data/fx-closes.ts +17 -2
  242. package/src/market-data/hooks.tsx +19 -11
  243. package/src/market-data/market/change-basis.ts +49 -7
  244. package/src/market-data/market/freshness.ts +34 -5
  245. package/src/market-data/market/period-return.ts +163 -0
  246. package/src/market-data/market/trading-sessions.ts +13 -0
  247. package/src/market-data/market/year-to-date.ts +8 -13
  248. package/src/market-data/performance.ts +20 -14
  249. package/src/market-data/perpetual-premium.ts +32 -0
  250. package/src/market-data/published-apac-sessions.ts +2 -1
  251. package/src/market-data/published-futures-sessions.ts +69 -0
  252. package/src/market-data/quotes/contributions.ts +5 -1
  253. package/src/market-data/quotes/freshness.ts +42 -0
  254. package/src/market-data/quotes/intraday-bar.ts +37 -0
  255. package/src/market-data/quotes/regular-session-valuation.ts +13 -8
  256. package/src/market-data/quotes/resolution.ts +4 -2
  257. package/src/market-data/tax-equivalent.ts +1 -1
  258. package/src/market-data/ticker-price-returns.ts +3 -1
  259. package/src/news/aggregator.ts +5 -1
  260. package/src/news/news-model.ts +4 -0
  261. package/src/news/types.ts +11 -0
  262. package/src/notifications/app-notifier.ts +1 -1
  263. package/src/plugins/auto-update.ts +2 -2
  264. package/src/plugins/builtin/account-management/index.tsx +1 -0
  265. package/src/plugins/builtin/account-management/pane.tsx +9 -8
  266. package/src/plugins/builtin/alerts/alert-engine.ts +29 -19
  267. package/src/plugins/builtin/alerts/calendar-events.ts +378 -0
  268. package/src/plugins/builtin/alerts/cli.ts +485 -76
  269. package/src/plugins/builtin/alerts/command.ts +5 -10
  270. package/src/plugins/builtin/alerts/event-rows.ts +9 -5
  271. package/src/plugins/builtin/alerts/events-pane.tsx +71 -56
  272. package/src/plugins/builtin/alerts/events.ts +107 -5
  273. package/src/plugins/builtin/alerts/fired-log.ts +78 -0
  274. package/src/plugins/builtin/alerts/format.ts +2 -1
  275. package/src/plugins/builtin/alerts/headless.ts +100 -39
  276. package/src/plugins/builtin/alerts/history-pane.tsx +105 -62
  277. package/src/plugins/builtin/alerts/history-rows.ts +89 -0
  278. package/src/plugins/builtin/alerts/index.tsx +45 -18
  279. package/src/plugins/builtin/alerts/iv-level.ts +365 -0
  280. package/src/plugins/builtin/alerts/levels.ts +3 -3
  281. package/src/plugins/builtin/alerts/pane.tsx +97 -29
  282. package/src/plugins/builtin/alerts/price.ts +35 -0
  283. package/src/plugins/builtin/alerts/quotes.ts +24 -0
  284. package/src/plugins/builtin/alerts/research-builder.ts +84 -11
  285. package/src/plugins/builtin/alerts/research-rules.ts +76 -3
  286. package/src/plugins/builtin/alerts/scheduled-check.ts +206 -32
  287. package/src/plugins/builtin/alerts/scheduled-sources.ts +26 -3
  288. package/src/plugins/builtin/alerts/scheduled.ts +188 -29
  289. package/src/plugins/builtin/alerts/storage.ts +13 -10
  290. package/src/plugins/builtin/alerts/targets.ts +12 -3
  291. package/src/plugins/builtin/analytics/index.tsx +8 -2
  292. package/src/plugins/builtin/analytics/metrics.ts +1 -1
  293. package/src/plugins/builtin/analytics/risk-book.ts +215 -0
  294. package/src/plugins/builtin/analytics/risk-client.ts +13 -6
  295. package/src/plugins/builtin/analytics/risk-headless.ts +55 -21
  296. package/src/plugins/builtin/analytics/risk-math.ts +6 -3
  297. package/src/plugins/builtin/analytics/risk-model.ts +297 -104
  298. package/src/plugins/builtin/analytics/risk-options.ts +17 -2
  299. package/src/plugins/builtin/analytics/risk-pane.tsx +97 -36
  300. package/src/plugins/builtin/attention/pane.tsx +6 -2
  301. package/src/plugins/builtin/awards/headless.ts +7 -3
  302. package/src/plugins/builtin/awards/model.ts +18 -0
  303. package/src/plugins/builtin/awards/pane.tsx +6 -3
  304. package/src/plugins/builtin/backtest/headless.ts +3 -3
  305. package/src/plugins/builtin/backtest/rules.ts +41 -5
  306. package/src/plugins/builtin/broker-manager/add-flow.tsx +12 -7
  307. package/src/plugins/builtin/broker-manager/detail.tsx +47 -19
  308. package/src/plugins/builtin/broker-manager/footer.ts +27 -11
  309. package/src/plugins/builtin/broker-manager/index.tsx +21 -12
  310. package/src/plugins/builtin/broker-manager/keyboard.ts +1 -1
  311. package/src/plugins/builtin/broker-manager/model.ts +12 -2
  312. package/src/plugins/builtin/broker-manager/pane-actions.tsx +183 -57
  313. package/src/plugins/builtin/broker-manager/table.ts +28 -12
  314. package/src/plugins/builtin/broker-trading/account-picker.tsx +2 -1
  315. package/src/plugins/builtin/broker-trading/chart-levels.ts +82 -13
  316. package/src/plugins/builtin/broker-trading/controller.ts +45 -13
  317. package/src/plugins/builtin/broker-trading/dock.tsx +22 -4
  318. package/src/plugins/builtin/broker-trading/headless.ts +2 -1
  319. package/src/plugins/builtin/broker-trading/index.tsx +7 -1
  320. package/src/plugins/builtin/broker-trading/linked-orders.ts +148 -0
  321. package/src/plugins/builtin/broker-trading/order-feed.ts +75 -7
  322. package/src/plugins/builtin/broker-trading/orders.tsx +109 -31
  323. package/src/plugins/builtin/broker-trading/overview-orders.tsx +9 -3
  324. package/src/plugins/builtin/broker-trading/pane-model.ts +30 -2
  325. package/src/plugins/builtin/broker-trading/pane.tsx +110 -23
  326. package/src/plugins/builtin/broker-trading/ticket-parts.tsx +36 -7
  327. package/src/plugins/builtin/broker-trading/ticket.tsx +112 -31
  328. package/src/plugins/builtin/buildout/cells.tsx +4 -0
  329. package/src/plugins/builtin/buildout/detail/index.tsx +5 -1
  330. package/src/plugins/builtin/buildout/detail/ui.tsx +7 -4
  331. package/src/plugins/builtin/buildout/pane/index.tsx +25 -12
  332. package/src/plugins/builtin/buildout/pane/status.tsx +0 -4
  333. package/src/plugins/builtin/builtin-plugin-meta.ts +1 -1
  334. package/src/plugins/builtin/catalysts/detail.tsx +3 -2
  335. package/src/plugins/builtin/catalysts/index.tsx +1 -1
  336. package/src/plugins/builtin/catalysts/model.ts +49 -4
  337. package/src/plugins/builtin/catalysts/pane.tsx +6 -8
  338. package/src/plugins/builtin/central-bank-rates/client.ts +5 -0
  339. package/src/plugins/builtin/central-bank-rates/headless.ts +36 -10
  340. package/src/plugins/builtin/central-bank-rates/model.ts +33 -8
  341. package/src/plugins/builtin/changelog/index.tsx +1 -0
  342. package/src/plugins/builtin/chart-composer/catalog-inventory.ts +1 -0
  343. package/src/plugins/builtin/chart-composer/chart-spec-edit.ts +2 -1
  344. package/src/plugins/builtin/chart-composer/chart-spec.ts +7 -0
  345. package/src/plugins/builtin/chart-composer/cli-options.ts +2 -5
  346. package/src/plugins/builtin/chart-composer/data-catalog-pane.tsx +2 -1
  347. package/src/plugins/builtin/chart-composer/editor/controller.ts +2 -0
  348. package/src/plugins/builtin/chart-composer/editor.tsx +4 -1
  349. package/src/plugins/builtin/chart-composer/headless-schema.ts +28 -26
  350. package/src/plugins/builtin/chart-composer/headless.ts +253 -35
  351. package/src/plugins/builtin/chart-composer/index.tsx +12 -2
  352. package/src/plugins/builtin/chart-composer/leverage-overlay.ts +142 -0
  353. package/src/plugins/builtin/chart-composer/pane.tsx +127 -28
  354. package/src/plugins/builtin/chart-composer/series-catalog.ts +1 -0
  355. package/src/plugins/builtin/chart-composer/series-expression.ts +65 -6
  356. package/src/plugins/builtin/chart-composer/session-history.ts +15 -21
  357. package/src/plugins/builtin/chart-composer/session-range.ts +4 -2
  358. package/src/plugins/builtin/chart-composer/settings.ts +31 -19
  359. package/src/plugins/builtin/chart-composer/use-series-catalog.ts +5 -6
  360. package/src/plugins/builtin/chart-composer/viewport-labels.ts +18 -8
  361. package/src/plugins/builtin/chat/attachments/model.ts +3 -1
  362. package/src/plugins/builtin/chat/content/index.tsx +1 -1
  363. package/src/plugins/builtin/chat/pane-links/open.ts +1 -1
  364. package/src/plugins/builtin/chat/people.ts +1 -1
  365. package/src/plugins/builtin/clinical-trials/client.ts +5 -2
  366. package/src/plugins/builtin/clinical-trials/model.ts +13 -4
  367. package/src/plugins/builtin/clinical-trials/pane.tsx +32 -12
  368. package/src/plugins/builtin/clinical-trials/ticker-sponsor.ts +17 -0
  369. package/src/plugins/builtin/cloud/askg/controller.ts +1 -1
  370. package/src/plugins/builtin/cloud/askg/lock-note.ts +1 -1
  371. package/src/plugins/builtin/cloud/askg/tool-display.ts +1 -1
  372. package/src/plugins/builtin/cloud/auth-commands.ts +3 -3
  373. package/src/plugins/builtin/cloud/team/pane-sections.tsx +105 -47
  374. package/src/plugins/builtin/cloud/team/pane-ui.tsx +42 -4
  375. package/src/plugins/builtin/cloud/team/pane.tsx +204 -64
  376. package/src/plugins/builtin/cloud/thesis/store.ts +45 -22
  377. package/src/plugins/builtin/cloud-tweets/registration.ts +1 -0
  378. package/src/plugins/builtin/commodities-energy/index.tsx +29 -2
  379. package/src/plugins/builtin/commodities-energy/view-state.ts +2 -0
  380. package/src/plugins/builtin/commodity-balances/pane.tsx +11 -4
  381. package/src/plugins/builtin/company-attention/app-rank.tsx +7 -5
  382. package/src/plugins/builtin/company-attention/building-model.ts +222 -0
  383. package/src/plugins/builtin/company-attention/building.tsx +172 -0
  384. package/src/plugins/builtin/company-attention/client.ts +117 -1
  385. package/src/plugins/builtin/company-attention/evidence.ts +16 -3
  386. package/src/plugins/builtin/company-attention/headless.ts +101 -5
  387. package/src/plugins/builtin/company-attention/index.tsx +6 -3
  388. package/src/plugins/builtin/company-attention/model.ts +33 -7
  389. package/src/plugins/builtin/company-attention/moves-model.ts +253 -0
  390. package/src/plugins/builtin/company-attention/moves.tsx +159 -0
  391. package/src/plugins/builtin/company-attention/pane.tsx +79 -23
  392. package/src/plugins/builtin/company-attention/signals-model.ts +229 -0
  393. package/src/plugins/builtin/company-attention/signals.tsx +160 -0
  394. package/src/plugins/builtin/company-kpis/headless.ts +3 -2
  395. package/src/plugins/builtin/company-kpis/model.ts +2 -2
  396. package/src/plugins/builtin/company-kpis/pane.tsx +1 -1
  397. package/src/plugins/builtin/composite-plugins.ts +2 -1
  398. package/src/plugins/builtin/congress-trades/headless.ts +1 -1
  399. package/src/plugins/builtin/connections/index.ts +1 -0
  400. package/src/plugins/builtin/correlation/headless-schema.ts +3 -2
  401. package/src/plugins/builtin/correlation/headless.ts +5 -3
  402. package/src/plugins/builtin/cot/headless.ts +28 -6
  403. package/src/plugins/builtin/cot/model.ts +12 -0
  404. package/src/plugins/builtin/cot/pane.tsx +3 -2
  405. package/src/plugins/builtin/cpi/headless.ts +5 -1
  406. package/src/plugins/builtin/cpi/pane.tsx +11 -9
  407. package/src/plugins/builtin/credit-boards/model.ts +2 -0
  408. package/src/plugins/builtin/credit-documents/headless.ts +1 -1
  409. package/src/plugins/builtin/crypto-board/client.ts +86 -0
  410. package/src/plugins/builtin/crypto-board/defi-view.tsx +218 -0
  411. package/src/plugins/builtin/crypto-board/defi.ts +239 -0
  412. package/src/plugins/builtin/crypto-board/headless.ts +117 -6
  413. package/src/plugins/builtin/crypto-board/index.tsx +8 -3
  414. package/src/plugins/builtin/crypto-board/model.ts +40 -8
  415. package/src/plugins/builtin/crypto-board/pane.tsx +55 -21
  416. package/src/plugins/builtin/crypto-board/series.ts +19 -1
  417. package/src/plugins/builtin/crypto-etf-flows/client.ts +60 -0
  418. package/src/plugins/builtin/crypto-etf-flows/headless.ts +132 -0
  419. package/src/plugins/builtin/crypto-etf-flows/index.tsx +44 -0
  420. package/src/plugins/builtin/crypto-etf-flows/model.ts +121 -0
  421. package/src/plugins/builtin/crypto-etf-flows/pane.tsx +193 -0
  422. package/src/plugins/builtin/debug/index.tsx +1 -0
  423. package/src/plugins/builtin/dividend-yield/index.tsx +1 -1
  424. package/src/plugins/builtin/docs/index.tsx +1 -1
  425. package/src/plugins/builtin/docs/pane.tsx +2 -2
  426. package/src/plugins/builtin/docs/targets.ts +1 -1
  427. package/src/plugins/builtin/doe/client.ts +5 -1
  428. package/src/plugins/builtin/doe/headless.ts +12 -6
  429. package/src/plugins/builtin/doe/model.ts +43 -6
  430. package/src/plugins/builtin/doe/pane.tsx +18 -11
  431. package/src/plugins/builtin/earnings/board-model.ts +13 -6
  432. package/src/plugins/builtin/earnings/board-table.ts +4 -1
  433. package/src/plugins/builtin/earnings/board.tsx +253 -50
  434. package/src/plugins/builtin/earnings/calendar-model.ts +188 -0
  435. package/src/plugins/builtin/earnings/calendar.tsx +338 -0
  436. package/src/plugins/builtin/earnings/client.ts +4 -3
  437. package/src/plugins/builtin/earnings/headless.ts +53 -15
  438. package/src/plugins/builtin/earnings/history-model.ts +53 -36
  439. package/src/plugins/builtin/earnings/index.tsx +15 -22
  440. package/src/plugins/builtin/earnings/model.ts +17 -12
  441. package/src/plugins/builtin/earnings/scope.ts +89 -0
  442. package/src/plugins/builtin/earnings-calls/calendar.tsx +310 -0
  443. package/src/plugins/builtin/earnings-calls/data.ts +146 -2
  444. package/src/plugins/builtin/earnings-calls/headless.ts +151 -9
  445. package/src/plugins/builtin/earnings-calls/index.tsx +3 -3
  446. package/src/plugins/builtin/earnings-calls/lock-note.ts +1 -1
  447. package/src/plugins/builtin/earnings-calls/pane.tsx +149 -31
  448. package/src/plugins/builtin/earnings-calls/upcoming.ts +195 -0
  449. package/src/plugins/builtin/earnings-ripple/pane.tsx +10 -5
  450. package/src/plugins/builtin/econ/calendar-model.ts +132 -20
  451. package/src/plugins/builtin/econ/detail-view.tsx +48 -10
  452. package/src/plugins/builtin/econ/fred-catalog.ts +23 -6
  453. package/src/plugins/builtin/econ/fred-series-map.ts +4 -0
  454. package/src/plugins/builtin/econ/index.tsx +112 -25
  455. package/src/plugins/builtin/econ/print-watch.ts +2 -1
  456. package/src/plugins/builtin/econ/types.ts +32 -1
  457. package/src/plugins/builtin/econ-statistics/client.ts +16 -3
  458. package/src/plugins/builtin/econ-statistics/defs.ts +4 -0
  459. package/src/plugins/builtin/econ-statistics/detail.tsx +2 -2
  460. package/src/plugins/builtin/econ-statistics/headless.ts +13 -2
  461. package/src/plugins/builtin/econ-statistics/index.tsx +3 -3
  462. package/src/plugins/builtin/econ-statistics/pane.tsx +2 -1
  463. package/src/plugins/builtin/econ-statistics/stats.ts +103 -0
  464. package/src/plugins/builtin/econ-statistics/view.ts +16 -1
  465. package/src/plugins/builtin/equity-screener/client.ts +21 -3
  466. package/src/plugins/builtin/equity-screener/headless.ts +68 -6
  467. package/src/plugins/builtin/equity-screener/live.ts +1 -1
  468. package/src/plugins/builtin/equity-screener/model.ts +6 -0
  469. package/src/plugins/builtin/equity-screener/pane.tsx +45 -10
  470. package/src/plugins/builtin/equity-screener/screen-check.ts +90 -0
  471. package/src/plugins/builtin/equity-screener/ticker-check.tsx +148 -0
  472. package/src/plugins/builtin/estimate-revisions/headless.ts +3 -1
  473. package/src/plugins/builtin/estimate-revisions/lock-note.ts +3 -3
  474. package/src/plugins/builtin/estimate-revisions/model.ts +8 -10
  475. package/src/plugins/builtin/exposure/headless.ts +51 -6
  476. package/src/plugins/builtin/exposure/index.tsx +28 -2
  477. package/src/plugins/builtin/exposure/model.ts +7 -0
  478. package/src/plugins/builtin/exposure/pane.tsx +6 -1
  479. package/src/plugins/builtin/fear-greed/index.tsx +1 -1
  480. package/src/plugins/builtin/filing-events/index.tsx +1 -1
  481. package/src/plugins/builtin/futures/model.ts +10 -9
  482. package/src/plugins/builtin/futures/returns.ts +8 -36
  483. package/src/plugins/builtin/futures/table.tsx +1 -1
  484. package/src/plugins/builtin/futures-curve/client.ts +40 -9
  485. package/src/plugins/builtin/futures-curve/headless.ts +39 -17
  486. package/src/plugins/builtin/futures-curve/model.ts +258 -69
  487. package/src/plugins/builtin/futures-curve/pane.tsx +46 -17
  488. package/src/plugins/builtin/fx-matrix/client.ts +15 -8
  489. package/src/plugins/builtin/fx-matrix/headless.ts +32 -14
  490. package/src/plugins/builtin/fx-matrix/index.tsx +13 -11
  491. package/src/plugins/builtin/fx-matrix/live-legs.ts +22 -0
  492. package/src/plugins/builtin/fx-matrix/settings.ts +2 -1
  493. package/src/plugins/builtin/gpu/headless.ts +9 -4
  494. package/src/plugins/builtin/help/index.tsx +13 -3
  495. package/src/plugins/builtin/holders/beneficial-model.ts +8 -11
  496. package/src/plugins/builtin/holders/beneficial-report.ts +6 -5
  497. package/src/plugins/builtin/holders/beneficial-view.tsx +7 -3
  498. package/src/plugins/builtin/holders/client.ts +13 -1
  499. package/src/plugins/builtin/holders/format.ts +28 -17
  500. package/src/plugins/builtin/holders/headless.ts +46 -7
  501. package/src/plugins/builtin/holders/index-holders.ts +264 -0
  502. package/src/plugins/builtin/holders/pane.tsx +79 -15
  503. package/src/plugins/builtin/holders/report-rows.ts +35 -7
  504. package/src/plugins/builtin/holders/table-model.ts +2 -1
  505. package/src/plugins/builtin/holders/treemap.tsx +2 -2
  506. package/src/plugins/builtin/insider/headless.ts +1 -1
  507. package/src/plugins/builtin/insider/signals-client.ts +1 -1
  508. package/src/plugins/builtin/insider/signals.tsx +1 -1
  509. package/src/plugins/builtin/ipo-calendar/pane.tsx +7 -4
  510. package/src/plugins/builtin/iv-history/client.ts +20 -0
  511. package/src/plugins/builtin/iv-history/headless.ts +4 -4
  512. package/src/plugins/builtin/iv-history/index.tsx +1 -1
  513. package/src/plugins/builtin/iv-history/model.ts +13 -4
  514. package/src/plugins/builtin/iv-history/series.ts +3 -1
  515. package/src/plugins/builtin/jobs/lock-note.ts +1 -1
  516. package/src/plugins/builtin/jobs/model.ts +4 -15
  517. package/src/plugins/builtin/jobs/pane.tsx +7 -5
  518. package/src/plugins/builtin/jobs/share-bars.tsx +11 -5
  519. package/src/plugins/builtin/jodi/pane.tsx +10 -4
  520. package/src/plugins/builtin/layout-manager/index.tsx +1 -0
  521. package/src/plugins/builtin/macro-day/headless.ts +20 -7
  522. package/src/plugins/builtin/macro-day/index.tsx +3 -2
  523. package/src/plugins/builtin/macro-day/model.ts +29 -8
  524. package/src/plugins/builtin/macro-day/pane.tsx +46 -10
  525. package/src/plugins/builtin/macro-day/releases.ts +55 -13
  526. package/src/plugins/builtin/market-heatmap/data.ts +9 -2
  527. package/src/plugins/builtin/market-heatmap/evidence.ts +1 -1
  528. package/src/plugins/builtin/market-heatmap/headless.ts +9 -6
  529. package/src/plugins/builtin/market-heatmap/index.tsx +3 -3
  530. package/src/plugins/builtin/market-heatmap/model.ts +10 -7
  531. package/src/plugins/builtin/market-movers/client.ts +33 -19
  532. package/src/plugins/builtin/market-movers/headless.ts +8 -2
  533. package/src/plugins/builtin/market-movers/index.tsx +16 -10
  534. package/src/plugins/builtin/market-movers/screener.ts +29 -8
  535. package/src/plugins/builtin/market-movers/session-body.tsx +4 -2
  536. package/src/plugins/builtin/market-movers/session-table.ts +4 -2
  537. package/src/plugins/builtin/market-movers/table.ts +4 -1
  538. package/src/plugins/builtin/market-valuation/headless.ts +2 -0
  539. package/src/plugins/builtin/market-valuation/view.ts +5 -0
  540. package/src/plugins/builtin/members/headless.ts +6 -5
  541. package/src/plugins/builtin/members/pane.tsx +11 -4
  542. package/src/plugins/builtin/mna/client.ts +1 -0
  543. package/src/plugins/builtin/mna/detail.tsx +20 -32
  544. package/src/plugins/builtin/mna/distress/detail.tsx +16 -4
  545. package/src/plugins/builtin/mna/distress/model.ts +3 -2
  546. package/src/plugins/builtin/mna/distress/pane.tsx +7 -4
  547. package/src/plugins/builtin/mna/headless.ts +6 -13
  548. package/src/plugins/builtin/mna/model.ts +93 -15
  549. package/src/plugins/builtin/mna/pane.tsx +5 -4
  550. package/src/plugins/builtin/news/headless.ts +12 -6
  551. package/src/plugins/builtin/news/index.tsx +10 -1
  552. package/src/plugins/builtin/news/wire/index.tsx +3 -2
  553. package/src/plugins/builtin/news/wire/news/command-bar-search.ts +26 -10
  554. package/src/plugins/builtin/news/wire/news/query-presets.ts +6 -2
  555. package/src/plugins/builtin/news/wire/rss/cli.ts +3 -3
  556. package/src/plugins/builtin/notes/cli.ts +49 -14
  557. package/src/plugins/builtin/openfda/pane.tsx +1 -1
  558. package/src/plugins/builtin/options/carry.ts +2 -2
  559. package/src/plugins/builtin/options/index.tsx +1 -1
  560. package/src/plugins/builtin/options/view.tsx +10 -10
  561. package/src/plugins/builtin/options-calculator/headless.ts +46 -7
  562. package/src/plugins/builtin/options-scenario/client.ts +123 -28
  563. package/src/plugins/builtin/options-scenario/collar.ts +8 -6
  564. package/src/plugins/builtin/options-scenario/csp-screen-headless.ts +127 -0
  565. package/src/plugins/builtin/options-scenario/csp-screen-pane.tsx +165 -0
  566. package/src/plugins/builtin/options-scenario/csp-screen.ts +258 -0
  567. package/src/plugins/builtin/options-scenario/csp.ts +101 -21
  568. package/src/plugins/builtin/options-scenario/headless.ts +36 -15
  569. package/src/plugins/builtin/options-scenario/hedge.ts +20 -14
  570. package/src/plugins/builtin/options-scenario/index.tsx +28 -3
  571. package/src/plugins/builtin/options-scenario/model.ts +13 -0
  572. package/src/plugins/builtin/options-scenario/pane.tsx +9 -5
  573. package/src/plugins/builtin/perps/equity-row.tsx +11 -3
  574. package/src/plugins/builtin/perps/freshness.ts +8 -5
  575. package/src/plugins/builtin/perps/headless.ts +3 -1
  576. package/src/plugins/builtin/perps/list-perpetuals.ts +25 -4
  577. package/src/plugins/builtin/perps/live-rows.ts +161 -0
  578. package/src/plugins/builtin/perps/markets-section.tsx +154 -0
  579. package/src/plugins/builtin/perps/pane.tsx +36 -17
  580. package/src/plugins/builtin/perps/venue-markets.ts +96 -0
  581. package/src/plugins/builtin/plugin-marketplace/index.tsx +2 -1
  582. package/src/plugins/builtin/plugin-marketplace/pane.tsx +143 -59
  583. package/src/plugins/builtin/portfolio-list/cli/bulk-symbols.ts +72 -24
  584. package/src/plugins/builtin/portfolio-list/cli/portfolio-command.ts +158 -141
  585. package/src/plugins/builtin/portfolio-list/cli/render.ts +49 -20
  586. package/src/plugins/builtin/portfolio-list/cli/shared.ts +3 -3
  587. package/src/plugins/builtin/portfolio-list/cli/watchlist-command.ts +29 -24
  588. package/src/plugins/builtin/portfolio-list/headless.ts +6 -3
  589. package/src/plugins/builtin/portfolio-list/income.ts +13 -2
  590. package/src/plugins/builtin/portfolio-list/index.tsx +9 -2
  591. package/src/plugins/builtin/portfolio-list/pane/index.tsx +21 -8
  592. package/src/plugins/builtin/portfolio-list/pane/purchase-date-fx.ts +46 -0
  593. package/src/plugins/builtin/portfolio-list/summary/live-accounts.ts +16 -9
  594. package/src/plugins/builtin/portfolio-list/summary/totals.ts +2 -15
  595. package/src/plugins/builtin/power/client.ts +4 -1
  596. package/src/plugins/builtin/power/evidence.ts +22 -7
  597. package/src/plugins/builtin/power/gas.tsx +5 -1
  598. package/src/plugins/builtin/power/pane.tsx +8 -1
  599. package/src/plugins/builtin/power/prices.tsx +10 -3
  600. package/src/plugins/builtin/research/analyst-headless.ts +25 -8
  601. package/src/plugins/builtin/research/analyst-model.ts +68 -3
  602. package/src/plugins/builtin/research/corporate-actions-pane.tsx +63 -14
  603. package/src/plugins/builtin/research/event-model.ts +3 -1
  604. package/src/plugins/builtin/research/event-sources.ts +12 -4
  605. package/src/plugins/builtin/research/index.tsx +2 -1
  606. package/src/plugins/builtin/research/relative-valuation-basis.ts +58 -0
  607. package/src/plugins/builtin/research/relative-valuation-columns.ts +31 -2
  608. package/src/plugins/builtin/research/relative-valuation-currency.ts +12 -5
  609. package/src/plugins/builtin/research/relative-valuation-headless.ts +84 -26
  610. package/src/plugins/builtin/research/relative-valuation-model.ts +88 -19
  611. package/src/plugins/builtin/research/relative-valuation-pane.tsx +76 -9
  612. package/src/plugins/builtin/research/relative-valuation-peers.ts +1 -1
  613. package/src/plugins/builtin/reverse-dcf/model.ts +6 -2
  614. package/src/plugins/builtin/risk-factors/index.tsx +2 -2
  615. package/src/plugins/builtin/scanner/lock-note.ts +1 -1
  616. package/src/plugins/builtin/sec/forms.ts +13 -0
  617. package/src/plugins/builtin/sec/fund-abroad.ts +32 -0
  618. package/src/plugins/builtin/sec/fund-facts.ts +68 -8
  619. package/src/plugins/builtin/sec/headless.ts +85 -8
  620. package/src/plugins/builtin/sec/index.tsx +58 -12
  621. package/src/plugins/builtin/sectors/client.ts +2 -1
  622. package/src/plugins/builtin/sectors/sector-model.ts +11 -15
  623. package/src/plugins/builtin/series-inventory.ts +2 -0
  624. package/src/plugins/builtin/shared/broker-reconnect.ts +107 -22
  625. package/src/plugins/builtin/shared/cloud-upgrade.ts +34 -6
  626. package/src/plugins/builtin/shared/earnings-calendar.ts +375 -0
  627. package/src/plugins/builtin/{earnings/estimate-basis.ts → shared/earnings-estimate-basis.ts} +1 -1
  628. package/src/plugins/builtin/shared/earnings-report.ts +3 -3
  629. package/src/plugins/builtin/shared/fx-rate-freshness.ts +23 -1
  630. package/src/plugins/builtin/shared/job-posting.ts +129 -0
  631. package/src/plugins/builtin/shared/pro-lock-note.ts +3 -3
  632. package/src/plugins/builtin/shared/report-freshness.ts +3 -0
  633. package/src/plugins/builtin/shared/research-trading.tsx +21 -0
  634. package/src/plugins/builtin/shared/series-cache.ts +2 -0
  635. package/src/plugins/builtin/shared/ticker-surface.ts +2 -1
  636. package/src/plugins/builtin/short-interest/client.ts +2 -0
  637. package/src/plugins/builtin/short-interest/headless.ts +41 -12
  638. package/src/plugins/builtin/short-interest/index.tsx +23 -1
  639. package/src/plugins/builtin/short-interest/model.ts +70 -19
  640. package/src/plugins/builtin/short-interest/pane.tsx +19 -2
  641. package/src/plugins/builtin/short-interest/publications-client.ts +82 -0
  642. package/src/plugins/builtin/short-interest/publications-headless.ts +29 -0
  643. package/src/plugins/builtin/short-interest/publications-model.ts +50 -0
  644. package/src/plugins/builtin/short-interest/publications-pane.tsx +66 -0
  645. package/src/plugins/builtin/short-interest/schedule.ts +35 -2
  646. package/src/plugins/builtin/short-interest/surface.tsx +11 -4
  647. package/src/plugins/builtin/short-interest/types.ts +9 -0
  648. package/src/plugins/builtin/short-interest/watch-client.ts +14 -8
  649. package/src/plugins/builtin/short-interest/watch-model.ts +12 -25
  650. package/src/plugins/builtin/short-interest/watch-pane.tsx +5 -1
  651. package/src/plugins/builtin/supply-chain/flow.tsx +33 -9
  652. package/src/plugins/builtin/supply-chain/model.ts +51 -3
  653. package/src/plugins/builtin/supply-chain/pane.tsx +78 -39
  654. package/src/plugins/builtin/supply-chain/row-evidence.tsx +1 -1
  655. package/src/plugins/builtin/themes/headless.ts +8 -5
  656. package/src/plugins/builtin/themes/model.ts +14 -4
  657. package/src/plugins/builtin/themes/pane.tsx +24 -5
  658. package/src/plugins/builtin/thirteenf/headless.ts +5 -5
  659. package/src/plugins/builtin/thirteenf/signals.ts +3 -1
  660. package/src/plugins/builtin/ticker-detail/adr-pair/headless.ts +123 -0
  661. package/src/plugins/builtin/ticker-detail/adr-pair/model.ts +132 -0
  662. package/src/plugins/builtin/ticker-detail/adr-pair/tab.tsx +87 -0
  663. package/src/plugins/builtin/ticker-detail/data-panes/historical-prices.tsx +40 -26
  664. package/src/plugins/builtin/ticker-detail/data-panes/history-bars.ts +8 -4
  665. package/src/plugins/builtin/ticker-detail/data-panes/returns-history.ts +67 -3
  666. package/src/plugins/builtin/ticker-detail/data-panes/returns-model.ts +112 -5
  667. package/src/plugins/builtin/ticker-detail/data-panes/returns-pane.tsx +17 -2
  668. package/src/plugins/builtin/ticker-detail/financials/aggregation.ts +21 -7
  669. package/src/plugins/builtin/ticker-detail/financials/model.ts +36 -1
  670. package/src/plugins/builtin/ticker-detail/financials/offerings.ts +56 -0
  671. package/src/plugins/builtin/ticker-detail/financials/ratios.ts +62 -13
  672. package/src/plugins/builtin/ticker-detail/financials/tab.tsx +30 -4
  673. package/src/plugins/builtin/ticker-detail/headless-schema.ts +14 -2
  674. package/src/plugins/builtin/ticker-detail/headless.ts +148 -35
  675. package/src/plugins/builtin/ticker-detail/index.tsx +37 -5
  676. package/src/plugins/builtin/ticker-detail/overview/model.ts +65 -10
  677. package/src/plugins/builtin/ticker-detail/overview/pane.tsx +9 -1
  678. package/src/plugins/builtin/ticker-detail/overview-tab.tsx +68 -11
  679. package/src/plugins/builtin/ticker-detail/pane.tsx +11 -0
  680. package/src/plugins/builtin/ticker-detail/quote-footer.ts +8 -3
  681. package/src/plugins/builtin/ticker-detail/research-tabs.ts +11 -0
  682. package/src/plugins/builtin/vol-surface/client.ts +5 -4
  683. package/src/plugins/builtin/vol-surface/headless.ts +12 -3
  684. package/src/plugins/builtin/vol-surface/model.ts +4 -2
  685. package/src/plugins/builtin/volatility/model.ts +5 -10
  686. package/src/plugins/builtin/world-venue-map/basemap-layer.tsx +4 -3
  687. package/src/plugins/builtin/world-venue-map/basemap.ts +3 -1
  688. package/src/plugins/builtin/world-venue-map/chokepoint-chart.ts +40 -0
  689. package/src/plugins/builtin/world-venue-map/evidence.ts +1 -1
  690. package/src/plugins/builtin/world-venue-map/geo-series.ts +90 -11
  691. package/src/plugins/builtin/world-venue-map/headless.ts +1 -1
  692. package/src/plugins/builtin/world-venue-map/index.ts +3 -26
  693. package/src/plugins/builtin/world-venue-map/layers.ts +1 -1
  694. package/src/plugins/builtin/world-venue-map/map.tsx +2 -1
  695. package/src/plugins/builtin/world-venue-map/pane.tsx +4 -2
  696. package/src/plugins/builtin/world-venue-map/venue-header.tsx +15 -4
  697. package/src/plugins/builtin/yield-curve/client.ts +25 -0
  698. package/src/plugins/builtin/yield-curve/curves.ts +7 -4
  699. package/src/plugins/builtin/yield-curve/headless.ts +38 -4
  700. package/src/plugins/builtin/yield-curve/history.ts +4 -3
  701. package/src/plugins/builtin/yield-curve/index.tsx +12 -6
  702. package/src/plugins/builtin/yield-curve/swaps-model.ts +93 -0
  703. package/src/plugins/builtin/yield-curve/swaps.tsx +99 -0
  704. package/src/plugins/bundle.ts +1 -1
  705. package/src/plugins/catalog-browser.ts +2 -1
  706. package/src/plugins/compat.ts +3 -3
  707. package/src/plugins/dependencies.ts +75 -14
  708. package/src/plugins/extracted-plugins.ts +132 -34
  709. package/src/plugins/host-link.ts +149 -34
  710. package/src/plugins/installer.ts +35 -10
  711. package/src/plugins/loader.ts +206 -38
  712. package/src/plugins/manager-node.ts +2 -2
  713. package/src/plugins/marketplace/deactivation.ts +22 -0
  714. package/src/plugins/marketplace/model.ts +2 -2
  715. package/src/plugins/marketplace/packs.ts +1 -1
  716. package/src/plugins/ownership.ts +1 -1
  717. package/src/plugins/peer-retry.ts +155 -0
  718. package/src/plugins/registry/contributions.ts +3 -1
  719. package/src/plugins/registry/index.ts +4 -3
  720. package/src/plugins/registry/plugin-state.ts +3 -0
  721. package/src/plugins/seed-notice.ts +20 -0
  722. package/src/plugins/shortcut-argument.ts +39 -0
  723. package/src/portfolio/allocation.ts +1 -1
  724. package/src/portfolio/collection-name.ts +31 -0
  725. package/src/portfolio/column-values.ts +10 -8
  726. package/src/portfolio/cost-fx.ts +296 -19
  727. package/src/portfolio/manual-lots.ts +75 -0
  728. package/src/portfolio/mutations.ts +60 -22
  729. package/src/portfolio/suffixed-listings.ts +209 -0
  730. package/src/portfolio/totals-currency.ts +24 -0
  731. package/src/public/__snapshots__/public-api.test.ts.snap +14 -0
  732. package/src/public/time-series.ts +11 -8
  733. package/src/remote/schema.ts +1 -1
  734. package/src/renderers/browser/config-host.ts +3 -0
  735. package/src/renderers/browser/main.tsx +23 -3
  736. package/src/renderers/dom/boot-frame-page.ts +187 -0
  737. package/src/renderers/dom/boot-frame.ts +237 -0
  738. package/src/renderers/dom/build-assets.ts +46 -8
  739. package/src/renderers/dom/dom-ui-host.tsx +4 -29
  740. package/src/renderers/dom/host/ascii-text.ts +16 -2
  741. package/src/renderers/dom/host/box.tsx +43 -2
  742. package/src/renderers/dom/host/chart-surface.tsx +2 -0
  743. package/src/renderers/dom/host/hls.chunk.ts +3 -0
  744. package/src/renderers/dom/host/image-surface.tsx +49 -0
  745. package/src/renderers/dom/host/media-surface.tsx +24 -18
  746. package/src/renderers/dom/host/mouse.ts +30 -0
  747. package/src/renderers/dom/host/size-observer.ts +1 -1
  748. package/src/renderers/dom/host/style.ts +1 -1
  749. package/src/renderers/dom/styles.css +76 -0
  750. package/src/renderers/dom/test-utils.tsx +2 -1
  751. package/src/renderers/electrobun/bun/application-menu/index.ts +3 -3
  752. package/src/renderers/electrobun/bun/desktop/backend-requests.ts +3 -0
  753. package/src/renderers/electrobun/bun/desktop/backend.ts +46 -3
  754. package/src/renderers/electrobun/bun/desktop/detached-windows.ts +1 -1
  755. package/src/renderers/electrobun/bun/desktop/host-requests.ts +9 -3
  756. package/src/renderers/electrobun/bun/desktop/initialization.ts +81 -18
  757. package/src/renderers/electrobun/bun/external-plugins.ts +29 -7
  758. package/src/renderers/electrobun/bun/index.ts +11 -1
  759. package/src/renderers/electrobun/bun/window/boot-frame.ts +67 -0
  760. package/src/renderers/electrobun/bun/window/create.ts +4 -1
  761. package/src/renderers/electrobun/shared/boot-frame.ts +7 -0
  762. package/src/renderers/electrobun/shared/protocol.ts +6 -1
  763. package/src/renderers/electrobun/view/cli-pane-shot-entry.tsx +1 -1
  764. package/src/renderers/electrobun/view/config-host.ts +3 -0
  765. package/src/renderers/electrobun/view/fatal-screen.tsx +1 -1
  766. package/src/renderers/electrobun/view/main.tsx +30 -4
  767. package/src/renderers/electrobun/view/news-source.ts +5 -5
  768. package/src/renderers/electrobun/view/remote/asset-data-client.ts +1 -1
  769. package/src/renderers/electrobun/view/ui-host.tsx +1 -1
  770. package/src/renderers/opentui/browser-open.ts +88 -0
  771. package/src/renderers/opentui/host.tsx +5 -14
  772. package/src/renderers/opentui/image/loader.ts +3 -2
  773. package/src/renderers/opentui/native-smoke.ts +10 -1
  774. package/src/renderers/opentui/pane-image/index.ts +2 -1
  775. package/src/renderers/opentui/render-lib.ts +253 -0
  776. package/src/renderers/opentui/render-timing-smoke.ts +1 -1
  777. package/src/renderers/opentui/start.tsx +1 -1
  778. package/src/renderers/share/layout-view.tsx +2 -2
  779. package/src/renderers/share/main.tsx +4 -4
  780. package/src/renderers/share/view.tsx +1 -1
  781. package/src/series/resolve.ts +22 -6
  782. package/src/series/standalone.ts +30 -2
  783. package/src/series/types.ts +8 -1
  784. package/src/shares/api.ts +4 -1
  785. package/src/shares/pane.ts +1 -1
  786. package/src/sources/gloomberb-cloud/fred-series.ts +46 -1
  787. package/src/sources/gloomberb-cloud/index.ts +32 -16
  788. package/src/sources/gloomberb-cloud/news.ts +39 -0
  789. package/src/sources/gloomberb-cloud/normalizers.ts +14 -1
  790. package/src/sources/gloomberb-cloud/perpetuals.ts +49 -1
  791. package/src/sources/listing-symbols.ts +37 -0
  792. package/src/sources/provider-errors.ts +16 -2
  793. package/src/sources/provider-router/financial-routes.ts +21 -3
  794. package/src/sources/provider-router/financials.ts +15 -2
  795. package/src/sources/provider-router/history.ts +30 -8
  796. package/src/sources/provider-router/primary.ts +1 -1
  797. package/src/state/app/bootstrap.ts +23 -0
  798. package/src/state/hooks/inline-tickers.ts +30 -5
  799. package/src/sync/controller.ts +1 -1
  800. package/src/sync/core-contributors.ts +46 -14
  801. package/src/team/collections-sync.ts +2 -1
  802. package/src/team/collections.ts +178 -17
  803. package/src/telemetry/crash-reports.ts +17 -4
  804. package/src/test-support/builtin-panes.ts +1 -1
  805. package/src/theme/colors.ts +3 -30
  806. package/src/theme/ui-tokens.ts +37 -1
  807. package/src/tickers/company-name-listing.ts +210 -33
  808. package/src/tickers/index-roots.ts +47 -0
  809. package/src/tickers/instrument-label.ts +5 -1
  810. package/src/tickers/metadata.ts +10 -0
  811. package/src/tickers/perpetual-listing.ts +5 -2
  812. package/src/tickers/search/home-listing.ts +75 -0
  813. package/src/tickers/search/index.ts +76 -27
  814. package/src/tickers/search/ranking.ts +54 -4
  815. package/src/tickers/search/upsert.ts +29 -0
  816. package/src/tickers/terminal-codes.ts +416 -40
  817. package/src/time-series/bar-aggregation.ts +243 -0
  818. package/src/time-series/base-series.ts +307 -0
  819. package/src/time-series/chart-bounds.ts +349 -0
  820. package/src/time-series/chart-seed.ts +142 -0
  821. package/src/time-series/economic.ts +5 -0
  822. package/src/time-series/fundamentals.ts +18 -3
  823. package/src/time-series/history-acquisition.ts +499 -0
  824. package/src/time-series/leverage.ts +100 -0
  825. package/src/time-series/market-resolution.ts +4 -2
  826. package/src/time-series/market.ts +2 -1
  827. package/src/time-series/price-comparison.ts +175 -30
  828. package/src/time-series/range.ts +9 -1
  829. package/src/time-series/resolution.ts +174 -16
  830. package/src/time-series/resolve-context.ts +157 -0
  831. package/src/time-series/resolve.ts +126 -1577
  832. package/src/time-series/series-name.ts +38 -0
  833. package/src/time-series/series-presentation.ts +208 -0
  834. package/src/time-series/spec.ts +11 -6
  835. package/src/time-series/studies.ts +109 -12
  836. package/src/time-series/tail-reconcile.ts +121 -0
  837. package/src/time-series/types.ts +29 -2
  838. package/src/time-series/use-chart-resolution.ts +4 -5
  839. package/src/types/broker.ts +10 -0
  840. package/src/types/config.ts +14 -0
  841. package/src/types/data-provider.ts +14 -0
  842. package/src/types/exchange-rate.ts +6 -0
  843. package/src/types/financials.ts +104 -7
  844. package/src/types/headless.ts +76 -6
  845. package/src/types/instrument.ts +3 -0
  846. package/src/types/plugin.ts +65 -8
  847. package/src/types/price-history.ts +2 -0
  848. package/src/types/ticker.ts +13 -0
  849. package/src/types/trading.ts +59 -1
  850. package/src/ui/ascii-font.ts +13 -1
  851. package/src/ui/host.tsx +6 -1
  852. package/src/updater/command-names.ts +175 -0
  853. package/src/updater/index.ts +10 -5
  854. package/src/utils/calendar-date.ts +32 -15
  855. package/src/utils/cash-runway.ts +241 -0
  856. package/src/utils/central-banks.ts +42 -0
  857. package/src/utils/cli-output.ts +259 -80
  858. package/src/utils/contract-month.ts +16 -0
  859. package/src/utils/crypto-pair.ts +61 -3
  860. package/src/utils/currency-units.ts +29 -0
  861. package/src/utils/datetime-format.ts +10 -0
  862. package/src/utils/debug-log.ts +1 -1
  863. package/src/utils/decimal-comma.ts +39 -6
  864. package/src/utils/exchange-announcements.ts +71 -0
  865. package/src/utils/exchange-rate-snapshot.ts +10 -0
  866. package/src/utils/financial-statements.ts +83 -4
  867. package/src/utils/format.ts +34 -16
  868. package/src/utils/fundamentals.ts +150 -34
  869. package/src/utils/fx-market-hours.ts +10 -1
  870. package/src/utils/latest-financial-period.ts +8 -0
  871. package/src/utils/linux-libc.ts +54 -0
  872. package/src/utils/market-capitalization.ts +111 -15
  873. package/src/utils/max-drawdown.ts +64 -0
  874. package/src/utils/network-failure.ts +83 -0
  875. package/src/utils/option-expiry.ts +139 -7
  876. package/src/utils/price-earnings.ts +11 -5
  877. package/src/utils/price-history.ts +18 -8
  878. package/src/utils/price-window.ts +131 -0
  879. package/src/utils/release-date.ts +47 -0
  880. package/src/utils/sec.ts +3 -0
  881. package/src/utils/throttled-fetch.ts +11 -4
  882. package/src/utils/trailing-eps.ts +67 -0
  883. package/src/utils/typed-text.ts +21 -0
  884. package/src/utils/utc-time.ts +24 -1
  885. package/src/version.ts +6 -0
  886. package/src/cli/pane-functions/screenshot.ts +0 -2122
@@ -9,6 +9,7 @@ import { usePluginBrokerActions } from "../../../runtime";
9
9
  import type { OfflineBroker } from "../../shared/broker-reconnect";
10
10
  import { tf } from "../../../../i18n";
11
11
  import { isSignedInBrokerProfile, signedInBrokerId } from "../../../../brokers/signed-in/profile";
12
+ import { accountsShownFor } from "../../../../brokers/broker-portfolio-sync";
12
13
  import { resolvePortfolioAccountState, type ResolvedPortfolioAccountState } from "./index";
13
14
 
14
15
  const EMPTY_ACCOUNTS = { instanceId: null, accounts: [] as BrokerAccount[], error: null };
@@ -98,9 +99,10 @@ export interface PortfolioAccountStateResult {
98
99
 
99
100
  /**
100
101
  * The broker behind a portfolio while Gloom cannot reach it: disconnected,
101
- * failing, or without the plugin that connects it. Null while it is connected
102
- * or connecting, before it reports a status, for a profile turned off, and for
103
- * one that only syncs on demand (IBKR Flex), which is never connected.
102
+ * failing, without the plugin that connects it, or turned off (`disabled`),
103
+ * which nothing syncs until it is enabled. Null while it is connected or
104
+ * connecting, before it reports a status, and for one that only syncs on
105
+ * demand (IBKR Flex), which is never connected.
104
106
  */
105
107
  export function resolveOfflineBroker(
106
108
  portfolio: Portfolio | null,
@@ -108,16 +110,20 @@ export function resolveOfflineBroker(
108
110
  broker: BrokerAdapter | null | undefined,
109
111
  status: BrokerConnectionStatus | null,
110
112
  ): OfflineBroker | null {
111
- if (!portfolio || !brokerInstance || brokerInstance.enabled === false) return null;
113
+ if (!portfolio || !brokerInstance) return null;
112
114
  const syncedAt = portfolio.lastSyncedAt ?? brokerInstance.lastSyncedAt ?? null;
115
+ // A profile signed in through Gloom names its broker, not the adapter it needs.
116
+ const brokerName = broker
117
+ ? broker.describeInstance?.(brokerInstance).brokerName ?? broker.name
118
+ : (isSignedInBrokerProfile(brokerInstance) ? signedInBrokerId(brokerInstance) : brokerInstance.brokerType).toUpperCase();
119
+ if (brokerInstance.enabled === false) {
120
+ return { instance: brokerInstance, brokerName, syncedAt, reason: tf("{broker} disabled", { broker: brokerName }), reconnectable: !!broker, disabled: true };
121
+ }
113
122
  if (!broker) {
114
- // A profile signed in through Gloom names its broker, not the adapter it needs.
115
- const brokerName = (isSignedInBrokerProfile(brokerInstance) ? signedInBrokerId(brokerInstance) : brokerInstance.brokerType).toUpperCase();
116
123
  return { instance: brokerInstance, brokerName, syncedAt, reason: tf("{broker} unavailable", { broker: brokerName }), reconnectable: false };
117
124
  }
118
125
  if (!status || status.state === "connected" || status.state === "connecting") return null;
119
126
  if (status.mode?.toLowerCase() === "flex") return null;
120
- const brokerName = broker.describeInstance?.(brokerInstance).brokerName ?? broker.name;
121
127
  const reason = status.state === "error"
122
128
  ? status.message?.trim() || tf("{broker} unavailable", { broker: brokerName })
123
129
  : tf("{broker} disconnected", { broker: brokerName });
@@ -141,9 +147,10 @@ export function usePortfolioAccountState(
141
147
  const { getBrokerAdapter } = usePluginBrokerActions();
142
148
  const broker = brokerInstance ? getBrokerAdapter(brokerInstance.brokerType) : null;
143
149
  const live = useLiveBrokerAccounts(broker, brokerInstance, instanceId ? state.brokerAccounts[instanceId] : undefined);
150
+ // An account another profile holds under its own number is that profile's, here as in sync.
144
151
  const snapshot = useMemo(
145
- () => ({ status: live.status, accounts: live.accounts }),
146
- [live.accounts, live.status],
152
+ () => ({ status: live.status, accounts: brokerInstance ? accountsShownFor(state.config, brokerInstance, live.accounts) : live.accounts }),
153
+ [brokerInstance, live.accounts, live.status, state.config],
147
154
  );
148
155
  const accountState = useMemo(
149
156
  () => resolvePortfolioAccountState(portfolio, state, snapshot),
@@ -1,12 +1,11 @@
1
1
  import type { TickerFinancials } from "../../../../types/financials";
2
- import type { Portfolio, TickerRecord } from "../../../../types/ticker";
2
+ import type { TickerRecord } from "../../../../types/ticker";
3
3
  import { convertCurrency, formatCompactAmount } from "../../../../utils/format";
4
4
  import { getCurrencySymbol } from "../../../../market-data/market/format";
5
5
  import { getActiveQuoteDisplay } from "../../../../market-data/market/status";
6
6
  import { combinedChangeBasisLabel, quoteChangeBasis, type QuoteChangeBasis } from "../../../../market-data/market/change-basis";
7
7
  import { isQuoteStaleForCurrentSession } from "../../../../market-data/quotes/freshness";
8
8
  import { headlineQuoteDisplay } from "../../../../portfolio/column-values";
9
- import { isManualPortfolio } from "../../../../portfolio/mutations";
10
9
  import type { AllocationHolding } from "../../../../portfolio/allocation";
11
10
  import { getPortfolioValuationDisplay, type PortfolioValuationBasis } from "../../../../portfolio/valuation-basis";
12
11
  import type { PortfolioFuturesTerms } from "../../../../portfolio/futures-positions";
@@ -76,19 +75,7 @@ function currencyCode(value: string | undefined): string | null {
76
75
  return CURRENCY_CODE.test(code) ? code : null;
77
76
  }
78
77
 
79
- /**
80
- * The currency a portfolio's totals, market values and P&L are in. A broker
81
- * portfolio uses its account currency. A manual portfolio uses its stored
82
- * currency with the default USD base (its first holding sets it, see
83
- * adoptFirstPositionCurrency); a base currency the user chose is what manual
84
- * portfolios and watchlists total in.
85
- */
86
- export function resolvePortfolioTotalsCurrency(portfolio: Portfolio | null | undefined, baseCurrency: string): string {
87
- const base = currencyCode(baseCurrency) ?? "USD";
88
- if (!portfolio) return base;
89
- if (isManualPortfolio(portfolio) && base !== "USD") return base;
90
- return currencyCode(portfolio.currency) ?? base;
91
- }
78
+ export { resolvePortfolioTotalsCurrency } from "../../../../portfolio/totals-currency";
92
79
 
93
80
  /**
94
81
  * A compact total in the portfolio's currency. Bare when both it and the app's
@@ -15,7 +15,10 @@ const nullableText = (v: unknown) => v === null || text(v);
15
15
  const nonnegative = (v: unknown): v is number => typeof v === "number" && Number.isFinite(v) && v >= 0;
16
16
  const integer = (v: unknown) => nonnegative(v) && Number.isInteger(v);
17
17
  const instant = (v: unknown) => text(v) && Number.isFinite(Date.parse(v));
18
- const url = (v: unknown) => { try { return text(v) && new URL(v).protocol === "https:"; } catch { return false; } };
18
+ const url = (v: unknown) => { try { return text(v) && new URL(v).protocol === "https:"; } catch {
19
+ // Intentional ignore: malformed URLs fail this HTTPS field validator.
20
+ return false;
21
+ } };
19
22
  const access = (v: unknown) => v === "full" || v === "preview";
20
23
  const entities = (v: unknown) => Array.isArray(v) && v.every((e) => record(e) && text(e.name) && text(e.entityId)
21
24
  && ["utility", "developer"].includes(e.role) && nonnegative(e.confidence) && e.confidence <= 1
@@ -1,3 +1,4 @@
1
+ import { logFailure } from "../../../utils/log-failure";
1
2
  import type { CarbonBoard, CarbonHistory, EuropePowerBoard, EuropePowerHistory, GasStorageBoard, GasStorageSeasonal } from "../../../api-client/europe-energy";
2
3
  import type { PowerBoard, PowerHistory } from "../../../api-client/power";
3
4
  import type { PaneScreenshotEvidenceHook } from "../../../cli/pane-functions/screenshot-evidence";
@@ -21,6 +22,7 @@ interface PowerEvidence {
21
22
  /** The day-ahead board and the EUA board, on the Prices tab. */
22
23
  prices?: EuropePowerBoard | null;
23
24
  carbon?: CarbonBoard | null;
25
+ carbonError?: string;
24
26
  /** The gas storage board, on the Prices tab's gas board. */
25
27
  gas?: GasStorageBoard | null;
26
28
  tab: string;
@@ -33,6 +35,8 @@ export interface PowerPricesSnapshot {
33
35
  history: EuropePowerHistory | CarbonHistory | null;
34
36
  /** Null when the server has no EUA price yet; the tab then shows the board alone. */
35
37
  carbon: CarbonBoard | null;
38
+ /** A completed optional read that failed; older snapshots omit this field. */
39
+ carbonError?: string;
36
40
  }
37
41
  /** What the gas board draws, frozen by `shot`: the board and the selected area's seasonal range. */
38
42
  export interface GasStorageSnapshot {
@@ -45,10 +49,10 @@ export function usePowerEvidence(board: PowerBoard | undefined, history: PowerHi
45
49
  plottedValueCount: rowIds.length, board, history: history ?? null, tab, rowIds,
46
50
  }) });
47
51
  }
48
- export function usePowerPricesEvidence(prices: EuropePowerBoard | null, carbon: CarbonBoard | null, rowIds: string[], loading: boolean) {
52
+ export function usePowerPricesEvidence(prices: EuropePowerBoard | null, carbon: CarbonBoard | null, rowIds: string[], loading: boolean, carbonError?: string | null) {
49
53
  useRemoteUiNode({ role: "chart-data", label: "Rendered day-ahead power and carbon prices", getMetadata: () => ({
50
54
  kind: "power", version: 1, complete: !!prices && !loading, ready: !!prices && !loading,
51
- plottedValueCount: rowIds.length, board: null, history: null, prices, carbon, tab: "prices", rowIds,
55
+ plottedValueCount: rowIds.length, board: null, history: null, prices, carbon, ...(carbonError ? { carbonError } : {}), tab: "prices", rowIds,
52
56
  }) });
53
57
  }
54
58
  export function useGasStorageEvidence(gas: GasStorageBoard | null, rowIds: string[], loading: boolean) {
@@ -71,13 +75,19 @@ export const powerScreenshotEvidence: PaneScreenshotEvidenceHook<PowerEvidence>
71
75
  }
72
76
  if (tab === "prices") {
73
77
  const board = await fetchPowerPrices();
74
- // The carbon figures are captured when the server has them, and left out when it does not.
75
- const carbon = await fetchCarbonPrice().catch(() => null);
78
+ // Optional carbon failure travels with the board, just as it does in the live pane.
79
+ let carbonError: string | undefined;
80
+ const carbon = await fetchCarbonPrice().catch((error: unknown) => {
81
+ logFailure("power.evidence", "Load carbon price for capture failed")(error);
82
+ const message = error instanceof Error ? error.message : String(error);
83
+ carbonError = message.trim() ? message : "Request failed";
84
+ return null;
85
+ });
76
86
  const arg = resolved.createOptions?.arg;
77
87
  const market = powerPriceMarket(arg)?.code ?? DEFAULT_PRICE_MARKET;
78
88
  const history = isCarbonQuery(arg) && carbon?.row.date ? await fetchCarbonHistory()
79
89
  : board.rows.some((row) => row.code === market && row.date) ? await fetchPowerPriceHistory(market) : null;
80
- return { settings: { powerPricesSnapshot: { board, history, carbon } satisfies PowerPricesSnapshot }, financials: [] };
90
+ return { settings: { powerPricesSnapshot: { board, history, carbon, ...(carbonError ? { carbonError } : {}) } satisfies PowerPricesSnapshot }, financials: [] };
81
91
  }
82
92
  const symbol = resolved.createOptions?.symbol ?? resolved.createOptions?.arg;
83
93
  const filter = powerQuery({ ...settings, ...resolved.options, tab }, symbol);
@@ -103,6 +113,7 @@ export const powerScreenshotEvidence: PaneScreenshotEvidenceHook<PowerEvidence>
103
113
  if (!isRecord(value.prices)) return null;
104
114
  const prices = validatePowerPrices(value.prices as unknown as EuropePowerBoard);
105
115
  if (value.carbon != null) validateCarbonPrice(value.carbon as unknown as CarbonBoard);
116
+ if (value.carbonError !== undefined && (typeof value.carbonError !== "string" || !value.carbonError.trim() || value.carbon != null)) return null;
106
117
  if (value.rowIds.some((id) => !prices.rows.some((row) => row.code === id))) return null;
107
118
  return value as unknown as PowerEvidence;
108
119
  }
@@ -112,7 +123,10 @@ export const powerScreenshotEvidence: PaneScreenshotEvidenceHook<PowerEvidence>
112
123
  const rows = ["queue", "loads", "capacity"].includes(tab) ? projectRows(board.projects) : otherRows(tab, board, history?.points ?? []);
113
124
  if (value.rowIds.some((id) => !rows.some((r) => r.id === id))) return null;
114
125
  return value as unknown as PowerEvidence;
115
- } catch { return null; }
126
+ } catch {
127
+ // Intentional ignore: invalid captured observations are rejected as evidence by returning null.
128
+ return null;
129
+ }
116
130
  },
117
131
  mismatches(evidence, { resolved, payload }) {
118
132
  const settings = instanceSettings(payload);
@@ -123,7 +137,8 @@ export const powerScreenshotEvidence: PaneScreenshotEvidenceHook<PowerEvidence>
123
137
  } else if (evidence.tab === "prices") {
124
138
  const snapshot = settings?.powerPricesSnapshot;
125
139
  if (!isRecord(snapshot) || JSON.stringify(snapshot.board) !== JSON.stringify(evidence.prices)
126
- || JSON.stringify(snapshot.carbon ?? null) !== JSON.stringify(evidence.carbon ?? null)) errors.push("Power prices differ from the captured data.");
140
+ || JSON.stringify(snapshot.carbon ?? null) !== JSON.stringify(evidence.carbon ?? null)
141
+ || (snapshot.carbonError ?? null) !== (evidence.carbonError ?? null)) errors.push("Power prices differ from the captured data.");
127
142
  } else {
128
143
  const snapshot = settings?.powerSnapshot;
129
144
  if (!isRecord(snapshot) || JSON.stringify(snapshot.board) !== JSON.stringify(evidence.board)
@@ -1,3 +1,4 @@
1
+ import { logFailure } from "../../../utils/log-failure";
1
2
  import { useCallback, useMemo } from "react";
2
3
  import type { GasStorageRow } from "../../../api-client/europe-energy";
3
4
  import {
@@ -99,7 +100,10 @@ export function GasStorageView({ width, height, focused, snapshot }: {
99
100
  const frozen = useMemo(() => {
100
101
  try {
101
102
  return snapshot ? { board: validateGasStorage(snapshot.board), seasonal: snapshot.seasonal ? validateGasSeasonal(snapshot.seasonal) : null } : null;
102
- } catch { return null; }
103
+ } catch (error) {
104
+ logFailure("power.gas", "Validate gas storage snapshot failed")(error);
105
+ return null;
106
+ }
103
107
  }, [snapshot]);
104
108
  const resource = useAsyncResource(frozen ? null : loadGasStorage, { initialData: getCachedGasStorage });
105
109
  const board = frozen?.board ?? resource.data?.payload ?? null;
@@ -1,3 +1,4 @@
1
+ import { logFailure } from "../../../utils/log-failure";
1
2
  import { useCallback, useEffect, useMemo, useRef } from "react";
2
3
  import type { PowerBoard, PowerFilter, PowerHistory } from "../../../api-client/power";
3
4
  import { isAccessDenied } from "../../../api-client/errors";
@@ -8,6 +9,7 @@ import { useAsyncResource, useAutoRefresh, usePaneSettingValue, usePluginAppActi
8
9
  import { useThemeColors } from "../../../theme/theme-context";
9
10
  import type { PaneProps } from "../../../types/plugin";
10
11
  import { Box, Text, TextAttributes, useRendererHost, useUiCapabilities, type ScrollBoxRenderable } from "../../../ui";
12
+ import { withCountryFlag } from "../../../components/ui/country-flag";
11
13
  import { publicTickerKey } from "../../../utils/exchanges";
12
14
  import { getSharedRegistry } from "../../registry/shared";
13
15
  import { usePaneInstance } from "../../../state/app/context";
@@ -86,7 +88,10 @@ function PowerView({ width, height, focused, scope, needsVerification }: PanePro
86
88
  const searchFocus = useQueryBarSearch();
87
89
  const [snapshotSetting] = usePaneSettingValue<{ board: PowerBoard; history?: PowerHistory; tickerScopes?: PowerTickerScope[] } | null>("powerSnapshot", null);
88
90
  const snapshot = useMemo(() => { try { return snapshotSetting ? { board: validatePowerBoard(snapshotSetting.board), history: snapshotSetting.history ? validatePowerHistory(snapshotSetting.history) : undefined,
89
- tickerScopes: Array.isArray(snapshotSetting.tickerScopes) ? snapshotSetting.tickerScopes : null } : null; } catch { return null; } }, [snapshotSetting]);
91
+ tickerScopes: Array.isArray(snapshotSetting.tickerScopes) ? snapshotSetting.tickerScopes : null } : null; } catch (error) {
92
+ logFailure("power.pane", "Validate power snapshot failed")(error);
93
+ return null;
94
+ } }, [snapshotSetting]);
90
95
  const projectTab = ["queue", "loads", "capacity"].includes(tab);
91
96
  const filter = useMemo(() => powerQuery({ tab, country, region, fuel, status, search, historical, context, loadClass, sourceId, from, to,
92
97
  sort: sort.column, direction: sort.direction }, symbol), [tab, country, region, fuel, status, search, historical, context, loadClass, sourceId, from, to, sort.column, sort.direction, symbol]);
@@ -207,6 +212,8 @@ function PowerView({ width, height, focused, scope, needsVerification }: PanePro
207
212
  if (column.id === "status") return { text, color: toneColor(STATUS_TONES[text] ?? "text", colors) };
208
213
  if (column.id === "changeMw" && typeof value === "number") return { text: `${value > 0 ? "+" : ""}${text}`, value, color: signedColor(value, colors) };
209
214
  if (column.id === "ticker") return { text, color: colors.textBright, attributes: state.selected ? 0 : TextAttributes.BOLD };
215
+ // The column has room for the flag beside a code.
216
+ if (column.id === "country") return withCountryFlag({ text, color: colors.textDim }, text, desktop);
210
217
  return { text, value: numeric,
211
218
  color: column.id === "name" || column.id === "utility" || column.id === "capacityMw" || column.id === "requestedMw" ? colors.textBright
212
219
  : ["location", "asOf", "observedAt", "scope", "proposedDate", "region", "country", "kind", "role", "period"].includes(column.id) ? colors.textDim : colors.text };
@@ -1,3 +1,4 @@
1
+ import { logFailure } from "../../../utils/log-failure";
1
2
  import { useCallback, useMemo } from "react";
2
3
  import type { CarbonBoard, PowerPriceRow } from "../../../api-client/europe-energy";
3
4
  import {
@@ -140,15 +141,21 @@ function PowerPriceBoard({ width, height, focused }: { width: number; height: nu
140
141
  const [snapshotSetting] = usePaneSettingValue<PowerPricesSnapshot | null>("powerPricesSnapshot", null);
141
142
  const snapshot = useMemo(() => {
142
143
  try {
144
+ if (snapshotSetting?.carbonError !== undefined && (typeof snapshotSetting.carbonError !== "string"
145
+ || !snapshotSetting.carbonError.trim() || snapshotSetting.carbon != null)) throw new Error("Invalid carbon price failure state.");
143
146
  return snapshotSetting ? { ...snapshotSetting, board: validatePowerPrices(snapshotSetting.board),
144
147
  carbon: snapshotSetting.carbon ? validateCarbonPrice(snapshotSetting.carbon) : null } : null;
145
- } catch { return null; }
148
+ } catch (error) {
149
+ logFailure("power.prices", "Validate power prices snapshot failed")(error);
150
+ return null;
151
+ }
146
152
  }, [snapshotSetting]);
147
153
  const resource = useAsyncResource(snapshot ? null : loadPowerPrices, { initialData: getCachedPowerPrices });
148
154
  const board = snapshot?.board ?? resource.data?.payload ?? null;
149
155
  // The carbon allowance loads beside the board; its failure is a notice, never the board's.
150
156
  const carbonResource = useAsyncResource(snapshot ? null : loadCarbonPrice, { initialData: getCachedCarbonPrice });
151
157
  const carbon = snapshot ? snapshot.carbon : carbonResource.data?.payload ?? null;
158
+ const carbonError = snapshot ? snapshot.carbonError : carbonResource.error;
152
159
  const figures = useMemo(() => carbon ? carbonFigures(carbon) : [], [carbon]);
153
160
  const rows = useMemo(() => board?.rows.map(boardRow) ?? [], [board]);
154
161
  // The band charts the selected market, or the carbon allowance from `c` or EPWR EUA until a market is chosen.
@@ -160,7 +167,7 @@ function PowerPriceBoard({ width, height, focused }: { width: number; height: nu
160
167
  const loaded = useAsyncResource<{ payload: { code: string; points: ReadonlyArray<{ date: string; value: number }> } }>(
161
168
  code && !snapshot ? historyLoader : null, { keepPreviousData: true });
162
169
  const history = snapshot ? { ...loaded, data: snapshot.history ? { payload: snapshot.history } : null, loading: false, error: null } : loaded;
163
- usePowerPricesEvidence(board, carbon, useMemo(() => rows.map((row) => row.id), [rows]), resource.loading || history.loading || carbonResource.loading);
170
+ usePowerPricesEvidence(board, carbon, useMemo(() => rows.map((row) => row.id), [rows]), resource.loading || history.loading || carbonResource.loading, snapshot?.carbonError);
164
171
  useAutoRefresh(resource.updatedAt, resource.load);
165
172
  useAutoRefresh(carbonResource.updatedAt, carbonResource.load);
166
173
  usePaneRefreshKey(() => { void resource.reload(); void history.reload(); void carbonResource.reload(); }, { focused });
@@ -185,7 +192,7 @@ function PowerPriceBoard({ width, height, focused }: { width: number; height: nu
185
192
  error: board ? resource.error ?? (open ? null : history.error) : null, stale: !!resource.data?.stale, hints });
186
193
  usePaneNoticeFooter({ registrationId: "power-prices:notices", focused,
187
194
  notices: [...(board?.gaps ?? []), ...(resource.data?.refreshError ? [resource.data.refreshError] : []),
188
- ...(carbon?.gaps ?? []), ...(board && !carbon && carbonResource.error ? [carbonResource.error] : [])] });
195
+ ...(carbon?.gaps ?? []), ...(board && !carbon && carbonError ? [carbonError] : [])] });
189
196
  return <Box width={width} height={height} flexDirection="column">
190
197
  <PaneStatusBody loading={resource.loading && !board} error={!board && !notAvailable ? resource.error : null}
191
198
  empty={notAvailable} emptyTitle={POWER_PRICES_NOT_AVAILABLE} subject="power prices" width={width} height={height}>
@@ -6,11 +6,15 @@ import type {
6
6
  HeadlessPaneEntry,
7
7
  HeadlessPaneLoadArgs,
8
8
  } from "../../../types/plugin";
9
- import type { AnalystResearchData } from "../../../types/financials";
9
+ import type { AnalystResearchData, Quote } from "../../../types/financials";
10
+ import { logFailure } from "../../../utils/log-failure";
10
11
  import { formatPercent } from "../../../utils/format";
11
12
  import { loadAnalystResearch } from "./client";
12
13
  import {
14
+ analystReferenceMetadata,
13
15
  analystTargetCurrency,
16
+ analystUpside,
17
+ formatAnalystReference,
14
18
  formatAnalystPrice,
15
19
  formatRecommendationMix,
16
20
  recommendationMix,
@@ -18,7 +22,6 @@ import {
18
22
  formatRatingTarget,
19
23
  recommendationTotal,
20
24
  sortRatingRows,
21
- targetUpside,
22
25
  type RatingColumnId,
23
26
  } from "./analyst-model";
24
27
  import { REPORTED_DATA } from "../shared/report-freshness";
@@ -48,10 +51,11 @@ const SORT_COLUMNS: Record<string, RatingColumnId> = {
48
51
  target: "target",
49
52
  };
50
53
 
51
- function overviewEntries(data: AnalystResearchData): HeadlessPaneEntry[] {
54
+ /** The summary: the upside from Last (the quote's regular session price), and the price and time it is measured from, as `analyst` gives them. */
55
+ function overviewEntries(data: AnalystResearchData, quote: Quote | null): HeadlessPaneEntry[] {
52
56
  const target = data.priceTarget;
53
57
  const currency = analystTargetCurrency(data);
54
- const upside = targetUpside(target);
58
+ const { upside, reference } = analystUpside(data, quote);
55
59
  return [
56
60
  {
57
61
  label: "Average target",
@@ -65,8 +69,8 @@ function overviewEntries(data: AnalystResearchData): HeadlessPaneEntry[] {
65
69
  },
66
70
  {
67
71
  label: "Upside reference price",
68
- value: target?.current ?? null,
69
- formatted: formatAnalystPrice(target?.current, currency),
72
+ value: reference.price ?? null,
73
+ formatted: formatAnalystReference(reference, currency),
70
74
  },
71
75
  {
72
76
  label: "Target range",
@@ -97,6 +101,8 @@ export interface AnalystResearchHeadlessDependencies {
97
101
  args: HeadlessPaneLoadArgs,
98
102
  ctx: HeadlessPaneContext,
99
103
  ): Promise<AnalystResearchData>;
104
+ /** The listing's quote, whose regular session price the upside is measured from; null when none loads. */
105
+ loadQuote?(symbol: string, ctx: HeadlessPaneContext): Promise<Quote | null>;
100
106
  }
101
107
 
102
108
  const defaultDependencies: AnalystResearchHeadlessDependencies = {
@@ -104,6 +110,11 @@ const defaultDependencies: AnalystResearchHeadlessDependencies = {
104
110
  const instrument = await ctx.resolveInstrument?.(symbol);
105
111
  return loadAnalystResearch(ctx.marketData, symbol, instrument?.exchange);
106
112
  },
113
+ async loadQuote(symbol, ctx) {
114
+ const instrument = await ctx.resolveInstrument?.(symbol);
115
+ return ctx.marketData.getQuote(instrument?.symbol ?? symbol, instrument?.exchange ?? "")
116
+ .catch(logFailure("analyst", "Read the quote the upside is measured from failed", null));
117
+ },
107
118
  };
108
119
 
109
120
  export function createAnalystResearchHeadless(
@@ -148,7 +159,11 @@ export function createAnalystResearchHeadless(
148
159
  describe: (args) => `Analyst Research | ${args.symbols[0]}`,
149
160
  async load(args, ctx) {
150
161
  const symbol = args.symbols[0]!;
151
- const data = await dependencies.loadData(symbol, args, ctx);
162
+ const [data, quote] = await Promise.all([
163
+ dependencies.loadData(symbol, args, ctx),
164
+ dependencies.loadQuote?.(symbol, ctx) ?? Promise.resolve(null),
165
+ ]);
166
+ const { upside, reference } = analystUpside(data, quote);
152
167
  const currency = analystTargetCurrency(data);
153
168
  const ratings = sortRatingRows(data.ratings, {
154
169
  columnId: SORT_COLUMNS[String(args.options.sort)] ?? "date",
@@ -161,7 +176,7 @@ export function createAnalystResearchHeadless(
161
176
  currency: currency ?? null,
162
177
  }));
163
178
  const sections: HeadlessBundleSection[] = [
164
- { title: "Summary", entries: overviewEntries(data) },
179
+ { title: "Summary", entries: overviewEntries(data, quote) },
165
180
  { title: "Recent analyst actions", columns: RATING_COLUMNS, rows: ratings },
166
181
  ];
167
182
  return {
@@ -174,6 +189,8 @@ export function createAnalystResearchHeadless(
174
189
  currency: currency ?? null,
175
190
  fetchedAt: data.fetchedAt,
176
191
  stale: data.stale,
192
+ upside: upside ?? null,
193
+ upsideReference: analystReferenceMetadata(reference),
177
194
  },
178
195
  };
179
196
  },
@@ -6,7 +6,9 @@ import { displayWidth, formatCurrency, formatNumber } from "../../../utils/forma
6
6
  import { compareSortValues, type SortDirection } from "../../../utils/sort-values";
7
7
  import { loadingErrorFooterInfo } from "../../../components/data-table/table-pane";
8
8
  import { delayedFooterSegment } from "../../../components/layout/pane/footer/model";
9
- import { regularSessionValuationPrice } from "../../../market-data/quotes/regular-session-valuation";
9
+ import { regularSessionValuationPrice, regularSessionValuationTime } from "../../../market-data/quotes/regular-session-valuation";
10
+ import { getCompletedRegularSessionDisplay } from "../../../market-data/market/status";
11
+ import { formatUtcDayTime, parseReportTime, type ReportTime } from "../../../utils/utc-time";
10
12
 
11
13
  function compactPeriod(period: string): string {
12
14
  return period
@@ -32,6 +34,15 @@ export interface AnalystReferencePrice {
32
34
  /** What the price is when it is the live quote, such as `real-time` or `15m delayed`. */
33
35
  freshness: string | null;
34
36
  live: boolean;
37
+ /**
38
+ * When the price is from: a live quote's regular session close once that session is over, else the quote's own
39
+ * time (regularSessionValuationTime); the provider's reference from when the research was fetched. Null unknown.
40
+ */
41
+ time?: ReportTime | null;
42
+ /** The live price is a completed session's close. */
43
+ close?: boolean;
44
+ /** The exchange-local date of that session, when the quote names it. */
45
+ sessionDate?: string;
35
46
  }
36
47
 
37
48
  function quoteFreshness(quote: Quote): string | null {
@@ -51,12 +62,62 @@ export function analystReferencePrice(
51
62
  data: AnalystResearchData | null,
52
63
  quote: Quote | null | undefined,
53
64
  ): AnalystReferencePrice {
54
- const fallback = { price: data?.priceTarget?.current, freshness: null, live: false };
65
+ const fallback = { price: data?.priceTarget?.current, freshness: null, live: false, time: parseReportTime(data?.fetchedAt), close: false };
55
66
  const currency = analystTargetCurrency(data);
56
67
  const price = regularSessionValuationPrice(quote);
57
68
  if (!quote || quote.stale || !currency || price == null) return fallback;
58
69
  if (quote.currency?.trim() !== currency) return fallback;
59
- return { price, freshness: quoteFreshness(quote), live: true };
70
+ return {
71
+ price, freshness: quoteFreshness(quote), live: true,
72
+ time: regularSessionValuationTime(quote), close: getCompletedRegularSessionDisplay(quote) != null,
73
+ ...(quote.regularCloseSessionDate ? { sessionDate: quote.regularCloseSessionDate } : {}),
74
+ };
75
+ }
76
+
77
+ /**
78
+ * The upside and what it is measured from, as `analyst`, `fn ANR` and the ANR
79
+ * pane read it: the average target over Last (the quote's regular session
80
+ * price, as `valuation` and RV show it), or the provider's reference price when
81
+ * no quote in the target's currency stands (analystReferencePrice).
82
+ */
83
+ export function analystUpside(data: AnalystResearchData | null, quote: Quote | null | undefined) {
84
+ const reference = analystReferencePrice(data, quote);
85
+ return { upside: targetUpside(data?.priceTarget, reference.price), reference };
86
+ }
87
+
88
+ /** The reference an upside is measured from, for JSON: the price, when it is from, and whose it is. */
89
+ export function analystReferenceMetadata(reference: AnalystReferencePrice) {
90
+ const time = reference.time;
91
+ return {
92
+ price: reference.price ?? null,
93
+ asOf: time ? (time.dateOnly ? new Date(time.time).toISOString().slice(0, 10) : new Date(time.time).toISOString()) : null,
94
+ basis: !reference.live ? "provider reference at retrieval" : reference.close ? "regular session close" : "regular session price",
95
+ ...(reference.freshness ? { freshness: reference.freshness } : {}),
96
+ };
97
+ }
98
+
99
+ /** When a reference price is from, in the words a change line uses: "Thu 22 Oct close" or a print's time. */
100
+ function analystReferenceWhen(reference: AnalystReferencePrice, now: number): string {
101
+ const at = (time: ReportTime) => formatUtcDayTime(time, now) + (time.dateOnly ? "" : " UTC");
102
+ if (reference.live && reference.close) {
103
+ const day = reference.sessionDate ? { time: Date.parse(`${reference.sessionDate}T00:00:00Z`), dateOnly: true }
104
+ : reference.time ? { ...reference.time, dateOnly: true } : null;
105
+ return day ? `${at(day)} close` : "close";
106
+ }
107
+ return reference.time ? at(reference.time) : "";
108
+ }
109
+
110
+ /**
111
+ * The price an upside is measured from and when it is from: "$141.39, Thu 22 Oct close", "$141.39, Fri 23 Oct
112
+ * 14:05 UTC (15m delayed)" while the session trades, or the provider's reference, "$137.32, provider reference at
113
+ * retrieval Wed 21 Oct 21:30 UTC".
114
+ */
115
+ export function formatAnalystReference(reference: AnalystReferencePrice, currency: string | undefined, now = Date.now()): string {
116
+ if (reference.price == null || !Number.isFinite(reference.price)) return "-";
117
+ const price = formatAnalystPrice(reference.price, currency);
118
+ const when = analystReferenceWhen(reference, now);
119
+ if (!reference.live) return `${price}, provider reference${when ? ` at retrieval ${when}` : ""}`;
120
+ return `${price}${when ? `, ${when}` : ""}${reference.freshness && !reference.close ? ` (${reference.freshness})` : ""}`;
60
121
  }
61
122
 
62
123
  function isCurrentMonthPeriod(period: string | undefined): boolean {
@@ -340,6 +401,7 @@ export function buildAnalystFooterInfo(
340
401
  export function buildAnalystStatusSegments(
341
402
  data: AnalystResearchData | null,
342
403
  reference: AnalystReferencePrice = analystReferencePrice(data, null),
404
+ now = Date.now(),
343
405
  ): PaneFooterSegment[] {
344
406
  if (!data) return [];
345
407
 
@@ -372,11 +434,14 @@ export function buildAnalystStatusSegments(
372
434
  if (reference.price != null) {
373
435
  // A delayed price is the footer's clock beside it; a real-time one says so in words.
374
436
  const delay = reference.freshness?.endsWith(" delayed") ? reference.freshness.slice(0, -" delayed".length) : null;
437
+ const when = !reference.live ? "provider ref" : reference.close ? analystReferenceWhen(reference, now) : null;
375
438
  segments.push({
376
439
  id: "analyst-reference-price",
377
440
  parts: [
378
441
  { text: "upside vs", tone: "label" },
379
442
  { text: price(reference.price) },
443
+ // When it is from, as `analyst` and `fn ANR` print it: "Thu 22 Oct close" or the provider's reference.
444
+ ...(when ? [{ text: when, tone: "muted" as const }] : []),
380
445
  ...(reference.freshness && !delay ? [{ text: reference.freshness, tone: "muted" as const }] : []),
381
446
  ],
382
447
  });