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
@@ -10,30 +10,62 @@ import { signedInBrokerForProfile } from "../../../brokers/signed-in/connect";
10
10
  import { isSignedInBrokerProfile } from "../../../brokers/signed-in/profile";
11
11
  import { requestBrokerSignIn } from "../../../brokers/signed-in/sign-in-dialog";
12
12
  import { confirmDialog } from "../../../components";
13
+ import { useRowNotes } from "../../../components/ui/row-notes";
13
14
  import { openConfirmModal } from "../../../components/form-modal";
14
15
  import { useAppGetState } from "../../../state/app/context";
15
16
  import type { BrokerProfileAction } from "../../../types/broker";
16
17
  import { useDialog } from "../../../ui/dialog";
17
18
  import { t, tf } from "../../../i18n";
18
19
  import { usePluginAppActions, usePluginBrokerActions } from "../../runtime";
20
+ import { enableBrokerProfile } from "../shared/broker-reconnect";
19
21
  import type { BrokerEditKey } from "./detail";
20
22
  import { neighbourBrokerProfileId, type BrokerProfileRow } from "./model";
21
23
 
22
- /** The last action's result. Errors also replace the profile status in the detail. */
24
+ /**
25
+ * A result that is the whole pane's, said in its footer: the add flow's, which
26
+ * has no row yet, or a request the pane turned down.
27
+ */
23
28
  export interface BrokerManagerMessage {
24
29
  tone: "info" | "error";
25
30
  text: string;
26
31
  }
27
32
 
28
- function infoMessage(text: string): BrokerManagerMessage {
29
- return { tone: "info", text };
33
+ /**
34
+ * What the last action on one profile came to, said on its row: `status` in
35
+ * its STATUS, `text` in its detail, in place of the profile's own status
36
+ * message. It stands until the next action on the profile, or until the
37
+ * profile's own status or sync moves on past it.
38
+ */
39
+ export interface BrokerRowNote {
40
+ tone: "info" | "error";
41
+ text: string;
42
+ /** A failure's short state for STATUS, "Sync failed"; none keeps the row's own state. */
43
+ status?: string;
44
+ }
45
+
46
+ /**
47
+ * The parts of a row a real change moves: its state, its status message and
48
+ * when it last synced. Not the status's `updatedAt`, which an adapter may
49
+ * stamp on every read, nor a sign-in's end, which the pane reads on its own.
50
+ */
51
+ function rowSignature(row: BrokerProfileRow): string {
52
+ return [row.state, row.stateLabel, row.message, row.lastSyncedAt].join("\0");
30
53
  }
54
+ const rowKey = (row: BrokerProfileRow) => row.id;
31
55
 
32
- function errorMessage(error: unknown, fallback: string): BrokerManagerMessage {
33
- return { tone: "error", text: error instanceof Error ? error.message : fallback };
56
+ /** What a row shows of the pane's own work on it. */
57
+ export interface BrokerRowActivity {
58
+ /** The action running on the profile: "Syncing…". */
59
+ busy?: string | null;
60
+ note?: BrokerRowNote | null;
61
+ }
62
+
63
+ function errorText(error: unknown, fallback: string): string {
64
+ return error instanceof Error && error.message ? error.message : fallback;
34
65
  }
35
66
 
36
67
  export function useBrokerManagerActions({
68
+ rows,
37
69
  selectedRow,
38
70
  editDraft,
39
71
  setEditDraft,
@@ -42,6 +74,7 @@ export function useBrokerManagerActions({
42
74
  setSelectedId,
43
75
  refreshStatuses,
44
76
  }: {
77
+ rows: readonly BrokerProfileRow[];
45
78
  selectedRow: BrokerProfileRow | null;
46
79
  editDraft: BrokerProfileDraft | null;
47
80
  setEditDraft: Dispatch<SetStateAction<BrokerProfileDraft | null>>;
@@ -59,39 +92,66 @@ export function useBrokerManagerActions({
59
92
  syncBrokerInstance,
60
93
  removeBrokerInstance,
61
94
  } = usePluginBrokerActions();
62
- const [busy, setBusy] = useState<string | null>(null);
95
+ // The running action and the profile it is on; none for the add flow's.
96
+ const [busyState, setBusyState] = useState<{ text: string; profileId: string | null } | null>(null);
97
+ const setBusy = useCallback((text: string | null, profileId: string | null = null) => {
98
+ setBusyState(text ? { text, profileId } : null);
99
+ }, []);
100
+ const busy = busyState?.text ?? null;
63
101
  const [message, setMessage] = useState<BrokerManagerMessage | null>(null);
102
+ // What stops the open edit form from saving, said beside its Save.
103
+ const [editError, setEditError] = useState<string | null>(null);
104
+ // A note takes the row as it is when the note first shows, with the status
105
+ // the failure left, and goes when that row moves on: a new state, message or sync.
106
+ const { noteFor, setNote: setRowNote } = useRowNotes<BrokerProfileRow, BrokerRowNote>(rows, { key: rowKey, signature: rowSignature });
107
+ /** Starts an action on a profile: its row says so, in place of the last one's result. */
108
+ const startRowAction = useCallback((profileId: string, text: string) => {
109
+ setRowNote(profileId, null);
110
+ setBusy(text, profileId);
111
+ }, [setBusy, setRowNote]);
112
+ const rowActivity = useCallback((row: BrokerProfileRow): BrokerRowActivity => ({
113
+ busy: busyState?.profileId === row.id ? busyState.text : null,
114
+ note: noteFor(row),
115
+ }), [busyState, noteFor]);
64
116
 
65
117
  const startEdit = useCallback(() => {
66
- if (!selectedRow?.adapter) {
67
- setMessage({ tone: "error", text: t("Broker plugin is not available.") });
68
- return;
69
- }
118
+ if (!selectedRow?.adapter) return;
70
119
  const draft = createBrokerProfileDraft(selectedRow.adapter, selectedRow.instance);
71
120
  for (const field of selectedRow.adapter.configSchema) {
72
121
  if (field.type === "password" && draft.values[field.key]) draft.values[field.key] = "";
73
122
  }
74
123
  setEditDraft(draft);
75
124
  setActiveEditKey("label");
125
+ setEditError(null);
76
126
  setMessage(null);
77
127
  setDetailOpen(true);
78
128
  }, [selectedRow, setActiveEditKey, setDetailOpen, setEditDraft]);
79
129
 
130
+ // The form goes, and what it said with it.
131
+ const cancelEdit = useCallback(() => {
132
+ setEditDraft(null);
133
+ setEditError(null);
134
+ setMessage(null);
135
+ }, [setEditDraft]);
136
+
137
+ // What stops a save is about the open form, so it is said beside its Save, not on the row.
80
138
  const saveEdit = useCallback(async () => {
81
139
  if (!selectedRow?.adapter || !editDraft) return;
140
+ setMessage(null);
82
141
  const label = editDraft.label.trim();
83
142
  if (!label) {
84
- setMessage({ tone: "error", text: t("Profile label is required.") });
143
+ setEditError(t("Profile label is required."));
85
144
  return;
86
145
  }
87
146
  const validationError = validateBrokerProfileValues(selectedRow.adapter, editDraft.values, selectedRow.instance);
88
147
  if (validationError) {
89
- setMessage({ tone: "error", text: validationError });
148
+ setEditError(validationError);
90
149
  return;
91
150
  }
151
+ setEditError(null);
92
152
 
93
153
  try {
94
- setBusy(t("Saving…"));
154
+ startRowAction(selectedRow.id, t("Saving…"));
95
155
  const nextConfig = buildBrokerProfileConfig(selectedRow.adapter, editDraft.values, selectedRow.instance);
96
156
  const wasEnabled = selectedRow.adapter.getTradingCapabilities?.(selectedRow.instance).enabled === true;
97
157
  const willEnable = selectedRow.adapter.getTradingCapabilities?.({ ...selectedRow.instance, config: nextConfig }).enabled === true;
@@ -105,67 +165,106 @@ export function useBrokerManagerActions({
105
165
  localOnly: editDraft.localOnly,
106
166
  replaceConfig: true,
107
167
  });
168
+ // The row shows the saved profile.
108
169
  setEditDraft(null);
109
- setMessage(infoMessage(tf("Saved {label}.", { label })));
110
170
  } catch (error) {
111
- setMessage(errorMessage(error, t("Failed to save broker profile.")));
171
+ setEditError(errorText(error, t("Failed to save broker profile.")));
112
172
  } finally {
113
173
  setBusy(null);
114
174
  }
115
- }, [dialog, editDraft, selectedRow, setEditDraft, updateBrokerInstance]);
175
+ }, [dialog, editDraft, selectedRow, setBusy, setEditDraft, startRowAction, updateBrokerInstance]);
116
176
 
117
177
  const connectSelected = useCallback(async () => {
118
178
  if (!selectedRow) return;
119
179
  if (isSignedInBrokerProfile(selectedRow.instance)) {
120
180
  // Connecting happens in the browser, then the profile syncs what it can now see.
121
181
  const broker = signedInBrokerForProfile(selectedRow.instance, selectedRow.brokerName);
182
+ const { id, label } = selectedRow;
183
+ startRowAction(id, t("Connecting…"));
122
184
  try {
123
- setBusy(t("Connecting…"));
124
185
  // A connected broker is connected again only by a new sign-in: this renews it before the broker ends it.
125
186
  // A row that says when the sign-in ends is renewable before this session's first sync too.
126
187
  const renew = selectedRow.state === "connected" || selectedRow.signInEndsAt !== null;
127
- if (!await requestBrokerSignIn(broker, { renew })) {
188
+ let signedIn: boolean;
189
+ try {
190
+ signedIn = await requestBrokerSignIn(broker, { renew });
191
+ } catch (error) {
192
+ setRowNote(id, {
193
+ tone: "error",
194
+ status: t("Sign-in failed"),
195
+ text: errorText(error, tf("{broker} was not connected.", { broker: broker.name })),
196
+ });
197
+ return;
198
+ }
199
+ if (!signedIn) {
128
200
  // Backing out of a renewal leaves the broker connected, for now.
129
- setMessage(infoMessage(renew
130
- ? tf("{broker} sign-in was not renewed.", { broker: broker.name })
131
- : tf("{broker} was not connected.", { broker: broker.name })));
201
+ setRowNote(id, {
202
+ tone: "info",
203
+ text: renew
204
+ ? tf("{broker} sign-in was not renewed.", { broker: broker.name })
205
+ : tf("{broker} was not connected.", { broker: broker.name }),
206
+ });
132
207
  return;
133
208
  }
134
- await syncBrokerInstance(selectedRow.id);
209
+ try {
210
+ await syncBrokerInstance(id);
211
+ } catch (error) {
212
+ setRowNote(id, { tone: "error", status: t("Sync failed"), text: errorText(error, tf("Failed to sync {label}.", { label })) });
213
+ }
135
214
  refreshStatuses();
136
- setMessage(infoMessage(tf("Connected {broker}.", { broker: broker.name })));
137
- } catch (error) {
138
- setMessage(errorMessage(error, tf("Failed to sync {label}.", { label: selectedRow.label })));
139
215
  } finally {
140
216
  setBusy(null);
141
217
  }
142
218
  return;
143
219
  }
220
+ const { id, label } = selectedRow;
144
221
  try {
145
- setBusy(t("Testing…"));
146
- await connectBrokerInstance(selectedRow.id);
222
+ startRowAction(id, t("Testing…"));
223
+ await connectBrokerInstance(id);
147
224
  refreshStatuses();
148
- setMessage(infoMessage(tf("Tested {label}.", { label: selectedRow.label })));
149
225
  } catch (error) {
150
- setMessage(errorMessage(error, tf("Failed to test {label}.", { label: selectedRow.label })));
226
+ setRowNote(id, { tone: "error", status: t("Connect failed"), text: errorText(error, tf("Failed to test {label}.", { label })) });
151
227
  } finally {
152
228
  setBusy(null);
153
229
  }
154
- }, [connectBrokerInstance, refreshStatuses, selectedRow, syncBrokerInstance]);
230
+ }, [connectBrokerInstance, refreshStatuses, selectedRow, setBusy, setRowNote, startRowAction, syncBrokerInstance]);
231
+
232
+ // A disabled profile is never connected or synced; b turns it back on, then syncs it.
233
+ const enableSelected = useCallback(async () => {
234
+ if (!selectedRow || selectedRow.instance.enabled !== false) return;
235
+ const { id, label } = selectedRow;
236
+ try {
237
+ startRowAction(id, t("Enabling…"));
238
+ const failure = await enableBrokerProfile({ updateBrokerInstance, syncBrokerInstance }, id, {
239
+ sync: !!selectedRow.adapter,
240
+ label,
241
+ });
242
+ if (failure) {
243
+ setRowNote(id, {
244
+ tone: "error",
245
+ status: failure.step === "enable" ? t("Enable failed") : t("Sync failed"),
246
+ text: failure.text,
247
+ });
248
+ }
249
+ refreshStatuses();
250
+ } finally {
251
+ setBusy(null);
252
+ }
253
+ }, [refreshStatuses, selectedRow, setBusy, setRowNote, startRowAction, syncBrokerInstance, updateBrokerInstance]);
155
254
 
156
255
  const syncSelected = useCallback(async () => {
157
256
  if (!selectedRow) return;
257
+ const { id, label } = selectedRow;
158
258
  try {
159
- setBusy(t("Syncing…"));
160
- await syncBrokerInstance(selectedRow.id);
259
+ startRowAction(id, t("Syncing…"));
260
+ await syncBrokerInstance(id);
161
261
  refreshStatuses();
162
- setMessage(infoMessage(tf("Synced {label}.", { label: selectedRow.label })));
163
262
  } catch (error) {
164
- setMessage(errorMessage(error, tf("Failed to sync {label}.", { label: selectedRow.label })));
263
+ setRowNote(id, { tone: "error", status: t("Sync failed"), text: errorText(error, tf("Failed to sync {label}.", { label })) });
165
264
  } finally {
166
265
  setBusy(null);
167
266
  }
168
- }, [refreshStatuses, selectedRow, syncBrokerInstance]);
267
+ }, [refreshStatuses, selectedRow, setBusy, setRowNote, startRowAction, syncBrokerInstance]);
169
268
 
170
269
  const selectedProfileActions = useMemo(
171
270
  () => selectedRow?.adapter?.getProfileActions?.(selectedRow.instance) ?? [],
@@ -176,33 +275,53 @@ export function useBrokerManagerActions({
176
275
  const openProfileAction = useCallback((action: BrokerProfileAction | null = primaryProfileAction) => {
177
276
  if (!action) return;
178
277
  if (action.disabled) {
179
- setMessage(infoMessage(action.disabledReason ?? tf("{action} is unavailable for this profile.", { action: t(action.label) })));
278
+ if (selectedRow) {
279
+ setRowNote(selectedRow.id, {
280
+ tone: "info",
281
+ text: action.disabledReason ?? tf("{action} is unavailable for this profile.", { action: t(action.label) }),
282
+ });
283
+ }
180
284
  return;
181
285
  }
182
286
  if (action.paneId) showPane(action.paneId);
183
- }, [primaryProfileAction, showPane]);
287
+ }, [primaryProfileAction, selectedRow, setRowNote, showPane]);
184
288
 
185
289
  const removeSelected = useCallback(() => {
186
290
  if (!selectedRow) return;
187
291
  const { id, brokerName, label } = selectedRow;
188
- const confirm = brokerProfileRemovalConfirm(selectedRow.instance, brokerName, async () => {
189
- // Read when confirmed: the profile can change, or go, while the confirm is open.
190
- const instances = getState().config.brokerInstances;
191
- const instance = instances.find((entry) => entry.id === id);
192
- if (!instance) return;
193
- const nextSelectedId = neighbourBrokerProfileId(instances, id);
194
- try {
195
- setBusy(t("Disconnecting…"));
196
- const removal = await removeBrokerProfile(instance, brokerName, removeBrokerInstance);
197
- setEditDraft(null);
198
- setDetailOpen(false);
199
- setSelectedId(nextSelectedId);
200
- setMessage(null);
201
- notify({ body: removal.message, type: removal.accountKept ? "info" : "success" });
202
- } finally {
203
- setBusy(null);
204
- }
205
- });
292
+ // A removal that failed is said on the profile's row while it has one.
293
+ // Once the row is gone, only a toast can say it.
294
+ const listed = () => getState().config.brokerInstances.some((entry) => entry.id === id);
295
+ const failureText = (error: unknown) => errorText(error, tf("Failed to remove {label}.", { label }));
296
+ const toastIfGone = (error: unknown) => {
297
+ if (!listed()) notify({ body: failureText(error), type: "error" });
298
+ };
299
+ const confirm = {
300
+ ...brokerProfileRemovalConfirm(selectedRow.instance, brokerName, async () => {
301
+ // Read when confirmed: the profile can change, or go, while the confirm is open.
302
+ const instances = getState().config.brokerInstances;
303
+ const instance = instances.find((entry) => entry.id === id);
304
+ if (!instance) return;
305
+ const nextSelectedId = neighbourBrokerProfileId(instances, id);
306
+ try {
307
+ startRowAction(id, t("Disconnecting…"));
308
+ const removal = await removeBrokerProfile(instance, brokerName, removeBrokerInstance);
309
+ setEditDraft(null);
310
+ setDetailOpen(false);
311
+ setSelectedId(nextSelectedId);
312
+ setRowNote(id, null);
313
+ setMessage(null);
314
+ notify({ body: removal.message, type: removal.accountKept ? "info" : "success" });
315
+ } catch (error) {
316
+ // An open confirm says it inline too; the row keeps it once that closes.
317
+ if (listed()) setRowNote(id, { tone: "error", status: t("Remove failed"), text: failureText(error) });
318
+ throw error;
319
+ } finally {
320
+ setBusy(null);
321
+ }
322
+ }),
323
+ onFailureAfterClose: toastIfGone,
324
+ };
206
325
  if (openConfirmModal(confirm)) return;
207
326
  // A detached window has no confirm modal; its own dialog asks instead.
208
327
  void (async () => {
@@ -216,19 +335,26 @@ export function useBrokerManagerActions({
216
335
  try {
217
336
  await confirm.onConfirm();
218
337
  } catch (error) {
219
- setMessage(errorMessage(error, tf("Failed to remove {label}.", { label })));
338
+ toastIfGone(error);
220
339
  }
221
340
  })();
222
- }, [dialog, getState, notify, removeBrokerInstance, selectedRow, setDetailOpen, setEditDraft, setSelectedId]);
341
+ }, [dialog, getState, notify, removeBrokerInstance, selectedRow, setBusy, setDetailOpen, setEditDraft, setRowNote, setSelectedId, startRowAction]);
223
342
 
224
343
  return {
225
344
  busy,
345
+ /** The add flow's running action, which has no row to show it on. */
346
+ paneBusy: busyState && busyState.profileId === null ? busyState.text : null,
226
347
  message,
348
+ editError,
349
+ rowActivity,
227
350
  setBusy,
228
351
  setMessage,
352
+ setRowNote,
229
353
  startEdit,
354
+ cancelEdit,
230
355
  saveEdit,
231
356
  connectSelected,
357
+ enableSelected,
232
358
  syncSelected,
233
359
  selectedProfileActions,
234
360
  primaryProfileAction,
@@ -5,18 +5,21 @@ import type { DataTableCell, DataTableColumn } from "../../../components";
5
5
  import { colors } from "../../../theme/colors";
6
6
  import { formatRelativeAge } from "../../../utils/datetime-format";
7
7
  import type { BrokerDisplayState, BrokerProfileRow } from "./model";
8
+ import type { BrokerRowActivity } from "./pane-actions";
8
9
  import { t } from "../../../i18n";
9
10
  import { signInEndStatus } from "./sign-in-end";
10
11
 
11
12
  type BrokerColumnId = "profile" | "status" | "broker" | "mode" | "accounts" | "updated";
12
13
  export type BrokerColumn = DataTableColumn & { id: BrokerColumnId };
13
14
 
14
- export function stateColor(state: BrokerDisplayState): string {
15
+ function stateColor(state: BrokerDisplayState): string {
15
16
  switch (state) {
16
17
  case "connected": return colors.positive;
17
18
  case "connecting": return colors.warning;
18
19
  case "error": return colors.negative;
19
- case "disabled": return colors.textMuted;
20
+ // Nothing syncs these until the user steps in.
21
+ case "sign-in": return colors.warning;
22
+ case "disabled": return colors.warning;
20
23
  case "unavailable": return colors.negative;
21
24
  default: return colors.textDim;
22
25
  }
@@ -29,7 +32,8 @@ export function buildBrokerColumns(width: number): BrokerColumn[] {
29
32
  // PROFILE takes whatever the fixed columns leave; the kit spreads it.
30
33
  return [
31
34
  { id: "profile", label: t("PROFILE"), width: 14, align: "left", flexGrow: 1 },
32
- { id: "status", label: t("STATUS"), width: 12, align: "left" },
35
+ // Holds "Sign-in needed" and "Connect failed".
36
+ { id: "status", label: t("STATUS"), width: 14, align: "left" },
33
37
  { id: "broker", label: t("BROKER"), width: width >= 110 ? 20 : 16, align: "left" },
34
38
  ...(width >= MODE_COLUMN_MIN_WIDTH
35
39
  ? [{ id: "mode" as const, label: t("MODE"), width: 11, align: "left" as const }]
@@ -39,8 +43,27 @@ export function buildBrokerColumns(width: number): BrokerColumn[] {
39
43
  ];
40
44
  }
41
45
 
46
+ /**
47
+ * What a profile's STATUS says, in the table and atop its detail: the action
48
+ * running on it, then the one that just failed on it, then a sign-in the
49
+ * broker is about to end, then its own state ("Disabled", "Sign-in needed").
50
+ */
51
+ export function brokerRowStatus(row: BrokerProfileRow, activity: BrokerRowActivity = {}): { text: string; color: string } {
52
+ if (activity.busy) return { text: activity.busy, color: colors.warning };
53
+ // A sign-in the broker wants says more than which step ran into it.
54
+ if (activity.note?.status && row.state !== "sign-in") return { text: activity.note.status, color: colors.negative };
55
+ // A sign-in the broker is about to end replaces "Connected" until it is renewed.
56
+ if (row.signInEndsAt !== null) return { text: signInEndStatus(row.signInEndsAt), color: colors.warning };
57
+ return { text: row.stateLabel, color: stateColor(row.state) };
58
+ }
59
+
42
60
  /** `desktop`: the profile leads with its broker's logo, which the terminal does not draw. */
43
- export function renderBrokerCell(row: BrokerProfileRow, column: BrokerColumn, desktop = false): DataTableCell {
61
+ export function renderBrokerCell(
62
+ row: BrokerProfileRow,
63
+ column: BrokerColumn,
64
+ desktop = false,
65
+ activity: BrokerRowActivity = {},
66
+ ): DataTableCell {
44
67
  switch (column.id) {
45
68
  case "profile":
46
69
  return {
@@ -50,14 +73,7 @@ export function renderBrokerCell(row: BrokerProfileRow, column: BrokerColumn, de
50
73
  leading: desktop ? createElement(LogoMark, { src: row.logo, name: row.brokerName }) : undefined,
51
74
  };
52
75
  case "status":
53
- // A sign-in the broker is about to end replaces "Connected" until it is renewed.
54
- if (row.signInEndsAt !== null) {
55
- return { text: signInEndStatus(row.signInEndsAt), color: colors.warning };
56
- }
57
- return {
58
- text: row.stateLabel,
59
- color: stateColor(row.state),
60
- };
76
+ return brokerRowStatus(row, activity);
61
77
  case "broker":
62
78
  return { text: row.brokerName, color: colors.textDim };
63
79
  case "mode":
@@ -1,3 +1,4 @@
1
+ import { logFailure } from "../../../utils/log-failure";
1
2
  import { useCallback, useImperativeHandle, useMemo, useRef, useState, type Ref } from "react";
2
3
  import { Badge, Button, DialogFrame, DisclosureMarker, ListView, type SelectControl } from "../../../components";
3
4
  import { listCursorMove } from "../../../components/ui/list-view";
@@ -78,7 +79,7 @@ export function BrokerAccountPicker({ accounts, value, onChange, disabled = fals
78
79
  if (disabled || opened.current || !choices.length) return;
79
80
  opened.current = true;
80
81
  void dialog.prompt<string>({ closeOnClickOutside: true, style: { width: 72 }, content: (context) => <BrokerAccountChoiceDialog {...context} accounts={choices} value={value} /> })
81
- .then((next) => choose.current(next)).catch(() => {}).finally(() => { opened.current = false; });
82
+ .then((next) => choose.current(next)).catch(logFailure("broker-trading.account-picker", "Choose broker account failed")).finally(() => { opened.current = false; });
82
83
  }, [choices, dialog, disabled, value]);
83
84
  useImperativeHandle(controlRef, () => ({ open }), [open]);
84
85
  return <Button label="Choose account" variant="quiet" flush active={active} disabled={disabled || !choices.length} width={width} onPress={open} stopPropagation>
@@ -1,10 +1,11 @@
1
1
  import type { CompositeChartLevel } from "../../../components/chart/composite/levels";
2
2
  import type { ThemeColors } from "../../../theme/colors";
3
3
  import type { BrokerContractRef } from "../../../types/instrument";
4
- import type { BrokerOrder, BrokerOrderRequest } from "../../../types/trading";
4
+ import type { BrokerOrder, BrokerOrderRequest, BrokerTradingCapabilities } from "../../../types/trading";
5
5
  import { brokerOrderKey, brokerOrderStatus, canChangeBrokerOrder, ticketEditingPriceStep, withLatestOrder } from "./orders-data";
6
6
  import { sameBrokerContract } from "../../../utils/instrument-identity";
7
7
  import { isStrategyOrder } from "./strategy";
8
+ import { linkRoleName } from "./linked-orders";
8
9
 
9
10
  export function ticketOrderMatches(order: Pick<BrokerOrder, "accountId" | "brokerInstanceId" | "contract" | "legs">, contract: BrokerContractRef, profileId: string, accountId?: string): boolean {
10
11
  if (!accountId || order.accountId !== accountId || order.brokerInstanceId && order.brokerInstanceId !== profileId
@@ -19,9 +20,54 @@ export function ticketOrderMatches(order: Pick<BrokerOrder, "accountId" | "broke
19
20
  return sameBrokerContract(held, contract);
20
21
  }
21
22
 
22
- /** A read-only projection. No broker operation is attached to a chart level. */
23
- export function ticketChartLevels({ draft, editing, orders, latestOrder, avgCost, position, colors, priceStep, priceDecimals }: {
23
+ /**
24
+ * A price from the chart on the broker's tick, or the ticket's editing step, so the ticket reviews it as shown. Never
25
+ * under one tick: a line dragged to the bottom of the chart is not a price of zero.
26
+ */
27
+ export function chartPriceOnTick(value: number, priceStep?: number, priceDecimals?: number): number {
28
+ const step = priceStep !== undefined && Number.isFinite(priceStep) && priceStep > 0 ? priceStep : ticketEditingPriceStep(Math.max(value, 0), priceDecimals);
29
+ const decimals = Math.min(18, step.toLocaleString("en-US", { useGrouping: false, maximumFractionDigits: 18 }).split(".")[1]?.length ?? 0);
30
+ return Number((Math.max(1, Math.round(value / step)) * step).toFixed(decimals));
31
+ }
32
+
33
+ /** The orders the chart draws: the broker's list with the ticket's latest word on one merged in. */
34
+ export function ticketLineOrders(orders: readonly BrokerOrder[], latestOrder?: BrokerOrder): readonly BrokerOrder[] {
35
+ return latestOrder ? withLatestOrder(orders, latestOrder) : orders;
36
+ }
37
+
38
+ /**
39
+ * Whether a working order's line moves on the chart: the broker changes this order, and it is neither still being
40
+ * acknowledged nor already being replaced.
41
+ */
42
+ export function orderLineMoves(order: BrokerOrder, allowed: Pick<BrokerTradingCapabilities, "enabled" | "modify"> | undefined): boolean {
43
+ return !!allowed?.enabled && !!allowed.modify && canChangeBrokerOrder(order) && !["Replacing", "Submitted"].includes(brokerOrderStatus(order.status));
44
+ }
45
+
46
+ /** Which ticket price each draft level shows, by level id. */
47
+ export const TICKET_LEVEL_FIELDS = {
48
+ "ticket:limit": "limitPrice", "ticket:stop": "stopPrice", "ticket:take-profit": "takeProfitPrice", "ticket:stop-loss": "stopLossPrice",
49
+ } as const satisfies Record<string, keyof BrokerOrderRequest>;
50
+
51
+ /** The order a working order's level belongs to, and the price it shows. */
52
+ export function orderLevelTarget(id: string, orders: readonly BrokerOrder[]): { order: BrokerOrder; field: "limitPrice" | "stopPrice" } | undefined {
53
+ const [kind, ...rest] = id.split(":");
54
+ if (kind !== "order" && kind !== "stop") return undefined;
55
+ const key = rest.join(":");
56
+ const order = orders.find((value) => brokerOrderKey(value) === key);
57
+ if (!order) return undefined;
58
+ return { order, field: kind === "stop" || order.orderType === "STP" ? "stopPrice" : "limitPrice" };
59
+ }
60
+
61
+ /**
62
+ * The ticket's draft and this account's working orders as chart levels. Levels hold no broker operation: a moved
63
+ * draft level changes the draft, and a moved order level opens that order's change in the ticket, for its review.
64
+ * `movable` says which working orders' lines move (the broker changes them, and the ticket is free to).
65
+ * While an order is being changed, a dashed line shows the changed price, and its own line stays where the broker
66
+ * holds it until the change is confirmed.
67
+ */
68
+ export function ticketChartLevels({ draft, editing, orders, latestOrder, modifying, movable, avgCost, position, colors, priceStep, priceDecimals }: {
24
69
  draft?: BrokerOrderRequest; editing: boolean; orders: readonly BrokerOrder[]; latestOrder?: BrokerOrder;
70
+ modifying?: BrokerOrder; movable?: (order: BrokerOrder) => boolean;
25
71
  avgCost?: number; position?: number; colors: ThemeColors; priceStep?: number; priceDecimals?: number;
26
72
  }): CompositeChartLevel[] {
27
73
  const levels: CompositeChartLevel[] = [];
@@ -29,25 +75,48 @@ export function ticketChartLevels({ draft, editing, orders, latestOrder, avgCost
29
75
  // decimals are a limit, not a tick: five of them do not make $719.60745 an average anyone reads.
30
76
  const tick = (value: number) => priceStep !== undefined && Number.isFinite(priceStep) && priceStep > 0 ? priceStep : ticketEditingPriceStep(value, priceDecimals);
31
77
  // An order price shows every digit it was entered with; an average is arithmetic, so it rounds to the tick.
32
- const add = (id: string, value: number | undefined, label: string, color: string, dashed = false, averaged = false) => {
78
+ const add = (id: string, value: number | undefined, label: string, color: string, dashed = false, averaged = false, moves = false) => {
33
79
  if (value === undefined || !Number.isFinite(value) || value <= 0) return;
34
80
  const minimumFractionDigits = Math.min(18, tick(value).toLocaleString("en-US", { useGrouping: false, maximumFractionDigits: 18 }).split(".")[1]?.length ?? 0);
35
81
  const maximumFractionDigits = averaged ? minimumFractionDigits : Math.max(8, minimumFractionDigits);
36
82
  const axisLabel = value.toLocaleString("en-US", { minimumFractionDigits, maximumFractionDigits });
37
- levels.push({ id, value, axisLabel, label, color, editable: false, actionable: false, dashed });
83
+ levels.push({ id, value, axisLabel, label, color, editable: moves, draggable: moves, actionable: false, dashed });
38
84
  };
39
- if (draft && editing) {
85
+ const changing = modifying && editing && draft ? brokerOrderKey(modifying) : undefined;
86
+ if (draft && editing && !changing) {
40
87
  const color = draft.action === "SELL" ? colors.negative : colors.positive;
41
- if (["LMT", "STP LMT"].includes(draft.orderType)) add("ticket:limit", draft.limitPrice, "Draft limit", color, true);
42
- if (["STP", "STP LMT"].includes(draft.orderType)) add("ticket:stop", draft.stopPrice, "Draft stop", color, true);
88
+ // A bracket's exits trade the other way; an OCO's stop is its own side's.
89
+ const exitColor = draft.action === "SELL" ? colors.positive : colors.negative;
90
+ if (["LMT", "STP LMT"].includes(draft.orderType)) add("ticket:limit", draft.limitPrice, "Draft limit", color, true, false, true);
91
+ if (["STP", "STP LMT"].includes(draft.orderType)) add("ticket:stop", draft.stopPrice, "Draft stop", color, true, false, true);
92
+ if (draft.orderClass === "oco") add("ticket:stop-loss", draft.stopLossPrice, "Draft stop", color, true, false, true);
93
+ if (draft.orderClass === "bracket") {
94
+ add("ticket:take-profit", draft.takeProfitPrice, "Draft take profit", exitColor, true, false, true);
95
+ add("ticket:stop-loss", draft.stopLossPrice, "Draft stop loss", exitColor, true, false, true);
96
+ }
43
97
  }
44
- const projected = latestOrder ? withLatestOrder(orders, latestOrder) : orders;
45
- for (const order of projected) {
98
+ for (const order of ticketLineOrders(orders, latestOrder)) {
46
99
  if (!canChangeBrokerOrder(order)) continue;
47
- const label = `${order.action === "BUY" ? "Buy" : "Sell"} ${order.remaining} ${({ "Partially filled": "partial", Replacing: "replacing" } as Record<string, string>)[brokerOrderStatus(order.status)] ?? "working"}`;
100
+ const state = ({ "Partially filled": "partial", Replacing: "replacing" } as Record<string, string>)[brokerOrderStatus(order.status)];
101
+ // A bracket's exit or a trailing stop says what it is; a plain order says how it stands.
102
+ const kind = order.linkRole && order.linkRole !== "entry" ? linkRoleName[order.linkRole].toLowerCase() : order.orderType === "TRAIL" ? "trailing" : undefined;
103
+ const label = `${order.action === "BUY" ? "Buy" : "Sell"} ${order.remaining} ${[kind, state].filter(Boolean).join(" ") || "working"}`;
48
104
  const color = order.action === "SELL" ? colors.negative : colors.positive;
49
- add(`order:${brokerOrderKey(order)}`, order.limitPrice ?? order.stopPrice, label, color);
50
- if (order.orderType === "STP LMT") add(`stop:${brokerOrderKey(order)}`, order.stopPrice, `${label} stop`, color);
105
+ const key = brokerOrderKey(order);
106
+ // The order being changed shows where it is going, dashed, as a draft does, and moves on from there. Its own
107
+ // line stays put: nothing has reached the broker until the change is reviewed and confirmed.
108
+ if (key === changing && draft) {
109
+ const change = `${order.action === "BUY" ? "Buy" : "Sell"} ${order.remaining} change`;
110
+ add(`held:${key}`, order.limitPrice ?? order.stopPrice, label, color);
111
+ if (order.orderType === "STP LMT") add(`held-stop:${key}`, order.stopPrice, `${label} stop`, color);
112
+ add(`order:${key}`, order.orderType === "STP" ? draft.stopPrice : draft.limitPrice, change, color, true, false, true);
113
+ if (order.orderType === "STP LMT") add(`stop:${key}`, draft.stopPrice, `${change} stop`, color, true, false, true);
114
+ continue;
115
+ }
116
+ // A trailing stop's trigger is the broker's to move.
117
+ const moves = order.orderType !== "TRAIL" && !isStrategyOrder(order) && (movable?.(order) ?? false);
118
+ add(`order:${key}`, order.limitPrice ?? order.stopPrice, label, color, false, false, moves);
119
+ if (order.orderType === "STP LMT") add(`stop:${key}`, order.stopPrice, `${label} stop`, color, false, false, moves);
51
120
  }
52
121
  if (position && avgCost !== undefined) add("position:average", avgCost, "Average cost", colors.textDim, false, true);
53
122
  return levels;