gloomberb 0.18.3 → 0.18.5

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (1018) 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/patches/electrobun@1.18.1.patch +32 -1
  6. package/src/account/auth-model.ts +7 -3
  7. package/src/account/checkout-handoff.tsx +225 -0
  8. package/src/account/device-signin-dialog.tsx +2 -2
  9. package/src/account/device-signin.ts +2 -2
  10. package/src/account/upgrade-dialog.tsx +1 -1
  11. package/src/api-client/askg.ts +2 -2
  12. package/src/api-client/auth.ts +11 -6
  13. package/src/api-client/catalysts.ts +2 -1
  14. package/src/api-client/central-bank-rates.ts +6 -0
  15. package/src/api-client/collections.ts +5 -1
  16. package/src/api-client/cot.ts +2 -0
  17. package/src/api-client/crypto-etf-flows.ts +37 -0
  18. package/src/api-client/crypto-markets.ts +60 -0
  19. package/src/api-client/data.ts +98 -5
  20. package/src/api-client/doe.ts +15 -0
  21. package/src/api-client/equity-screener.ts +28 -0
  22. package/src/api-client/exchange-announcements.ts +38 -0
  23. package/src/api-client/fund-facts.ts +39 -0
  24. package/src/api-client/futures-curve.ts +9 -1
  25. package/src/api-client/hiring.ts +301 -0
  26. package/src/api-client/index.ts +182 -16
  27. package/src/api-client/live-scan.ts +91 -0
  28. package/src/api-client/market-discovery.ts +14 -0
  29. package/src/api-client/members.ts +18 -0
  30. package/src/api-client/mna.ts +6 -0
  31. package/src/api-client/paths.ts +18 -1
  32. package/src/api-client/request.ts +224 -26
  33. package/src/api-client/research-activity.ts +3 -10
  34. package/src/api-client/short-side-publications.ts +37 -0
  35. package/src/api-client/socket.ts +64 -4
  36. package/src/api-client/swap-curve.ts +35 -0
  37. package/src/api-client/themes.ts +7 -1
  38. package/src/api-client/types.ts +96 -2
  39. package/src/app/keybindings/index.ts +3 -0
  40. package/src/app/keybindings/labels.ts +18 -1
  41. package/src/app/keybindings/resolve.ts +14 -0
  42. package/src/app/pane-runtime/plugin-bindings.ts +9 -2
  43. package/src/app/runtime/broker-import.ts +43 -26
  44. package/src/app/runtime/desktop-deeplink.ts +5 -5
  45. package/src/app/runtime/plugin-bindings.ts +2 -2
  46. package/src/app/runtime/startup.ts +13 -0
  47. package/src/app/star-prompt/status-line.tsx +2 -2
  48. package/src/architecture/core-builtin-allowlist.json +5 -2
  49. package/src/architecture/ui-literals-allowlist.json +3 -3
  50. package/src/architecture/ui-tokens-allowlist.json +1 -1
  51. package/src/brokers/broker-portfolio-sync.ts +37 -0
  52. package/src/brokers/directory.ts +11 -0
  53. package/src/brokers/logos.ts +3 -1
  54. package/src/brokers/signed-in/adapter.ts +304 -26
  55. package/src/brokers/signed-in/client.ts +14 -2
  56. package/src/brokers/signed-in/connect.ts +10 -2
  57. package/src/brokers/sync-broker-instance.ts +9 -1
  58. package/src/capabilities/chart-series.ts +22 -6
  59. package/src/cli/bank-section.ts +1 -1
  60. package/src/cli/base-converter.ts +23 -14
  61. package/src/cli/central-bank-events.ts +1 -1
  62. package/src/cli/command-options.ts +59 -4
  63. package/src/cli/commands/api.ts +9 -6
  64. package/src/cli/commands/broker.ts +2 -2
  65. package/src/cli/commands/command-utils.ts +2 -2
  66. package/src/cli/commands/crypto-hints.ts +7 -20
  67. package/src/cli/commands/fred-series.ts +9 -2
  68. package/src/cli/commands/keybindings.ts +25 -2
  69. package/src/cli/commands/market.ts +1177 -278
  70. package/src/cli/commands/news-hints.ts +2 -2
  71. package/src/cli/commands/news-search.ts +59 -6
  72. package/src/cli/commands/options-chain.ts +59 -3
  73. package/src/cli/commands/options-leaps.ts +41 -26
  74. package/src/cli/commands/overview.ts +222 -61
  75. package/src/cli/commands/plugins.ts +9 -9
  76. package/src/cli/commands/remote.ts +13 -10
  77. package/src/cli/commands/search.ts +82 -46
  78. package/src/cli/commands/system.ts +27 -19
  79. package/src/cli/commands/themes.ts +1 -1
  80. package/src/cli/commands/ticker.ts +194 -48
  81. package/src/cli/context.ts +3 -2
  82. package/src/cli/desktop-pane-shot-view.ts +2 -2
  83. package/src/cli/desktop-pane-shot.ts +1 -1
  84. package/src/cli/earnings-calendar.ts +4 -4
  85. package/src/cli/entry.ts +18 -1
  86. package/src/cli/errors.ts +21 -3
  87. package/src/cli/exit-codes.ts +1 -1
  88. package/src/cli/export-source.ts +38 -4
  89. package/src/cli/freshness.ts +2 -8
  90. package/src/cli/fx-forward.ts +130 -0
  91. package/src/cli/fx-pair.ts +10 -9
  92. package/src/cli/glossary.ts +113 -20
  93. package/src/cli/help.ts +19 -13
  94. package/src/cli/history-export.ts +126 -0
  95. package/src/cli/history-rows.ts +226 -50
  96. package/src/cli/index-roots.ts +5 -45
  97. package/src/cli/index.ts +24 -18
  98. package/src/cli/known-gaps.ts +123 -27
  99. package/src/cli/listing-arg.ts +316 -46
  100. package/src/cli/name-entries.ts +30 -18
  101. package/src/cli/native-smoke.ts +2 -0
  102. package/src/cli/not-a-ticker.ts +19 -9
  103. package/src/cli/opentui-libc.ts +5 -0
  104. package/src/cli/options.ts +12 -0
  105. package/src/cli/pane-functions/capabilities.ts +75 -20
  106. package/src/cli/pane-functions/catalog.ts +24 -23
  107. package/src/cli/pane-functions/discovery.ts +1 -1
  108. package/src/cli/pane-functions/dom.ts +10 -7
  109. package/src/cli/pane-functions/financial-ratio-shot.ts +2 -2
  110. package/src/cli/pane-functions/freshness.ts +193 -30
  111. package/src/cli/pane-functions/function-help.ts +76 -30
  112. package/src/cli/pane-functions/headless.ts +59 -12
  113. package/src/cli/pane-functions/index.ts +28 -19
  114. package/src/cli/pane-functions/market-session.ts +15 -5
  115. package/src/cli/pane-functions/options.ts +22 -2
  116. package/src/cli/pane-functions/report-notices.ts +12 -4
  117. package/src/cli/pane-functions/report.ts +10 -6
  118. package/src/cli/pane-functions/resolver.ts +64 -11
  119. package/src/cli/pane-functions/screenshot-assessment.ts +322 -0
  120. package/src/cli/pane-functions/screenshot-bridge.ts +152 -0
  121. package/src/cli/pane-functions/screenshot-chart-evidence.ts +396 -0
  122. package/src/cli/pane-functions/screenshot-data-evidence.ts +383 -0
  123. package/src/cli/pane-functions/screenshot-evidence.ts +1 -1
  124. package/src/cli/pane-functions/screenshot-payload.ts +453 -0
  125. package/src/cli/pane-functions/screenshot-render.ts +316 -0
  126. package/src/cli/pane-functions/screenshot-types.ts +162 -0
  127. package/src/cli/pane-functions/shot-options.ts +8 -3
  128. package/src/cli/peso-dollar-rates.ts +79 -0
  129. package/src/cli/quote-answer.ts +45 -4
  130. package/src/cli/report-tables.ts +75 -19
  131. package/src/cli/restore-plugins.ts +42 -15
  132. package/src/cli/result.ts +164 -23
  133. package/src/cli/series-search.ts +5 -5
  134. package/src/cli/statement-filings.ts +19 -0
  135. package/src/cli/suffixed-listing-rows.ts +49 -0
  136. package/src/cli/symbol-args.ts +50 -15
  137. package/src/cli/symbol-cells.ts +120 -0
  138. package/src/cli/symbol-list.ts +198 -68
  139. package/src/cli/symbol-rows.ts +131 -25
  140. package/src/cli/ticker-resolution.ts +108 -11
  141. package/src/cli/treasury-yields.ts +5 -5
  142. package/src/cli/types.ts +2 -0
  143. package/src/cli/uncovered-instrument.ts +3 -3
  144. package/src/cli/unknown-command.ts +6 -6
  145. package/src/components/chart/composite/chart-layout.ts +131 -0
  146. package/src/components/chart/composite/composite-chart.tsx +395 -20
  147. package/src/components/chart/composite/format.ts +27 -0
  148. package/src/components/chart/composite/interactions.ts +7 -2
  149. package/src/components/chart/composite/legend.tsx +75 -3
  150. package/src/components/chart/composite/levels.ts +7 -0
  151. package/src/components/chart/composite/panel-gestures.ts +41 -0
  152. package/src/components/chart/composite/panel-labels.ts +2 -1
  153. package/src/components/chart/composite/panel-series.ts +1 -0
  154. package/src/components/chart/composite/panel-surface.tsx +314 -13
  155. package/src/components/chart/composite/price-axis-labels.tsx +27 -3
  156. package/src/components/chart/composite/range-statistics.ts +62 -0
  157. package/src/components/chart/composite/rasterizer.ts +44 -19
  158. package/src/components/chart/composite/scene.ts +20 -4
  159. package/src/components/chart/composite/series-axis-tags.tsx +16 -9
  160. package/src/components/chart/composite/text-renderer.ts +48 -21
  161. package/src/components/chart/composite/toolbar.tsx +52 -5
  162. package/src/components/chart/composite/types.ts +17 -0
  163. package/src/components/chart/composite/use-composite-chart-keyboard.ts +120 -13
  164. package/src/components/chart/composite/use-composite-value-scales.ts +44 -0
  165. package/src/components/chart/composite/use-composite-viewport.ts +12 -3
  166. package/src/components/chart/composite/value-scale.ts +149 -0
  167. package/src/components/chart/composite/volume-profile-paint.ts +6 -3
  168. package/src/components/chart/core/pointer.ts +2 -0
  169. package/src/components/chart-table/index.ts +2 -0
  170. package/src/components/chart-table/read.tsx +74 -0
  171. package/src/components/command-bar/commands/collection-list.ts +41 -19
  172. package/src/components/command-bar/commands/collection.ts +9 -3
  173. package/src/components/command-bar/commands/direct/index.ts +1 -1
  174. package/src/components/command-bar/commands/direct/runtime.ts +3 -2
  175. package/src/components/command-bar/pane-templates/items.ts +59 -6
  176. package/src/components/command-bar/pane-templates/workflow.ts +10 -1
  177. package/src/components/command-bar/panel/prompt-binding.ts +0 -8
  178. package/src/components/command-bar/routes/root/plugin-install.ts +1 -1
  179. package/src/components/command-bar/routes/root/provider-search.ts +42 -11
  180. package/src/components/command-bar/routes/root/results.ts +18 -4
  181. package/src/components/command-bar/routes/root/runtime.ts +15 -3
  182. package/src/components/command-bar/routes/root/search-providers.ts +25 -2
  183. package/src/components/command-bar/routes/root/selection.ts +6 -1
  184. package/src/components/command-bar/routes/root/shortcut-feedback.ts +4 -1
  185. package/src/components/command-bar/routes/root/shortcuts.ts +30 -3
  186. package/src/components/command-bar/routes/ticker-search/results.ts +73 -4
  187. package/src/components/command-bar/selection-runtime.ts +50 -10
  188. package/src/components/command-bar/surface/index.tsx +24 -2
  189. package/src/components/command-bar/view-model.ts +7 -0
  190. package/src/components/command-bar/workflow/alert.ts +1 -1
  191. package/src/components/command-bar/workflow/broker.ts +2 -2
  192. package/src/components/command-bar/workflow/collection-actions.ts +46 -7
  193. package/src/components/command-bar/workflow/collection-ticker.ts +32 -4
  194. package/src/components/command-bar/workflow/fields.ts +8 -2
  195. package/src/components/command-bar/workflow/ops.ts +18 -4
  196. package/src/components/command-bar/workflow/portfolio-position.ts +53 -4
  197. package/src/components/command-bar/workflow/submit.ts +3 -2
  198. package/src/components/command-bar/workflow/tickers.ts +5 -1
  199. package/src/components/company-logo.tsx +39 -0
  200. package/src/components/data-table/sections.ts +4 -2
  201. package/src/components/form-modal/confirm.tsx +2 -1
  202. package/src/components/form-modal/request.ts +5 -0
  203. package/src/components/form-modal/routes.ts +4 -1
  204. package/src/components/index.ts +12 -6
  205. package/src/components/layout/header.tsx +33 -46
  206. package/src/components/layout/market-summary.ts +9 -6
  207. package/src/components/layout/pane/capture-status.ts +1 -1
  208. package/src/components/layout/pane/footer/index.tsx +1 -0
  209. package/src/components/layout/pane/footer/model.ts +38 -5
  210. package/src/components/layout/shell/chrome.ts +19 -6
  211. package/src/components/layout/shell/index.tsx +2 -1
  212. package/src/components/layout/shell/pane/layers.tsx +19 -1
  213. package/src/components/layout/status-bar.tsx +2 -2
  214. package/src/components/market-board/index.tsx +11 -3
  215. package/src/components/onboarding/onboarding-frame.tsx +1 -1
  216. package/src/components/onboarding/onboarding-wizard.tsx +1 -0
  217. package/src/components/onboarding/portfolio-step/broker-setup-panel.tsx +2 -2
  218. package/src/components/onboarding/portfolio-step/positions-panel.tsx +2 -2
  219. package/src/components/onboarding/wizard-broker-sync.ts +4 -1
  220. package/src/components/pane-settings-dialog/desktop.tsx +20 -7
  221. package/src/components/pane-settings-dialog/tui.tsx +17 -9
  222. package/src/components/pane-settings-dialog/value.ts +8 -1
  223. package/src/components/pane-settings-dialog.tsx +44 -13
  224. package/src/components/sign-in-code-panel.tsx +27 -19
  225. package/src/components/ui/column-grid.tsx +48 -4
  226. package/src/components/ui/country-flag-art.tsx +180 -0
  227. package/src/components/ui/country-flag.tsx +118 -12
  228. package/src/components/ui/data-table/opentui/index.tsx +61 -2
  229. package/src/components/ui/data-table/opentui/model.ts +109 -2
  230. package/src/components/ui/data-table/types.ts +1 -1
  231. package/src/components/ui/display.tsx +10 -2
  232. package/src/components/ui/index.ts +3 -1
  233. package/src/components/ui/logo-mark.tsx +11 -2
  234. package/src/components/ui/query-bar.tsx +1 -1
  235. package/src/components/ui/row-notes.ts +79 -0
  236. package/src/core/state/app/layout.ts +6 -4
  237. package/src/core/state/app/state.ts +9 -0
  238. package/src/core/state/app/types.ts +3 -0
  239. package/src/data/cached-query.ts +8 -1
  240. package/src/data/config/chart-settings.ts +3 -3
  241. package/src/data/config/home.ts +10 -2
  242. package/src/data/config/layout.ts +4 -1
  243. package/src/data/config/store/node.ts +4 -0
  244. package/src/data/config/store/normalize.ts +13 -3
  245. package/src/data/config/store/portfolio-as-of-column.ts +2 -2
  246. package/src/data/json-storage.ts +2 -0
  247. package/src/data/saved-copies.ts +123 -0
  248. package/src/docs/snapshot.json +422 -112
  249. package/src/i18n/es.ts +30 -13
  250. package/src/i18n/ja.ts +30 -13
  251. package/src/i18n/ko.ts +30 -13
  252. package/src/i18n/zh-cn.ts +30 -13
  253. package/src/i18n/zh-tw.ts +30 -13
  254. package/src/layout/desks.ts +1 -1
  255. package/src/layout/launch-layout.ts +1 -1
  256. package/src/layout/pane-manager/floating-actions.ts +5 -3
  257. package/src/layout/pane-manager/floating.ts +43 -1
  258. package/src/layout/pane-manager/index.ts +2 -0
  259. package/src/layout/selected-ticker.ts +74 -0
  260. package/src/market-data/coordinator/financials.ts +10 -2
  261. package/src/market-data/coordinator/index.ts +3 -1
  262. package/src/market-data/coordinator/quotes.ts +4 -2
  263. package/src/market-data/depositary-pair.ts +251 -0
  264. package/src/market-data/futures-board.ts +1 -1
  265. package/src/market-data/futures-contract.ts +124 -40
  266. package/src/market-data/fx-closes.ts +17 -2
  267. package/src/market-data/hooks.tsx +19 -11
  268. package/src/market-data/market/change-basis.ts +81 -11
  269. package/src/market-data/market/dated-previous-close.ts +203 -0
  270. package/src/market-data/market/freshness.ts +34 -5
  271. package/src/market-data/market/futures-week.ts +68 -0
  272. package/src/market-data/market/period-return.ts +163 -0
  273. package/src/market-data/market/status.ts +16 -4
  274. package/src/market-data/market/trading-sessions.ts +13 -0
  275. package/src/market-data/market/year-to-date.ts +8 -13
  276. package/src/market-data/options-alternatives.ts +60 -0
  277. package/src/market-data/performance.ts +20 -14
  278. package/src/market-data/perpetual-premium.ts +32 -0
  279. package/src/market-data/published-apac-sessions.ts +2 -1
  280. package/src/market-data/published-futures-sessions.ts +69 -0
  281. package/src/market-data/quotes/contributions.ts +25 -3
  282. package/src/market-data/quotes/freshness.ts +42 -0
  283. package/src/market-data/quotes/intraday-bar.ts +37 -0
  284. package/src/market-data/quotes/regular-session-valuation.ts +13 -8
  285. package/src/market-data/quotes/resolution.ts +7 -2
  286. package/src/market-data/selectors.ts +3 -0
  287. package/src/market-data/tax-equivalent.ts +1 -1
  288. package/src/market-data/ticker-price-returns.ts +3 -1
  289. package/src/news/aggregator.ts +5 -1
  290. package/src/news/news-model.ts +4 -0
  291. package/src/news/types.ts +11 -0
  292. package/src/notifications/app-notifier.ts +1 -1
  293. package/src/notifications/notification-log.ts +6 -4
  294. package/src/plugins/auto-update.ts +2 -2
  295. package/src/plugins/builtin/account-management/index.tsx +1 -0
  296. package/src/plugins/builtin/account-management/pane.tsx +9 -8
  297. package/src/plugins/builtin/alerts/alert-engine.ts +34 -20
  298. package/src/plugins/builtin/alerts/calendar-events.ts +429 -0
  299. package/src/plugins/builtin/alerts/cli.ts +533 -85
  300. package/src/plugins/builtin/alerts/command.ts +12 -10
  301. package/src/plugins/builtin/alerts/constants.ts +1 -1
  302. package/src/plugins/builtin/alerts/event-rows.ts +9 -5
  303. package/src/plugins/builtin/alerts/events-pane.tsx +71 -56
  304. package/src/plugins/builtin/alerts/events.ts +107 -5
  305. package/src/plugins/builtin/alerts/fired-log.ts +119 -0
  306. package/src/plugins/builtin/alerts/format.ts +10 -3
  307. package/src/plugins/builtin/alerts/headless.ts +107 -41
  308. package/src/plugins/builtin/alerts/history-pane.tsx +105 -62
  309. package/src/plugins/builtin/alerts/history-rows.ts +92 -0
  310. package/src/plugins/builtin/alerts/history.ts +2 -0
  311. package/src/plugins/builtin/alerts/index.tsx +107 -30
  312. package/src/plugins/builtin/alerts/iv-level.ts +365 -0
  313. package/src/plugins/builtin/alerts/levels.ts +3 -3
  314. package/src/plugins/builtin/alerts/live.ts +3 -3
  315. package/src/plugins/builtin/alerts/metric-command.ts +61 -0
  316. package/src/plugins/builtin/alerts/metric-data.ts +70 -0
  317. package/src/plugins/builtin/alerts/metric-model.ts +175 -0
  318. package/src/plugins/builtin/alerts/metric-parity-fixture.json +725 -0
  319. package/src/plugins/builtin/alerts/pane.tsx +130 -49
  320. package/src/plugins/builtin/alerts/price.ts +35 -0
  321. package/src/plugins/builtin/alerts/quotes.ts +24 -0
  322. package/src/plugins/builtin/alerts/research-builder.ts +84 -11
  323. package/src/plugins/builtin/alerts/research-rules.ts +76 -3
  324. package/src/plugins/builtin/alerts/scheduled-check.ts +206 -32
  325. package/src/plugins/builtin/alerts/scheduled-sources.ts +26 -3
  326. package/src/plugins/builtin/alerts/scheduled.ts +188 -29
  327. package/src/plugins/builtin/alerts/storage.ts +38 -12
  328. package/src/plugins/builtin/alerts/targets.ts +12 -3
  329. package/src/plugins/builtin/alerts/types.ts +3 -0
  330. package/src/plugins/builtin/analytics/index.tsx +8 -2
  331. package/src/plugins/builtin/analytics/metrics.ts +1 -1
  332. package/src/plugins/builtin/analytics/risk-book.ts +215 -0
  333. package/src/plugins/builtin/analytics/risk-client.ts +13 -6
  334. package/src/plugins/builtin/analytics/risk-headless.ts +55 -21
  335. package/src/plugins/builtin/analytics/risk-math.ts +6 -3
  336. package/src/plugins/builtin/analytics/risk-model.ts +297 -104
  337. package/src/plugins/builtin/analytics/risk-options.ts +17 -2
  338. package/src/plugins/builtin/analytics/risk-pane.tsx +97 -36
  339. package/src/plugins/builtin/attention/pane.tsx +6 -2
  340. package/src/plugins/builtin/awards/headless.ts +7 -3
  341. package/src/plugins/builtin/awards/model.ts +18 -0
  342. package/src/plugins/builtin/awards/pane.tsx +6 -3
  343. package/src/plugins/builtin/backtest/headless.ts +13 -8
  344. package/src/plugins/builtin/backtest/pane.tsx +9 -4
  345. package/src/plugins/builtin/backtest/presets.ts +29 -3
  346. package/src/plugins/builtin/backtest/rules.ts +41 -5
  347. package/src/plugins/builtin/broker-manager/add-flow.tsx +12 -7
  348. package/src/plugins/builtin/broker-manager/detail.tsx +47 -19
  349. package/src/plugins/builtin/broker-manager/footer.ts +27 -11
  350. package/src/plugins/builtin/broker-manager/index.tsx +24 -14
  351. package/src/plugins/builtin/broker-manager/keyboard.ts +1 -1
  352. package/src/plugins/builtin/broker-manager/model.ts +18 -3
  353. package/src/plugins/builtin/broker-manager/pane-actions.tsx +183 -57
  354. package/src/plugins/builtin/broker-manager/table.ts +28 -12
  355. package/src/plugins/builtin/broker-trading/account-picker.tsx +2 -1
  356. package/src/plugins/builtin/broker-trading/chart-levels.ts +82 -13
  357. package/src/plugins/builtin/broker-trading/controller.ts +66 -24
  358. package/src/plugins/builtin/broker-trading/dock.tsx +22 -4
  359. package/src/plugins/builtin/broker-trading/headless.ts +2 -1
  360. package/src/plugins/builtin/broker-trading/index.tsx +19 -1
  361. package/src/plugins/builtin/broker-trading/linked-orders.ts +148 -0
  362. package/src/plugins/builtin/broker-trading/order-feed.ts +83 -10
  363. package/src/plugins/builtin/broker-trading/orders.tsx +109 -31
  364. package/src/plugins/builtin/broker-trading/overview-orders.tsx +9 -3
  365. package/src/plugins/builtin/broker-trading/pane-model.ts +30 -2
  366. package/src/plugins/builtin/broker-trading/pane.tsx +111 -24
  367. package/src/plugins/builtin/broker-trading/ticket-parts.tsx +36 -7
  368. package/src/plugins/builtin/broker-trading/ticket.tsx +112 -31
  369. package/src/plugins/builtin/buildout/cells.tsx +4 -0
  370. package/src/plugins/builtin/buildout/detail/index.tsx +5 -1
  371. package/src/plugins/builtin/buildout/detail/ui.tsx +7 -4
  372. package/src/plugins/builtin/buildout/pane/index.tsx +25 -12
  373. package/src/plugins/builtin/buildout/pane/status.tsx +0 -4
  374. package/src/plugins/builtin/builtin-plugin-meta.ts +2 -2
  375. package/src/plugins/builtin/catalysts/detail.tsx +3 -2
  376. package/src/plugins/builtin/catalysts/index.tsx +1 -1
  377. package/src/plugins/builtin/catalysts/model.ts +51 -5
  378. package/src/plugins/builtin/catalysts/pane.tsx +6 -8
  379. package/src/plugins/builtin/central-bank-rates/client.ts +5 -0
  380. package/src/plugins/builtin/central-bank-rates/headless.ts +36 -10
  381. package/src/plugins/builtin/central-bank-rates/model.ts +33 -8
  382. package/src/plugins/builtin/changelog/index.tsx +1 -0
  383. package/src/plugins/builtin/chart-composer/catalog-inventory.ts +4 -1
  384. package/src/plugins/builtin/chart-composer/chart-spec-edit.ts +3 -2
  385. package/src/plugins/builtin/chart-composer/chart-spec.ts +7 -0
  386. package/src/plugins/builtin/chart-composer/cli-options.ts +7 -10
  387. package/src/plugins/builtin/chart-composer/data-catalog-pane.tsx +7 -3
  388. package/src/plugins/builtin/chart-composer/editor/controller.ts +4 -0
  389. package/src/plugins/builtin/chart-composer/editor/model.ts +2 -0
  390. package/src/plugins/builtin/chart-composer/editor.tsx +9 -4
  391. package/src/plugins/builtin/chart-composer/formula.ts +71 -18
  392. package/src/plugins/builtin/chart-composer/headless-schema.ts +42 -29
  393. package/src/plugins/builtin/chart-composer/headless.ts +266 -37
  394. package/src/plugins/builtin/chart-composer/index.tsx +12 -2
  395. package/src/plugins/builtin/chart-composer/leverage-overlay.ts +142 -0
  396. package/src/plugins/builtin/chart-composer/pane.tsx +144 -30
  397. package/src/plugins/builtin/chart-composer/presets.ts +50 -15
  398. package/src/plugins/builtin/chart-composer/quick-add.tsx +40 -25
  399. package/src/plugins/builtin/chart-composer/series-catalog.ts +1 -0
  400. package/src/plugins/builtin/chart-composer/series-expression.ts +65 -6
  401. package/src/plugins/builtin/chart-composer/session-history.ts +31 -28
  402. package/src/plugins/builtin/chart-composer/session-range.ts +4 -2
  403. package/src/plugins/builtin/chart-composer/settings.ts +31 -19
  404. package/src/plugins/builtin/chart-composer/use-series-catalog.ts +44 -31
  405. package/src/plugins/builtin/chart-composer/viewport-labels.ts +18 -8
  406. package/src/plugins/builtin/chat/attachments/model.ts +3 -1
  407. package/src/plugins/builtin/chat/content/command-suggestions.ts +92 -0
  408. package/src/plugins/builtin/chat/content/composer.tsx +13 -6
  409. package/src/plugins/builtin/chat/content/footer.tsx +6 -3
  410. package/src/plugins/builtin/chat/content/index.tsx +51 -22
  411. package/src/plugins/builtin/chat/content/open-targets.ts +14 -3
  412. package/src/plugins/builtin/chat/controller/session-runtime.ts +4 -2
  413. package/src/plugins/builtin/chat/index.tsx +23 -0
  414. package/src/plugins/builtin/chat/message/desktop.tsx +1 -0
  415. package/src/plugins/builtin/chat/message/inline-tokens.tsx +23 -0
  416. package/src/plugins/builtin/chat/message/pane-chip.tsx +50 -20
  417. package/src/plugins/builtin/chat/pane-links/commands.ts +265 -0
  418. package/src/plugins/builtin/chat/pane-links/model.ts +12 -3
  419. package/src/plugins/builtin/chat/pane-links/open.ts +9 -2
  420. package/src/plugins/builtin/chat/people.ts +1 -1
  421. package/src/plugins/builtin/chat/unread-inbox-pane.tsx +10 -1
  422. package/src/plugins/builtin/clinical-trials/client.ts +5 -2
  423. package/src/plugins/builtin/clinical-trials/model.ts +13 -4
  424. package/src/plugins/builtin/clinical-trials/pane.tsx +32 -12
  425. package/src/plugins/builtin/clinical-trials/ticker-sponsor.ts +17 -0
  426. package/src/plugins/builtin/cloud/askg/controller.ts +1 -1
  427. package/src/plugins/builtin/cloud/askg/lock-note.ts +1 -1
  428. package/src/plugins/builtin/cloud/askg/tool-display.ts +1 -1
  429. package/src/plugins/builtin/cloud/auth-commands.ts +3 -3
  430. package/src/plugins/builtin/cloud/plugin.tsx +1 -1
  431. package/src/plugins/builtin/cloud/team/pane-sections.tsx +105 -47
  432. package/src/plugins/builtin/cloud/team/pane-ui.tsx +42 -4
  433. package/src/plugins/builtin/cloud/team/pane.tsx +204 -64
  434. package/src/plugins/builtin/cloud/thesis/store.ts +45 -22
  435. package/src/plugins/builtin/cloud-tweets/registration.ts +1 -0
  436. package/src/plugins/builtin/commodities-energy/index.tsx +29 -2
  437. package/src/plugins/builtin/commodities-energy/view-state.ts +2 -0
  438. package/src/plugins/builtin/commodity-balances/pane.tsx +11 -4
  439. package/src/plugins/builtin/company-attention/app-rank.tsx +7 -5
  440. package/src/plugins/builtin/company-attention/building-model.ts +222 -0
  441. package/src/plugins/builtin/company-attention/building.tsx +172 -0
  442. package/src/plugins/builtin/company-attention/client.ts +117 -1
  443. package/src/plugins/builtin/company-attention/evidence.ts +16 -3
  444. package/src/plugins/builtin/company-attention/headless.ts +101 -5
  445. package/src/plugins/builtin/company-attention/index.tsx +6 -3
  446. package/src/plugins/builtin/company-attention/model.ts +33 -7
  447. package/src/plugins/builtin/company-attention/moves-model.ts +253 -0
  448. package/src/plugins/builtin/company-attention/moves.tsx +159 -0
  449. package/src/plugins/builtin/company-attention/pane.tsx +79 -23
  450. package/src/plugins/builtin/company-attention/signals-model.ts +229 -0
  451. package/src/plugins/builtin/company-attention/signals.tsx +160 -0
  452. package/src/plugins/builtin/company-kpis/headless.ts +3 -2
  453. package/src/plugins/builtin/company-kpis/model.ts +2 -2
  454. package/src/plugins/builtin/company-kpis/pane.tsx +1 -1
  455. package/src/plugins/builtin/composite-plugins.ts +2 -1
  456. package/src/plugins/builtin/congress-trades/headless.ts +1 -1
  457. package/src/plugins/builtin/connections/index.ts +1 -0
  458. package/src/plugins/builtin/correlation/headless-schema.ts +3 -2
  459. package/src/plugins/builtin/correlation/headless.ts +5 -3
  460. package/src/plugins/builtin/cot/headless.ts +28 -6
  461. package/src/plugins/builtin/cot/model.ts +12 -0
  462. package/src/plugins/builtin/cot/pane.tsx +3 -2
  463. package/src/plugins/builtin/cpi/headless.ts +5 -1
  464. package/src/plugins/builtin/cpi/pane.tsx +11 -9
  465. package/src/plugins/builtin/credit-boards/model.ts +2 -0
  466. package/src/plugins/builtin/credit-documents/headless.ts +1 -1
  467. package/src/plugins/builtin/crypto-board/client.ts +86 -0
  468. package/src/plugins/builtin/crypto-board/defi-view.tsx +218 -0
  469. package/src/plugins/builtin/crypto-board/defi.ts +239 -0
  470. package/src/plugins/builtin/crypto-board/headless.ts +117 -6
  471. package/src/plugins/builtin/crypto-board/index.tsx +8 -3
  472. package/src/plugins/builtin/crypto-board/model.ts +40 -8
  473. package/src/plugins/builtin/crypto-board/pane.tsx +55 -21
  474. package/src/plugins/builtin/crypto-board/series.ts +19 -1
  475. package/src/plugins/builtin/crypto-etf-flows/client.ts +60 -0
  476. package/src/plugins/builtin/crypto-etf-flows/headless.ts +132 -0
  477. package/src/plugins/builtin/crypto-etf-flows/index.tsx +44 -0
  478. package/src/plugins/builtin/crypto-etf-flows/model.ts +121 -0
  479. package/src/plugins/builtin/crypto-etf-flows/pane.tsx +193 -0
  480. package/src/plugins/builtin/debug/index.tsx +1 -0
  481. package/src/plugins/builtin/dividend-yield/index.tsx +1 -1
  482. package/src/plugins/builtin/docs/index.tsx +1 -1
  483. package/src/plugins/builtin/docs/pane.tsx +2 -2
  484. package/src/plugins/builtin/docs/targets.ts +1 -1
  485. package/src/plugins/builtin/doe/client.ts +5 -1
  486. package/src/plugins/builtin/doe/headless.ts +12 -6
  487. package/src/plugins/builtin/doe/model.ts +43 -6
  488. package/src/plugins/builtin/doe/pane.tsx +18 -11
  489. package/src/plugins/builtin/earnings/board-model.ts +13 -6
  490. package/src/plugins/builtin/earnings/board-table.ts +4 -1
  491. package/src/plugins/builtin/earnings/board.tsx +253 -50
  492. package/src/plugins/builtin/earnings/calendar-model.ts +188 -0
  493. package/src/plugins/builtin/earnings/calendar.tsx +338 -0
  494. package/src/plugins/builtin/earnings/client.ts +4 -3
  495. package/src/plugins/builtin/earnings/headless.ts +53 -15
  496. package/src/plugins/builtin/earnings/history-model.ts +53 -36
  497. package/src/plugins/builtin/earnings/index.tsx +15 -22
  498. package/src/plugins/builtin/earnings/model.ts +17 -12
  499. package/src/plugins/builtin/earnings/scope.ts +89 -0
  500. package/src/plugins/builtin/earnings-calls/calendar.tsx +310 -0
  501. package/src/plugins/builtin/earnings-calls/data.ts +146 -2
  502. package/src/plugins/builtin/earnings-calls/headless.ts +151 -9
  503. package/src/plugins/builtin/earnings-calls/index.tsx +3 -3
  504. package/src/plugins/builtin/earnings-calls/lock-note.ts +1 -1
  505. package/src/plugins/builtin/earnings-calls/pane.tsx +149 -31
  506. package/src/plugins/builtin/earnings-calls/upcoming.ts +195 -0
  507. package/src/plugins/builtin/earnings-ripple/pane.tsx +10 -5
  508. package/src/plugins/builtin/econ/calendar-model.ts +144 -27
  509. package/src/plugins/builtin/econ/detail-view.tsx +48 -10
  510. package/src/plugins/builtin/econ/figures.ts +72 -0
  511. package/src/plugins/builtin/econ/fred-catalog.ts +23 -6
  512. package/src/plugins/builtin/econ/fred-series-map.ts +4 -0
  513. package/src/plugins/builtin/econ/index.tsx +144 -27
  514. package/src/plugins/builtin/econ/print-watch.ts +2 -1
  515. package/src/plugins/builtin/econ/types.ts +34 -1
  516. package/src/plugins/builtin/econ-statistics/client.ts +16 -3
  517. package/src/plugins/builtin/econ-statistics/defs.ts +4 -0
  518. package/src/plugins/builtin/econ-statistics/detail.tsx +2 -2
  519. package/src/plugins/builtin/econ-statistics/headless.ts +87 -28
  520. package/src/plugins/builtin/econ-statistics/index.tsx +3 -3
  521. package/src/plugins/builtin/econ-statistics/pane.tsx +2 -1
  522. package/src/plugins/builtin/econ-statistics/stats.ts +104 -0
  523. package/src/plugins/builtin/econ-statistics/view.ts +19 -1
  524. package/src/plugins/builtin/equity-screener/client.ts +21 -3
  525. package/src/plugins/builtin/equity-screener/headless.ts +68 -6
  526. package/src/plugins/builtin/equity-screener/live.ts +1 -1
  527. package/src/plugins/builtin/equity-screener/model.ts +6 -0
  528. package/src/plugins/builtin/equity-screener/pane.tsx +47 -12
  529. package/src/plugins/builtin/equity-screener/screen-check.ts +90 -0
  530. package/src/plugins/builtin/equity-screener/ticker-check.tsx +148 -0
  531. package/src/plugins/builtin/estimate-revisions/headless.ts +3 -1
  532. package/src/plugins/builtin/estimate-revisions/lock-note.ts +3 -3
  533. package/src/plugins/builtin/estimate-revisions/model.ts +8 -10
  534. package/src/plugins/builtin/exposure/charts.tsx +2 -2
  535. package/src/plugins/builtin/exposure/headless.ts +51 -6
  536. package/src/plugins/builtin/exposure/index.tsx +28 -2
  537. package/src/plugins/builtin/exposure/model.ts +20 -1
  538. package/src/plugins/builtin/exposure/pane.tsx +10 -5
  539. package/src/plugins/builtin/fear-greed/index.tsx +1 -1
  540. package/src/plugins/builtin/filing-events/index.tsx +1 -1
  541. package/src/plugins/builtin/futures/index.tsx +1 -0
  542. package/src/plugins/builtin/futures/model.ts +12 -10
  543. package/src/plugins/builtin/futures/returns.ts +8 -36
  544. package/src/plugins/builtin/futures/table.tsx +3 -3
  545. package/src/plugins/builtin/futures-curve/client.ts +40 -9
  546. package/src/plugins/builtin/futures-curve/headless.ts +39 -17
  547. package/src/plugins/builtin/futures-curve/model.ts +258 -69
  548. package/src/plugins/builtin/futures-curve/pane.tsx +46 -17
  549. package/src/plugins/builtin/fx-matrix/client.ts +20 -8
  550. package/src/plugins/builtin/fx-matrix/headless.ts +37 -16
  551. package/src/plugins/builtin/fx-matrix/index.tsx +25 -13
  552. package/src/plugins/builtin/fx-matrix/live-legs.ts +34 -0
  553. package/src/plugins/builtin/fx-matrix/settings.ts +2 -1
  554. package/src/plugins/builtin/gpu/headless.ts +9 -4
  555. package/src/plugins/builtin/help/index.tsx +13 -3
  556. package/src/plugins/builtin/help/keybindings-editor.tsx +18 -14
  557. package/src/plugins/builtin/holders/beneficial-model.ts +8 -11
  558. package/src/plugins/builtin/holders/beneficial-report.ts +6 -5
  559. package/src/plugins/builtin/holders/beneficial-view.tsx +7 -3
  560. package/src/plugins/builtin/holders/client.ts +13 -1
  561. package/src/plugins/builtin/holders/format.ts +28 -17
  562. package/src/plugins/builtin/holders/headless.ts +46 -7
  563. package/src/plugins/builtin/holders/index-holders.ts +264 -0
  564. package/src/plugins/builtin/holders/pane.tsx +79 -15
  565. package/src/plugins/builtin/holders/report-rows.ts +35 -7
  566. package/src/plugins/builtin/holders/table-model.ts +2 -1
  567. package/src/plugins/builtin/holders/treemap.tsx +2 -2
  568. package/src/plugins/builtin/insider/headless.ts +1 -1
  569. package/src/plugins/builtin/insider/signals-client.ts +1 -1
  570. package/src/plugins/builtin/insider/signals.tsx +1 -1
  571. package/src/plugins/builtin/ipo-calendar/pane.tsx +7 -4
  572. package/src/plugins/builtin/iv-history/client.ts +20 -0
  573. package/src/plugins/builtin/iv-history/headless.ts +7 -4
  574. package/src/plugins/builtin/iv-history/index.tsx +1 -1
  575. package/src/plugins/builtin/iv-history/model.ts +13 -4
  576. package/src/plugins/builtin/iv-history/series.ts +3 -1
  577. package/src/plugins/builtin/jobs/lock-note.ts +1 -1
  578. package/src/plugins/builtin/jobs/model.ts +4 -15
  579. package/src/plugins/builtin/jobs/pane.tsx +7 -5
  580. package/src/plugins/builtin/jobs/share-bars.tsx +11 -5
  581. package/src/plugins/builtin/jodi/pane.tsx +10 -4
  582. package/src/plugins/builtin/layout-manager/index.tsx +1 -0
  583. package/src/plugins/builtin/macro-day/headless.ts +20 -7
  584. package/src/plugins/builtin/macro-day/index.tsx +3 -2
  585. package/src/plugins/builtin/macro-day/model.ts +29 -8
  586. package/src/plugins/builtin/macro-day/pane.tsx +51 -13
  587. package/src/plugins/builtin/macro-day/releases.ts +55 -13
  588. package/src/plugins/builtin/market-heatmap/data.ts +9 -2
  589. package/src/plugins/builtin/market-heatmap/evidence.ts +1 -1
  590. package/src/plugins/builtin/market-heatmap/headless.ts +9 -6
  591. package/src/plugins/builtin/market-heatmap/index.tsx +3 -3
  592. package/src/plugins/builtin/market-heatmap/model.ts +10 -7
  593. package/src/plugins/builtin/market-movers/client.ts +33 -19
  594. package/src/plugins/builtin/market-movers/footer.ts +2 -2
  595. package/src/plugins/builtin/market-movers/headless.ts +8 -2
  596. package/src/plugins/builtin/market-movers/index.tsx +16 -10
  597. package/src/plugins/builtin/market-movers/screener.ts +29 -8
  598. package/src/plugins/builtin/market-movers/session-body.tsx +4 -2
  599. package/src/plugins/builtin/market-movers/session-table.ts +4 -2
  600. package/src/plugins/builtin/market-movers/table.ts +4 -1
  601. package/src/plugins/builtin/market-valuation/headless.ts +2 -0
  602. package/src/plugins/builtin/market-valuation/view.ts +5 -0
  603. package/src/plugins/builtin/members/breadth-pane.tsx +81 -0
  604. package/src/plugins/builtin/members/client.ts +19 -4
  605. package/src/plugins/builtin/members/headless.ts +24 -10
  606. package/src/plugins/builtin/members/index.tsx +9 -9
  607. package/src/plugins/builtin/members/model.ts +23 -4
  608. package/src/plugins/builtin/members/pane.tsx +31 -14
  609. package/src/plugins/builtin/mna/client.ts +1 -0
  610. package/src/plugins/builtin/mna/detail.tsx +20 -32
  611. package/src/plugins/builtin/mna/distress/detail.tsx +16 -4
  612. package/src/plugins/builtin/mna/distress/model.ts +3 -2
  613. package/src/plugins/builtin/mna/distress/pane.tsx +7 -4
  614. package/src/plugins/builtin/mna/headless.ts +6 -13
  615. package/src/plugins/builtin/mna/model.ts +93 -15
  616. package/src/plugins/builtin/mna/pane.tsx +5 -4
  617. package/src/plugins/builtin/news/headless.ts +12 -6
  618. package/src/plugins/builtin/news/index.tsx +10 -1
  619. package/src/plugins/builtin/news/wire/index.tsx +3 -2
  620. package/src/plugins/builtin/news/wire/news/command-bar-search.ts +26 -10
  621. package/src/plugins/builtin/news/wire/news/query-presets.ts +6 -2
  622. package/src/plugins/builtin/news/wire/rss/cli.ts +3 -3
  623. package/src/plugins/builtin/notes/cli.ts +49 -14
  624. package/src/plugins/builtin/openfda/pane.tsx +1 -1
  625. package/src/plugins/builtin/options/analytics.ts +26 -2
  626. package/src/plugins/builtin/options/carry.ts +2 -2
  627. package/src/plugins/builtin/options/index.tsx +1 -1
  628. package/src/plugins/builtin/options/model-spot.ts +5 -2
  629. package/src/plugins/builtin/options/strike-window.ts +2 -1
  630. package/src/plugins/builtin/options/table.ts +1 -7
  631. package/src/plugins/builtin/options/view.tsx +30 -13
  632. package/src/plugins/builtin/options-calculator/headless.ts +46 -7
  633. package/src/plugins/builtin/options-positioning/client.ts +19 -0
  634. package/src/plugins/builtin/options-positioning/headless.ts +54 -14
  635. package/src/plugins/builtin/options-positioning/index.tsx +3 -3
  636. package/src/plugins/builtin/options-positioning/model.ts +47 -8
  637. package/src/plugins/builtin/options-positioning/pane.tsx +68 -38
  638. package/src/plugins/builtin/options-scenario/client.ts +123 -28
  639. package/src/plugins/builtin/options-scenario/collar.ts +8 -6
  640. package/src/plugins/builtin/options-scenario/csp-screen-headless.ts +127 -0
  641. package/src/plugins/builtin/options-scenario/csp-screen-pane.tsx +165 -0
  642. package/src/plugins/builtin/options-scenario/csp-screen.ts +258 -0
  643. package/src/plugins/builtin/options-scenario/csp.ts +101 -21
  644. package/src/plugins/builtin/options-scenario/headless.ts +36 -15
  645. package/src/plugins/builtin/options-scenario/hedge.ts +20 -14
  646. package/src/plugins/builtin/options-scenario/index.tsx +28 -3
  647. package/src/plugins/builtin/options-scenario/model.ts +13 -0
  648. package/src/plugins/builtin/options-scenario/pane.tsx +9 -5
  649. package/src/plugins/builtin/perps/equity-row.tsx +11 -3
  650. package/src/plugins/builtin/perps/freshness.ts +14 -9
  651. package/src/plugins/builtin/perps/headless.ts +3 -1
  652. package/src/plugins/builtin/perps/list-perpetuals.ts +25 -4
  653. package/src/plugins/builtin/perps/live-rows.ts +168 -0
  654. package/src/plugins/builtin/perps/markets-section.tsx +154 -0
  655. package/src/plugins/builtin/perps/pane.tsx +49 -26
  656. package/src/plugins/builtin/perps/venue-markets.ts +96 -0
  657. package/src/plugins/builtin/plugin-marketplace/index.tsx +2 -1
  658. package/src/plugins/builtin/plugin-marketplace/pane.tsx +143 -59
  659. package/src/plugins/builtin/portfolio-list/cli/bulk-symbols.ts +72 -24
  660. package/src/plugins/builtin/portfolio-list/cli/portfolio-command.ts +158 -141
  661. package/src/plugins/builtin/portfolio-list/cli/render.ts +54 -22
  662. package/src/plugins/builtin/portfolio-list/cli/shared.ts +3 -3
  663. package/src/plugins/builtin/portfolio-list/cli/watchlist-command.ts +29 -24
  664. package/src/plugins/builtin/portfolio-list/headless.ts +7 -4
  665. package/src/plugins/builtin/portfolio-list/income.ts +13 -2
  666. package/src/plugins/builtin/portfolio-list/index.tsx +9 -2
  667. package/src/plugins/builtin/portfolio-list/pane/index.tsx +21 -8
  668. package/src/plugins/builtin/portfolio-list/pane/purchase-date-fx.ts +46 -0
  669. package/src/plugins/builtin/portfolio-list/summary/index.tsx +11 -8
  670. package/src/plugins/builtin/portfolio-list/summary/live-accounts.ts +16 -9
  671. package/src/plugins/builtin/portfolio-list/summary/totals.ts +2 -15
  672. package/src/plugins/builtin/power/client.ts +4 -1
  673. package/src/plugins/builtin/power/evidence.ts +22 -7
  674. package/src/plugins/builtin/power/gas.tsx +5 -1
  675. package/src/plugins/builtin/power/pane.tsx +8 -1
  676. package/src/plugins/builtin/power/prices.tsx +10 -3
  677. package/src/plugins/builtin/rate-path/pane.tsx +2 -2
  678. package/src/plugins/builtin/research/analyst-headless.ts +25 -8
  679. package/src/plugins/builtin/research/analyst-model.ts +68 -3
  680. package/src/plugins/builtin/research/corporate-actions-pane.tsx +63 -14
  681. package/src/plugins/builtin/research/event-model.ts +3 -1
  682. package/src/plugins/builtin/research/event-sources.ts +12 -4
  683. package/src/plugins/builtin/research/index.tsx +2 -1
  684. package/src/plugins/builtin/research/relative-valuation-basis.ts +58 -0
  685. package/src/plugins/builtin/research/relative-valuation-columns.ts +31 -2
  686. package/src/plugins/builtin/research/relative-valuation-currency.ts +12 -5
  687. package/src/plugins/builtin/research/relative-valuation-headless.ts +84 -26
  688. package/src/plugins/builtin/research/relative-valuation-model.ts +88 -19
  689. package/src/plugins/builtin/research/relative-valuation-pane.tsx +80 -13
  690. package/src/plugins/builtin/research/relative-valuation-peers.ts +1 -1
  691. package/src/plugins/builtin/reverse-dcf/model.ts +6 -2
  692. package/src/plugins/builtin/risk-factors/index.tsx +2 -2
  693. package/src/plugins/builtin/scanner/feed.ts +2 -2
  694. package/src/plugins/builtin/scanner/index.ts +24 -1
  695. package/src/plugins/builtin/scanner/live-condition-editor.tsx +222 -0
  696. package/src/plugins/builtin/scanner/live-feed.ts +168 -0
  697. package/src/plugins/builtin/scanner/live-headless.ts +114 -0
  698. package/src/plugins/builtin/scanner/live-model.ts +351 -0
  699. package/src/plugins/builtin/scanner/live-pane.tsx +677 -0
  700. package/src/plugins/builtin/scanner/live-track.ts +186 -0
  701. package/src/plugins/builtin/scanner/lock-note.ts +1 -1
  702. package/src/plugins/builtin/sec/forms.ts +13 -0
  703. package/src/plugins/builtin/sec/fund-abroad.ts +32 -0
  704. package/src/plugins/builtin/sec/fund-facts.ts +68 -8
  705. package/src/plugins/builtin/sec/headless.ts +85 -8
  706. package/src/plugins/builtin/sec/index.tsx +58 -12
  707. package/src/plugins/builtin/sectors/client.ts +2 -1
  708. package/src/plugins/builtin/sectors/sector-model.ts +11 -15
  709. package/src/plugins/builtin/series-inventory.ts +3 -0
  710. package/src/plugins/builtin/shared/broker-reconnect.ts +107 -22
  711. package/src/plugins/builtin/shared/cloud-upgrade.ts +34 -6
  712. package/src/plugins/builtin/shared/earnings-calendar.ts +375 -0
  713. package/src/plugins/builtin/{earnings/estimate-basis.ts → shared/earnings-estimate-basis.ts} +1 -1
  714. package/src/plugins/builtin/shared/earnings-report.ts +3 -3
  715. package/src/plugins/builtin/shared/fx-rate-freshness.ts +23 -1
  716. package/src/plugins/builtin/shared/job-posting.ts +129 -0
  717. package/src/plugins/builtin/shared/macro-releases.ts +65 -0
  718. package/src/plugins/builtin/shared/pro-lock-note.ts +3 -3
  719. package/src/plugins/builtin/shared/report-freshness.ts +3 -0
  720. package/src/plugins/builtin/shared/research-trading.tsx +21 -0
  721. package/src/plugins/builtin/shared/scanner-capture.ts +3 -0
  722. package/src/plugins/builtin/shared/series-cache.ts +2 -0
  723. package/src/plugins/builtin/shared/ticker-surface.ts +2 -1
  724. package/src/plugins/builtin/shared/use-quote-board.ts +8 -2
  725. package/src/plugins/builtin/shared/volatility/pricing.ts +7 -1
  726. package/src/plugins/builtin/short-interest/client.ts +2 -0
  727. package/src/plugins/builtin/short-interest/headless.ts +41 -12
  728. package/src/plugins/builtin/short-interest/index.tsx +23 -1
  729. package/src/plugins/builtin/short-interest/model.ts +70 -19
  730. package/src/plugins/builtin/short-interest/pane.tsx +19 -2
  731. package/src/plugins/builtin/short-interest/publications-client.ts +82 -0
  732. package/src/plugins/builtin/short-interest/publications-headless.ts +29 -0
  733. package/src/plugins/builtin/short-interest/publications-model.ts +50 -0
  734. package/src/plugins/builtin/short-interest/publications-pane.tsx +66 -0
  735. package/src/plugins/builtin/short-interest/schedule.ts +35 -2
  736. package/src/plugins/builtin/short-interest/surface.tsx +11 -4
  737. package/src/plugins/builtin/short-interest/types.ts +9 -0
  738. package/src/plugins/builtin/short-interest/watch-client.ts +14 -8
  739. package/src/plugins/builtin/short-interest/watch-model.ts +12 -25
  740. package/src/plugins/builtin/short-interest/watch-pane.tsx +5 -1
  741. package/src/plugins/builtin/supply-chain/flow.tsx +33 -9
  742. package/src/plugins/builtin/supply-chain/model.ts +51 -3
  743. package/src/plugins/builtin/supply-chain/pane.tsx +78 -39
  744. package/src/plugins/builtin/supply-chain/row-evidence.tsx +1 -1
  745. package/src/plugins/builtin/themes/headless.ts +11 -6
  746. package/src/plugins/builtin/themes/model.ts +15 -5
  747. package/src/plugins/builtin/themes/pane.tsx +27 -8
  748. package/src/plugins/builtin/thirteenf/headless.ts +5 -5
  749. package/src/plugins/builtin/thirteenf/signals.ts +3 -1
  750. package/src/plugins/builtin/ticker-detail/adr-pair/headless.ts +123 -0
  751. package/src/plugins/builtin/ticker-detail/adr-pair/model.ts +132 -0
  752. package/src/plugins/builtin/ticker-detail/adr-pair/tab.tsx +87 -0
  753. package/src/plugins/builtin/ticker-detail/data-panes/historical-prices.tsx +40 -26
  754. package/src/plugins/builtin/ticker-detail/data-panes/history-bars.ts +8 -4
  755. package/src/plugins/builtin/ticker-detail/data-panes/returns-history.ts +67 -3
  756. package/src/plugins/builtin/ticker-detail/data-panes/returns-model.ts +112 -5
  757. package/src/plugins/builtin/ticker-detail/data-panes/returns-pane.tsx +17 -2
  758. package/src/plugins/builtin/ticker-detail/financials/aggregation.ts +21 -7
  759. package/src/plugins/builtin/ticker-detail/financials/model.ts +36 -1
  760. package/src/plugins/builtin/ticker-detail/financials/offerings.ts +56 -0
  761. package/src/plugins/builtin/ticker-detail/financials/ratios.ts +62 -13
  762. package/src/plugins/builtin/ticker-detail/financials/tab.tsx +30 -4
  763. package/src/plugins/builtin/ticker-detail/headless-schema.ts +14 -2
  764. package/src/plugins/builtin/ticker-detail/headless.ts +148 -35
  765. package/src/plugins/builtin/ticker-detail/index.tsx +37 -5
  766. package/src/plugins/builtin/ticker-detail/overview/model.ts +65 -10
  767. package/src/plugins/builtin/ticker-detail/overview/pane.tsx +9 -1
  768. package/src/plugins/builtin/ticker-detail/overview-tab.tsx +68 -11
  769. package/src/plugins/builtin/ticker-detail/pane.tsx +11 -0
  770. package/src/plugins/builtin/ticker-detail/quote-footer.ts +14 -4
  771. package/src/plugins/builtin/ticker-detail/research-tabs.ts +11 -0
  772. package/src/plugins/builtin/vol-surface/charts.tsx +9 -4
  773. package/src/plugins/builtin/vol-surface/client.ts +7 -4
  774. package/src/plugins/builtin/vol-surface/headless.ts +71 -13
  775. package/src/plugins/builtin/vol-surface/index.tsx +2 -2
  776. package/src/plugins/builtin/vol-surface/model.ts +26 -9
  777. package/src/plugins/builtin/vol-surface/pane.tsx +44 -7
  778. package/src/plugins/builtin/vol-surface/tables.ts +31 -3
  779. package/src/plugins/builtin/volatility/dvol.ts +46 -0
  780. package/src/plugins/builtin/volatility/model.ts +5 -10
  781. package/src/plugins/builtin/volatility/pane.tsx +2 -2
  782. package/src/plugins/builtin/volatility/series.ts +26 -0
  783. package/src/plugins/builtin/world-indices/footer.ts +1 -1
  784. package/src/plugins/builtin/world-venue-map/basemap-layer.tsx +4 -3
  785. package/src/plugins/builtin/world-venue-map/basemap.ts +3 -1
  786. package/src/plugins/builtin/world-venue-map/chokepoint-chart.ts +40 -0
  787. package/src/plugins/builtin/world-venue-map/evidence.ts +1 -1
  788. package/src/plugins/builtin/world-venue-map/geo-series.ts +90 -11
  789. package/src/plugins/builtin/world-venue-map/headless.ts +1 -1
  790. package/src/plugins/builtin/world-venue-map/index.ts +3 -26
  791. package/src/plugins/builtin/world-venue-map/layers.ts +1 -1
  792. package/src/plugins/builtin/world-venue-map/map.tsx +2 -1
  793. package/src/plugins/builtin/world-venue-map/pane.tsx +4 -2
  794. package/src/plugins/builtin/world-venue-map/venue-header.tsx +15 -4
  795. package/src/plugins/builtin/yield-curve/client.ts +25 -0
  796. package/src/plugins/builtin/yield-curve/curves.ts +7 -4
  797. package/src/plugins/builtin/yield-curve/headless.ts +38 -4
  798. package/src/plugins/builtin/yield-curve/history.ts +4 -3
  799. package/src/plugins/builtin/yield-curve/index.tsx +12 -6
  800. package/src/plugins/builtin/yield-curve/swaps-model.ts +93 -0
  801. package/src/plugins/builtin/yield-curve/swaps.tsx +99 -0
  802. package/src/plugins/bundle.ts +1 -1
  803. package/src/plugins/catalog-browser.ts +15 -9
  804. package/src/plugins/compat.ts +3 -3
  805. package/src/plugins/dependencies.ts +75 -14
  806. package/src/plugins/extracted-plugins.ts +132 -34
  807. package/src/plugins/host-link.ts +149 -34
  808. package/src/plugins/installer.ts +35 -10
  809. package/src/plugins/loader.ts +206 -38
  810. package/src/plugins/manager-node.ts +2 -2
  811. package/src/plugins/marketplace/deactivation.ts +22 -0
  812. package/src/plugins/marketplace/model.ts +2 -2
  813. package/src/plugins/marketplace/packs.ts +1 -1
  814. package/src/plugins/ownership.ts +1 -1
  815. package/src/plugins/peer-retry.ts +155 -0
  816. package/src/plugins/registry/contributions.ts +3 -1
  817. package/src/plugins/registry/index.ts +4 -3
  818. package/src/plugins/registry/plugin-state.ts +3 -0
  819. package/src/plugins/seed-notice.ts +20 -0
  820. package/src/plugins/shortcut-argument.ts +39 -0
  821. package/src/portfolio/allocation.ts +1 -1
  822. package/src/portfolio/collection-name.ts +31 -0
  823. package/src/portfolio/column-values.ts +15 -13
  824. package/src/portfolio/cost-fx.ts +296 -19
  825. package/src/portfolio/manual-lots.ts +75 -0
  826. package/src/portfolio/mutations.ts +60 -22
  827. package/src/portfolio/suffixed-listings.ts +209 -0
  828. package/src/portfolio/totals-currency.ts +24 -0
  829. package/src/public/__snapshots__/public-api.test.ts.snap +15 -0
  830. package/src/public/time-series.ts +11 -8
  831. package/src/remote/schema.ts +1 -1
  832. package/src/renderers/browser/app-services.ts +1 -7
  833. package/src/renderers/browser/config-host.ts +5 -55
  834. package/src/renderers/browser/main.tsx +30 -60
  835. package/src/renderers/dom/boot-frame-page.ts +187 -0
  836. package/src/renderers/dom/boot-frame.ts +237 -0
  837. package/src/renderers/dom/build-assets.ts +46 -8
  838. package/src/renderers/dom/dom-ui-host.tsx +4 -29
  839. package/src/renderers/dom/host/ascii-text.ts +16 -2
  840. package/src/renderers/dom/host/box.tsx +43 -2
  841. package/src/renderers/dom/host/chart-surface.tsx +2 -0
  842. package/src/renderers/dom/host/hls.chunk.ts +3 -0
  843. package/src/renderers/dom/host/image-surface.tsx +49 -0
  844. package/src/renderers/dom/host/media-surface.tsx +24 -18
  845. package/src/renderers/dom/host/mouse.ts +30 -0
  846. package/src/renderers/dom/host/size-observer.ts +1 -1
  847. package/src/renderers/dom/host/style.ts +1 -1
  848. package/src/renderers/dom/styles.css +76 -0
  849. package/src/renderers/dom/test-utils.tsx +2 -1
  850. package/src/renderers/electrobun/bun/application-menu/index.ts +3 -3
  851. package/src/renderers/electrobun/bun/desktop/app-name.ts +222 -0
  852. package/src/renderers/electrobun/bun/desktop/backend-requests.ts +3 -0
  853. package/src/renderers/electrobun/bun/desktop/backend.ts +56 -3
  854. package/src/renderers/electrobun/bun/desktop/detached-windows.ts +1 -1
  855. package/src/renderers/electrobun/bun/desktop/host-requests.ts +9 -3
  856. package/src/renderers/electrobun/bun/desktop/initialization.ts +81 -18
  857. package/src/renderers/electrobun/bun/desktop/relaunch.ts +74 -25
  858. package/src/renderers/electrobun/bun/desktop/state-broadcaster.ts +1 -0
  859. package/src/renderers/electrobun/bun/desktop/update.ts +70 -3
  860. package/src/renderers/electrobun/bun/desktop/workspace/index.ts +2 -0
  861. package/src/renderers/electrobun/bun/external-plugins.ts +29 -7
  862. package/src/renderers/electrobun/bun/index.ts +36 -2
  863. package/src/renderers/electrobun/bun/window/boot-frame.ts +67 -0
  864. package/src/renderers/electrobun/bun/window/create.ts +4 -1
  865. package/src/renderers/electrobun/shared/app-name.ts +17 -0
  866. package/src/renderers/electrobun/shared/boot-frame.ts +7 -0
  867. package/src/renderers/electrobun/shared/protocol.ts +6 -1
  868. package/src/renderers/electrobun/view/cli-pane-shot-entry.tsx +1 -1
  869. package/src/renderers/electrobun/view/cli-pane-shot-frame.tsx +3 -3
  870. package/src/renderers/electrobun/view/config-host.ts +3 -0
  871. package/src/renderers/electrobun/view/desktop/window/snapshot.ts +1 -0
  872. package/src/renderers/electrobun/view/fatal-screen.tsx +1 -1
  873. package/src/renderers/electrobun/view/main.tsx +30 -4
  874. package/src/renderers/electrobun/view/news-source.ts +5 -5
  875. package/src/renderers/electrobun/view/remote/asset-data-client.ts +1 -1
  876. package/src/renderers/electrobun/view/ui-host.tsx +1 -1
  877. package/src/renderers/opentui/browser-open.ts +88 -0
  878. package/src/renderers/opentui/host.tsx +5 -14
  879. package/src/renderers/opentui/image/loader.ts +3 -2
  880. package/src/renderers/opentui/native-smoke.ts +10 -1
  881. package/src/renderers/opentui/pane-image/index.ts +2 -1
  882. package/src/renderers/opentui/render-lib.ts +253 -0
  883. package/src/renderers/opentui/render-timing-smoke.ts +1 -1
  884. package/src/renderers/opentui/start.tsx +1 -1
  885. package/src/renderers/opentui/toast-host.tsx +71 -43
  886. package/src/renderers/share/layout-view.tsx +2 -2
  887. package/src/renderers/share/main.tsx +4 -4
  888. package/src/renderers/share/view.tsx +1 -1
  889. package/src/series/resolve.ts +22 -6
  890. package/src/series/standalone.ts +30 -2
  891. package/src/series/types.ts +8 -1
  892. package/src/shares/api.ts +4 -1
  893. package/src/shares/pane.ts +1 -1
  894. package/src/sources/gloomberb-cloud/fred-series.ts +46 -1
  895. package/src/sources/gloomberb-cloud/index.ts +32 -16
  896. package/src/sources/gloomberb-cloud/news.ts +39 -0
  897. package/src/sources/gloomberb-cloud/normalizers.ts +16 -1
  898. package/src/sources/gloomberb-cloud/perpetuals.ts +49 -1
  899. package/src/sources/listing-symbols.ts +37 -0
  900. package/src/sources/provider-errors.ts +16 -2
  901. package/src/sources/provider-router/batches.ts +10 -2
  902. package/src/sources/provider-router/financial-routes.ts +21 -3
  903. package/src/sources/provider-router/financials.ts +15 -2
  904. package/src/sources/provider-router/history.ts +58 -15
  905. package/src/sources/provider-router/index.ts +146 -10
  906. package/src/sources/provider-router/primary.ts +1 -1
  907. package/src/sources/provider-router/search.ts +13 -2
  908. package/src/state/app/bootstrap.ts +23 -0
  909. package/src/state/app/context/index.tsx +3 -0
  910. package/src/state/hooks/inline-tickers.ts +30 -5
  911. package/src/sync/auth-transition.ts +19 -9
  912. package/src/sync/baseline.ts +10 -4
  913. package/src/sync/controller.ts +67 -17
  914. package/src/sync/core-contributors.ts +46 -14
  915. package/src/sync/react.ts +4 -1
  916. package/src/sync/types.ts +3 -0
  917. package/src/team/collections-sync.ts +2 -1
  918. package/src/team/collections.ts +178 -17
  919. package/src/telemetry/crash-reports.ts +17 -4
  920. package/src/telemetry/usage-counts.ts +0 -18
  921. package/src/test-support/builtin-panes.ts +1 -1
  922. package/src/theme/colors.ts +11 -30
  923. package/src/theme/ui-tokens.ts +37 -1
  924. package/src/tickers/company-name-listing.ts +210 -33
  925. package/src/tickers/company-name.ts +59 -0
  926. package/src/tickers/index-roots.ts +47 -0
  927. package/src/tickers/instrument-label.ts +5 -1
  928. package/src/tickers/listing-venues.ts +23 -0
  929. package/src/tickers/metadata.ts +10 -0
  930. package/src/tickers/perpetual-listing.ts +5 -2
  931. package/src/tickers/search/bare-symbol.ts +36 -0
  932. package/src/tickers/search/home-listing.ts +75 -0
  933. package/src/tickers/search/index.ts +111 -33
  934. package/src/tickers/search/ranking.ts +64 -5
  935. package/src/tickers/search/types.ts +5 -0
  936. package/src/tickers/search/upsert.ts +29 -0
  937. package/src/tickers/terminal-codes.ts +416 -40
  938. package/src/time-series/bar-aggregation.ts +243 -0
  939. package/src/time-series/base-series.ts +315 -0
  940. package/src/time-series/chart-bounds.ts +349 -0
  941. package/src/time-series/chart-seed.ts +142 -0
  942. package/src/time-series/daily-valuation.ts +62 -0
  943. package/src/time-series/economic.ts +5 -0
  944. package/src/time-series/field-catalog.ts +1 -3
  945. package/src/time-series/forward-valuation.ts +32 -0
  946. package/src/time-series/fundamentals.ts +173 -10
  947. package/src/time-series/history-acquisition.ts +499 -0
  948. package/src/time-series/hooks.ts +1 -0
  949. package/src/time-series/leverage.ts +100 -0
  950. package/src/time-series/market-resolution.ts +4 -2
  951. package/src/time-series/market.ts +2 -1
  952. package/src/time-series/price-comparison.ts +175 -30
  953. package/src/time-series/price-units.ts +72 -2
  954. package/src/time-series/range.ts +9 -1
  955. package/src/time-series/resolution.ts +174 -16
  956. package/src/time-series/resolve-context.ts +161 -0
  957. package/src/time-series/resolve.ts +185 -1587
  958. package/src/time-series/series-name.ts +38 -0
  959. package/src/time-series/series-presentation.ts +242 -0
  960. package/src/time-series/spec.ts +13 -7
  961. package/src/time-series/studies.ts +377 -82
  962. package/src/time-series/tail-reconcile.ts +121 -0
  963. package/src/time-series/transforms.ts +1 -0
  964. package/src/time-series/types.ts +34 -2
  965. package/src/time-series/use-chart-resolution.ts +4 -5
  966. package/src/time-series/valuation-releases.ts +39 -0
  967. package/src/types/broker.ts +10 -0
  968. package/src/types/config.ts +14 -0
  969. package/src/types/data-provider.ts +23 -1
  970. package/src/types/desktop-window.ts +2 -0
  971. package/src/types/exchange-rate.ts +6 -0
  972. package/src/types/financials.ts +145 -8
  973. package/src/types/headless.ts +117 -9
  974. package/src/types/instrument.ts +6 -0
  975. package/src/types/plugin.ts +66 -9
  976. package/src/types/price-history.ts +2 -0
  977. package/src/types/ticker.ts +13 -0
  978. package/src/types/trading.ts +59 -1
  979. package/src/ui/ascii-font.ts +13 -1
  980. package/src/ui/host.tsx +6 -1
  981. package/src/updater/command-names.ts +180 -0
  982. package/src/updater/index.ts +10 -5
  983. package/src/utils/calendar-date.ts +32 -15
  984. package/src/utils/cash-runway.ts +241 -0
  985. package/src/utils/central-banks.ts +42 -0
  986. package/src/utils/cli-output.ts +259 -80
  987. package/src/utils/contract-month.ts +16 -0
  988. package/src/utils/crypto-pair.ts +61 -3
  989. package/src/utils/currency-units.ts +29 -0
  990. package/src/utils/datetime-format.ts +10 -0
  991. package/src/utils/debug-log.ts +1 -1
  992. package/src/utils/decimal-comma.ts +39 -6
  993. package/src/utils/exchange-announcements.ts +71 -0
  994. package/src/utils/exchange-rate-snapshot.ts +10 -0
  995. package/src/utils/financial-statements.ts +89 -5
  996. package/src/utils/format.ts +34 -16
  997. package/src/utils/fundamentals.ts +150 -34
  998. package/src/utils/fx-market-hours.ts +10 -1
  999. package/src/utils/latest-financial-period.ts +8 -0
  1000. package/src/utils/linux-libc.ts +54 -0
  1001. package/src/utils/market-capitalization.ts +111 -15
  1002. package/src/utils/max-drawdown.ts +64 -0
  1003. package/src/utils/network-failure.ts +86 -0
  1004. package/src/utils/option-expiry.ts +186 -7
  1005. package/src/utils/options.ts +10 -0
  1006. package/src/utils/plugin-proxy-hosts.json +1 -0
  1007. package/src/utils/price-earnings.ts +11 -5
  1008. package/src/utils/price-history.ts +23 -8
  1009. package/src/utils/price-window.ts +131 -0
  1010. package/src/utils/release-date.ts +47 -0
  1011. package/src/utils/sec.ts +3 -0
  1012. package/src/utils/throttled-fetch.ts +11 -4
  1013. package/src/utils/trailing-eps.ts +67 -0
  1014. package/src/utils/typed-text.ts +21 -0
  1015. package/src/utils/utc-time.ts +24 -1
  1016. package/src/version.ts +6 -0
  1017. package/src/cli/pane-functions/screenshot.ts +0 -2122
  1018. package/src/renderers/browser/first-screen.ts +0 -193
@@ -16,15 +16,18 @@
16
16
  "src/cli/pane-functions/headless.ts": ["portfolio-list"],
17
17
  "src/cli/pane-functions/options.ts": ["ticker-detail"],
18
18
  "src/cli/pane-functions/resolver.ts": ["chart-composer"],
19
+ "src/cli/pane-functions/screenshot-bridge.ts": ["time-sales"],
20
+ "src/cli/pane-functions/screenshot-chart-evidence.ts": ["chart-composer"],
21
+ "src/cli/pane-functions/screenshot-data-evidence.ts": ["chart-composer","ticker-detail"],
19
22
  "src/cli/pane-functions/screenshot-evidence.ts": ["attention","awards","catalysts","company-attention","company-kpis","credit-documents","exposure","market-heatmap","options-calculator","options-scenario","power","realized-vol","supply-chain","vol-surface","volatility","world-venue-map"],
20
- "src/cli/pane-functions/screenshot.ts": ["chart-composer","econ-statistics","market-valuation","portfolio-list","ticker-detail","time-sales"],
23
+ "src/cli/pane-functions/screenshot-payload.ts": ["chart-composer","econ-statistics","market-valuation","portfolio-list","ticker-detail","time-sales"],
21
24
  "src/components/command-bar/commands/direct/index.ts": ["broker-manager"],
22
25
  "src/components/command-bar/routes/root/help-items.ts": ["help"],
23
26
  "src/components/command-bar/workflow/ops.ts": ["correlation","portfolio-list","ticker-detail"],
24
27
  "src/components/layout/shell/index.tsx": ["cloud"],
25
28
  "src/components/onboarding/use-onboarding-upgrade.ts": ["chat"],
26
29
  "src/layout/desks.ts": ["chart-composer"],
27
- "src/plugins/catalog-browser.ts": ["alerts","analytics","attention","awards","backtest","bond-calculator","catalysts","cds","central-bank-rates","changelog","chart-composer","clinical-trials","cloud","comment-letters","commodities-energy","commodity-balances","company-attention","company-kpis","connections","correlation","cot","cpi","credit-boards","credit-conditions","credit-documents","crypto-board","debt-maturities","dividend-yield","docs","doe","earnings-calls","earnings-ripple","econ","econ-statistics","equity-screener","estimate-revisions","executives","exposure","fear-greed","filing-events","fixed-income","futures","futures-curve","fx-matrix","gpu","help","insider","ipo-calendar","iv-history","jobs","jodi","kelly-sizer","layout-manager","macro-day","market-halts","market-heatmap","market-valuation","members","mna","money-markets","news","openfda","options","options-calculator","options-positioning","options-scenario","pe-band","perps","portfolio-list","power","primary-dealers","rate-path","realized-vol","relative-rotation","research","research-search","revenue-breakdown","reverse-dcf","risk-factors","scanner","seasonality","sec","sectors","short-interest","short-volume","social-mentions","supply-chain","ticker-detail","time-sales","trace-bonds","treasury-auctions","treasury-daily","vol-surface","volatility","world-indices","world-venue-map","yield-curve"],
30
+ "src/plugins/catalog-browser.ts": ["alerts","analytics","attention","awards","backtest","bond-calculator","catalysts","cds","central-bank-rates","changelog","chart-composer","clinical-trials","cloud","comment-letters","commodities-energy","commodity-balances","company-attention","company-kpis","connections","correlation","cot","cpi","credit-boards","credit-conditions","credit-documents","crypto-board","crypto-etf-flows","debt-maturities","dividend-yield","docs","doe","earnings","earnings-calls","earnings-ripple","econ","econ-statistics","equity-screener","estimate-revisions","executives","exposure","fear-greed","filing-events","fixed-income","futures","futures-curve","fx-matrix","gpu","help","holders","insider","ipo-calendar","iv-history","jobs","jodi","kelly-sizer","layout-manager","macro-day","market-halts","market-heatmap","market-valuation","members","mna","money-markets","news","openfda","options","options-calculator","options-positioning","options-scenario","pe-band","perps","portfolio-list","power","primary-dealers","rate-path","realized-vol","relative-rotation","research","research-search","revenue-breakdown","reverse-dcf","risk-factors","scanner","seasonality","sec","sectors","short-interest","short-volume","social-mentions","supply-chain","thirteenf","ticker-detail","time-sales","trace-bonds","treasury-auctions","treasury-daily","vol-surface","volatility","world-indices","world-venue-map","yield-curve"],
28
31
  "src/plugins/catalog-ui.ts": ["alerts","clinical-trials","cloud","comment-letters","custom-view","fear-greed","ipo-calendar","market-halts","market-heatmap","members","news","notes","openfda","research-search"],
29
32
  "src/plugins/catalog.ts": ["debug"],
30
33
  "src/remote/controller.ts": ["custom-view"],
@@ -65,14 +65,14 @@
65
65
  "radius": 5,
66
66
  "spacing": 2
67
67
  },
68
- "why": "Chat has its own owner and conventions; reported, not changed (GLO-768)."
68
+ "why": "Chat has its own owner and conventions; reported, not changed."
69
69
  },
70
70
  "src/plugins/builtin/chat/content/handle-prompt.tsx": {
71
71
  "literals": {
72
72
  "font weight": 1,
73
73
  "spacing": 2
74
74
  },
75
- "why": "Chat has its own owner and conventions; reported, not changed (GLO-768)."
75
+ "why": "Chat has its own owner and conventions; reported, not changed."
76
76
  },
77
77
  "src/plugins/builtin/chat/message/pane-chip.tsx": {
78
78
  "literals": {
@@ -80,7 +80,7 @@
80
80
  "radius": 3,
81
81
  "spacing": 2
82
82
  },
83
- "why": "Chat has its own owner and conventions; reported, not changed (GLO-768)."
83
+ "why": "Chat has its own owner and conventions; reported, not changed."
84
84
  },
85
85
  "src/plugins/builtin/credit-documents/gauge.tsx": {
86
86
  "literals": {
@@ -26,7 +26,7 @@
26
26
  "measure": "inset",
27
27
  "value": 7.2,
28
28
  "component": "PaneSidebarRow",
29
- "why": "Chat has its own owner: its channel rows start 7px in (reported, not changed, in GLO-768)."
29
+ "why": "Chat has its own owner: its channel rows start 7px in (reported, not changed)."
30
30
  }
31
31
  ],
32
32
  "FXMD_REST_HEALTH": [
@@ -1,6 +1,7 @@
1
1
  import type { BrokerAdapter } from "../types/broker";
2
2
  import type { AppConfig, BrokerInstanceConfig } from "../types/config";
3
3
  import type { Portfolio, TickerPosition, TickerRecord } from "../types/ticker";
4
+ import type { BrokerAccount } from "../types/trading";
4
5
  import { buildBrokerPortfolioId, getBrokerInstance, isBrokerPortfolioId } from "../utils/broker-instances";
5
6
  import { isSignedInBrokerProfile } from "./signed-in/profile";
6
7
 
@@ -55,6 +56,42 @@ export function isHeldByOtherSignedInProfile(
55
56
  return !!owner && owner.id !== instance.id && isSignedInBrokerProfile(owner);
56
57
  }
57
58
 
59
+ /**
60
+ * The accounts `instance` reports that another enabled profile already holds
61
+ * under the account's own number, such as IBKR U1234567 synced on this device
62
+ * and linked through SnapTrade as well. That profile keeps the account, so its
63
+ * portfolio and positions appear once.
64
+ */
65
+ export function accountsHeldUnderOwnNumber(
66
+ config: AppConfig,
67
+ instance: BrokerInstanceConfig,
68
+ accounts: readonly BrokerAccount[],
69
+ ): Set<string> {
70
+ const held = new Set(config.portfolios.flatMap((portfolio) => {
71
+ if (!portfolio.brokerAccountId || portfolio.brokerInstanceId === instance.id) return [];
72
+ const owner = getBrokerInstance(config.brokerInstances, portfolio.brokerInstanceId);
73
+ return owner && owner.enabled !== false ? [portfolio.brokerAccountId.trim().toUpperCase()] : [];
74
+ }));
75
+ return new Set(accounts.flatMap((account) => {
76
+ const number = account.brokerageAccountId?.trim().toUpperCase();
77
+ return number && held.has(number) ? [account.accountId] : [];
78
+ }));
79
+ }
80
+
81
+ /**
82
+ * The accounts of `instance` to list: without those another enabled profile
83
+ * holds under their own number (`accountsHeldUnderOwnNumber`), so an account
84
+ * linked twice appears once wherever accounts are chosen or shown.
85
+ */
86
+ export function accountsShownFor(
87
+ config: AppConfig,
88
+ instance: BrokerInstanceConfig,
89
+ accounts: BrokerAccount[],
90
+ ): BrokerAccount[] {
91
+ const held = accountsHeldUnderOwnNumber(config, instance, accounts);
92
+ return held.size ? accounts.filter((account) => !held.has(account.accountId)) : accounts;
93
+ }
94
+
58
95
  /**
59
96
  * Who keeps a portfolio when the profile holding it is removed: another
60
97
  * enabled profile of the same broker that syncs the same account. Only a
@@ -57,6 +57,17 @@ export function brokerMethodSummary(entry: BrokerDirectoryEntry): string {
57
57
  return signsIn ? t("Sign in") : t("On this device");
58
58
  }
59
59
 
60
+ /**
61
+ * The method summary with what the broker says of itself, for a list that
62
+ * gives each broker a line under its name: "Sign in · Brokerages you link in
63
+ * SnapTrade" for one that is not itself a broker.
64
+ */
65
+ export function brokerDirectorySummary(entry: BrokerDirectoryEntry): string {
66
+ const described = entry.methods.find((method) => method.kind === "signed-in")?.broker.description?.trim();
67
+ const summary = brokerMethodSummary(entry);
68
+ return described ? `${summary} · ${described}` : summary;
69
+ }
70
+
60
71
  export function brokerMethodLabel(entry: BrokerDirectoryEntry, method: BrokerMethod): string {
61
72
  if (method.kind === "signed-in") {
62
73
  return entry.methods.some((candidate) => candidate.kind === "device") ? t("Sign in (recommended)") : t("Sign in");
@@ -15,11 +15,13 @@ function svg(markup: string): string {
15
15
 
16
16
  /**
17
17
  * The marks the official plugins ship as their icon, for the same brokers
18
- * when Gloom connects them, keyed by the backend's broker id.
18
+ * when Gloom connects them, keyed by the backend's broker id. SnapTrade has
19
+ * no plugin: its mark is from its own site, on white.
19
20
  */
20
21
  const SIGNED_IN_BROKER_LOGOS: Readonly<Record<string, string>> = {
21
22
  ibkr: svg('<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 64 64"><defs><linearGradient id="t" x1="0" y1="0" x2="0" y2="64" gradientUnits="userSpaceOnUse"><stop offset="0" stop-color="#262626"/><stop offset="1" stop-color="#0F0F0F"/></linearGradient><linearGradient id="m" gradientUnits="userSpaceOnUse" x1="3633.335" y1="66.0445" x2="3671.0737" y2="66.0445" gradientTransform="matrix(-1 0 0 1 3673.7529 0)"><stop offset="0" stop-color="#D71F27"/><stop offset="1" stop-color="#971B1E"/></linearGradient></defs><rect width="64" height="64" fill="url(#t)"/><g transform="translate(20.4 8.2) scale(0.539)"><polygon points="40.4,86.8 2.7,86.8 2.7,45.3" fill="url(#m)"/><polygon points="40.4,1.5 2.7,45.3 2.7,86.8" fill="#D71F27"/><circle cx="35.2" cy="55.5" r="11.3" fill="#D71F27"/></g></svg>'),
22
23
  robinhood: svg('<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 64 64"><rect width="64" height="64" fill="#CCFF00"/><path transform="translate(14 14) scale(1.5)" d="M2.84 24h.53c.096 0 .192-.048.224-.128C7.591 13.696 11.94 8.656 14.67 5.638c.112-.128.064-.225-.096-.225h-4.88a.55.55 0 0 0-.45.225L5.746 9.972c-.514.642-.642 1.236-.642 2.086v4.43c-1.14 3.194-1.862 5.361-2.392 7.32-.032.125.016.192.129.192M20.447.646c-.754-.802-4.157-.834-5.73-.224a3 3 0 0 0-.786.465 41 41 0 0 0-3.323 3.178c-.112.113-.064.225.097.225h5.409c.497 0 .786.289.786.786v6.1c0 .16.128.208.225.064l3.258-4.254c.53-.69.69-.898.835-1.861.192-1.413.08-3.58-.77-4.479m-6.982 16.18 2.231-3.676a.7.7 0 0 0 .064-.29V6.73c0-.16-.112-.225-.224-.097-3.355 3.74-5.971 7.672-8.395 12.407-.06.12.016.225.16.177l5.009-1.54c.565-.174.882-.402 1.155-.852" fill="#1A1A1A"/></svg>'),
24
+ snaptrade: svg('<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 64 64"><defs><linearGradient id="a" x1="14" y1="-33.2" x2="39.35" y2="10.81" gradientUnits="userSpaceOnUse"><stop stop-color="#045856"/><stop offset="1" stop-color="#52C4C2"/></linearGradient><linearGradient id="b" x1="14.33" y1="34.34" x2="-24.58" y2="-4.39" gradientUnits="userSpaceOnUse"><stop stop-color="#E6960D"/><stop offset=".27" stop-color="#F2CA86"/></linearGradient><linearGradient id="c" x1="1.95" y1="33.87" x2="-32.55" y2="-6.92" gradientUnits="userSpaceOnUse"><stop stop-color="#E6960D"/><stop offset=".27" stop-color="#F2CA86"/></linearGradient></defs><rect width="64" height="64" fill="#FFFFFF"/><g transform="translate(12.4 10.45) scale(1.4)"><path d="M27.47 11.24 27.11 10.62 22.55 2.73C21.96 1.72 20.88 1.09 19.7 1.09H11.12C9.95 1.09 8.86 1.72 8.28 2.73L3.71 10.62 8.28 18.51C8.86 19.53 9.95 20.15 11.12 20.15H15.42L9.9 10.62 15.41 1.1 20.92 10.62 25.32 18.23 27.46 14.52C28.05 13.5 28.05 12.25 27.46 11.24Z" fill="url(#a)"/><path d="M24.21 20.15 19.64 12.26C19.06 11.25 17.97 10.62 16.8 10.62H12.5L18.01 20.15 12.5 29.69H16.8C17.97 29.69 19.06 29.06 19.64 28.05Z" fill="url(#b)"/><path d="M6.99 20.15 2.59 12.54.44 16.26C-.15 17.27-.15 18.52.44 19.54L.8 20.15 5.36 28.05C5.95 29.06 7.03 29.69 8.21 29.69H12.5L6.99 20.15Z" fill="url(#c)"/></g></svg>'),
23
25
  };
24
26
 
25
27
  /** The plugin icon of a broker adapter (`getBrokerLogo` on the plugin runtime). */
@@ -10,12 +10,15 @@ import { ApiRequestError } from "../../api-client/errors";
10
10
  import { openUrl } from "../../components/ui/external-link";
11
11
  import type { BrokerAdapter, BrokerConnectionStatus, BrokerPosition } from "../../types/broker";
12
12
  import type { BrokerInstanceConfig } from "../../types/config";
13
+ import type { Quote } from "../../types/financials";
13
14
  import type {
14
15
  BrokerAccount,
15
16
  BrokerExecution,
16
17
  BrokerOrder,
18
+ BrokerOrderPreview,
17
19
  BrokerOrderRequest,
18
20
  BrokerPortfolioPerformance,
21
+ BrokerTradingCapabilities,
19
22
  } from "../../types/trading";
20
23
  import { findSignedInBroker, refreshSignedInBrokers } from "./catalog";
21
24
  import type { SignedInBroker, SignedInBrokerConnection } from "./client";
@@ -47,16 +50,50 @@ function brokerReason(lastError: string | null | undefined): string | null {
47
50
  return described.replace(/[\s.]+$/, "").slice(0, 200) || null;
48
51
  }
49
52
 
50
- /** What to tell the user when Gloom answers a broker call with an error. */
51
- function describeSignedInBrokerError(error: unknown, brokerName: string): string {
53
+ /** Gloom holds no live sign-in for the broker: only connecting again helps. */
54
+ class SignInNeededError extends Error {}
55
+
56
+ /**
57
+ * What to tell the user when Gloom answers a broker call with an error, and
58
+ * whether only a new sign-in, to Gloom or the broker, gets the profile going.
59
+ */
60
+ function describeSignedInBrokerError(error: unknown, brokerName: string): { message: string; needsSignIn: boolean } {
52
61
  const status = error instanceof ApiRequestError ? error.status : undefined;
53
- if (status === 401) return `Sign in to Gloom first, then connect ${brokerName}.`;
62
+ if (status === 401) return { message: `Sign in to Gloom first, then connect ${brokerName}.`, needsSignIn: true };
54
63
  const signInAgain = `${brokerName} needs you to sign in again. Press Connect in Brokers.`;
55
64
  // A sign-in the broker ended says why, in Gloom's words.
56
- if (status === 409) return (error instanceof ApiRequestError && writtenMessage(error)) || signInAgain;
57
- if (status === 404) return signInAgain;
58
- if (status === 502) return `${brokerName} is not responding. Try again shortly.`;
59
- return error instanceof Error && error.message ? error.message : String(error);
65
+ if (status === 409) return { message: (error instanceof ApiRequestError && writtenMessage(error)) || signInAgain, needsSignIn: true };
66
+ if (status === 404) return { message: signInAgain, needsSignIn: true };
67
+ if (status === 502) return { message: `${brokerName} is not responding. Try again shortly.`, needsSignIn: false };
68
+ // A refused order or a busy broker says why without its error code.
69
+ if (error instanceof ApiRequestError && (status === 403 || status === 422 || status === 503)) {
70
+ return { message: writtenMessage(error) ?? error.message, needsSignIn: false };
71
+ }
72
+ return {
73
+ message: error instanceof Error && error.message ? error.message : String(error),
74
+ needsSignIn: error instanceof SignInNeededError,
75
+ };
76
+ }
77
+
78
+ /**
79
+ * Gloom answered an order action and nothing was placed, changed or
80
+ * cancelled: the broker refused it, its check lapsed, trading is not granted,
81
+ * the broker was too busy to take it, or the sign-in has to be renewed. A
82
+ * 502 or a lost answer may have reached the broker, so it is not one.
83
+ */
84
+ function refusedOrderAction(error: unknown): boolean {
85
+ if (!(error instanceof ApiRequestError)) return false;
86
+ return error.status !== undefined && error.status >= 400 && error.status < 500 || error.status === 503;
87
+ }
88
+
89
+ /** A sign-in that ended or was never made, as opposed to a refused order: the profile's status says so. */
90
+ function signInLost(error: unknown): boolean {
91
+ if (!(error instanceof ApiRequestError)) return false;
92
+ return error.status === 401 || error.status === 404 || error.status === 409 && error.code === "reauth_required";
93
+ }
94
+
95
+ function refused(message: string): Error {
96
+ return Object.assign(new Error(message), { refused: true });
60
97
  }
61
98
 
62
99
  /** The broker does not offer this. A broker tool that failed is also a 422, but a failure. */
@@ -67,7 +104,7 @@ function isUnsupported(error: unknown): boolean {
67
104
  type BrokerRequest = <T>(
68
105
  broker: string,
69
106
  path: string,
70
- options?: { method?: "GET" | "POST" | "DELETE"; body?: unknown },
107
+ options?: { method?: "GET" | "POST" | "PUT" | "DELETE"; body?: unknown },
71
108
  ) => Promise<T>;
72
109
 
73
110
  export interface SignedInBrokerAdapterDeps {
@@ -84,6 +121,60 @@ interface PortfolioSnapshot {
84
121
  fetchedAt?: number;
85
122
  }
86
123
 
124
+ /** Gloom's answer to a direct-mode order, before the user confirms it. */
125
+ interface DirectOrderPreview {
126
+ status: "preview";
127
+ previewId: string;
128
+ expiresAt: string;
129
+ impact: {
130
+ source: "broker" | "unavailable";
131
+ sourceLabel: string;
132
+ currency?: string;
133
+ estimatedCost?: number;
134
+ cashBefore?: number;
135
+ cashAfter?: number;
136
+ commission?: number;
137
+ fees?: number;
138
+ disclosure: string;
139
+ };
140
+ }
141
+
142
+ interface PlacedOrder { status: "placed"; order: BrokerOrder }
143
+
144
+ /** The quote a direct-mode broker gives the ticket. */
145
+ interface SignedInBrokerQuote {
146
+ symbol: string;
147
+ name?: string;
148
+ currency?: string;
149
+ price: number;
150
+ bid?: number;
151
+ ask?: number;
152
+ bidSize?: number;
153
+ askSize?: number;
154
+ lastTradePrice?: number;
155
+ lastUpdated: number;
156
+ dataSource: "live" | "delayed";
157
+ }
158
+
159
+ /** The same order always keys the same, whatever order its fields arrive in. */
160
+ function canonical(value: unknown): string {
161
+ if (Array.isArray(value)) return `[${value.map(canonical).join(",")}]`;
162
+ if (value && typeof value === "object") {
163
+ return `{${Object.entries(value).filter(([, entry]) => entry !== undefined).sort(([a], [b]) => (a < b ? -1 : a > b ? 1 : 0))
164
+ .map(([key, entry]) => `${JSON.stringify(key)}:${canonical(entry)}`).join(",")}}`;
165
+ }
166
+ return JSON.stringify(value) ?? "null";
167
+ }
168
+
169
+ /** The ticket's fields, without the profile's own, as Gloom checks and places the order. */
170
+ function orderBody(request: BrokerOrderRequest): BrokerOrderRequest {
171
+ const { brokerInstanceId: _profile, ...body } = request;
172
+ const { brokerInstanceId: _contractProfile, ...contract } = body.contract;
173
+ return { ...body, contract };
174
+ }
175
+
176
+ const DIRECT_TIF = ["DAY"];
177
+
87
178
  export function createSignedInBrokerAdapter(overrides: Partial<SignedInBrokerAdapterDeps> = {}): BrokerAdapter {
88
179
  const deps: SignedInBrokerAdapterDeps = {
89
180
  request: (broker, path, options) => apiClient.brokerRequest(broker, path, options),
@@ -95,12 +186,29 @@ export function createSignedInBrokerAdapter(overrides: Partial<SignedInBrokerAda
95
186
  };
96
187
  const statuses = new Map<string, BrokerConnectionStatus>();
97
188
  const listeners = new Map<string, Set<() => void>>();
189
+ /** Whether each profile's sign-in granted trading, as its last connect read it. */
190
+ const canTrade = new Map<string, boolean>();
191
+ /** Direct mode: the check the user is reviewing, per profile, by the exact order it was for. */
192
+ const previews = new Map<string, { order: string; previewId: string; expiresAt: number }>();
193
+ /** Direct mode: the broker's own id behind each order number the app holds, per profile. */
194
+ const handles = new Map<string, Map<number, { accountId: string; brokerOrderId: string }>>();
98
195
 
99
196
  const brokerName = (instance: BrokerInstanceConfig) =>
100
197
  deps.findBroker(signedInBrokerId(instance))?.name ?? instance.label;
101
198
 
102
- const setStatus = (instance: BrokerInstanceConfig, state: "connected" | "error", message?: string) => {
103
- statuses.set(instance.id, { state, message, mode: METHOD, updatedAt: deps.now() });
199
+ /** The broker's direct-mode orders, or null for one that keeps orders for review or takes none. */
200
+ const directOrders = (instance: BrokerInstanceConfig) => {
201
+ const orders = deps.findBroker(signedInBrokerId(instance))?.capabilities.orders;
202
+ return orders && orders.mode === "direct" ? orders : null;
203
+ };
204
+
205
+ const setStatus = (instance: BrokerInstanceConfig, state: "connected" | "error", message?: string, needsSignIn = false) => {
206
+ statuses.set(instance.id, {
207
+ state, message, mode: METHOD, updatedAt: deps.now(),
208
+ ...(needsSignIn ? { needsSignIn } : {}),
209
+ // A direct-mode broker says per quote whether it is real-time.
210
+ ...(directOrders(instance) ? { quoteData: "realtime" as const } : {}),
211
+ });
104
212
  for (const listener of listeners.get(instance.id) ?? []) listener();
105
213
  };
106
214
 
@@ -111,8 +219,8 @@ export function createSignedInBrokerAdapter(overrides: Partial<SignedInBrokerAda
111
219
  setStatus(instance, "connected");
112
220
  return result;
113
221
  } catch (error) {
114
- const message = describeSignedInBrokerError(error, brokerName(instance));
115
- setStatus(instance, "error", message);
222
+ const { message, needsSignIn } = describeSignedInBrokerError(error, brokerName(instance));
223
+ setStatus(instance, "error", message, needsSignIn);
116
224
  throw new Error(message);
117
225
  }
118
226
  };
@@ -130,7 +238,51 @@ export function createSignedInBrokerAdapter(overrides: Partial<SignedInBrokerAda
130
238
  const snapshot = (instance: BrokerInstanceConfig) =>
131
239
  track(instance, () => get<PortfolioSnapshot>(instance, "/snapshot"));
132
240
 
133
- /** Checks an order against what the broker takes, before Gloom sees it. */
241
+ /**
242
+ * An order as the app holds it: this profile's, under this adapter, and
243
+ * remembered by its number so a change or cancel can name it to the broker.
244
+ */
245
+ const ownOrder = (instance: BrokerInstanceConfig, order: BrokerOrder): BrokerOrder => {
246
+ if (order.brokerOrderId && order.accountId) {
247
+ const known = handles.get(instance.id) ?? new Map();
248
+ known.set(order.orderId, { accountId: order.accountId, brokerOrderId: order.brokerOrderId });
249
+ handles.set(instance.id, known);
250
+ }
251
+ return { ...order, brokerInstanceId: instance.id, contract: { ...order.contract, brokerId: SIGNED_IN_BROKER_TYPE, brokerInstanceId: instance.id } };
252
+ };
253
+
254
+ /**
255
+ * One order action. A refusal leaves the profile's status alone (the
256
+ * broker is fine; the order is not) and is marked refused; a sign-in that
257
+ * ended shows on the profile as any failed call does.
258
+ */
259
+ const orderAction = async <T>(instance: BrokerInstanceConfig, run: () => Promise<T>): Promise<T> => {
260
+ try {
261
+ const result = await run();
262
+ setStatus(instance, "connected");
263
+ return result;
264
+ } catch (error) {
265
+ const { message, needsSignIn } = describeSignedInBrokerError(error, brokerName(instance));
266
+ if (signInLost(error)) setStatus(instance, "error", message, needsSignIn);
267
+ throw refusedOrderAction(error) ? refused(message) : new Error(message);
268
+ }
269
+ };
270
+
271
+ /** The broker's id for an order number; nothing is sent when it cannot be found. */
272
+ const brokerOrderHandle = async (instance: BrokerInstanceConfig, orderId: number) => {
273
+ const known = handles.get(instance.id)?.get(orderId);
274
+ if (known) return known;
275
+ try {
276
+ for (const order of await get<BrokerOrder[]>(instance, "/orders")) ownOrder(instance, order);
277
+ } catch (error) {
278
+ throw refused(describeSignedInBrokerError(error, brokerName(instance)).message);
279
+ }
280
+ const found = handles.get(instance.id)?.get(orderId);
281
+ if (!found) throw refused("This order is no longer listed. Refresh your orders.");
282
+ return found;
283
+ };
284
+
285
+ /** Checks an order against what the broker takes, before Gloom sees it: a failure sent nothing. */
134
286
  const checkOrder = async (instance: BrokerInstanceConfig, request: BrokerOrderRequest) => {
135
287
  const id = signedInBrokerId(instance);
136
288
  let broker = deps.findBroker(id);
@@ -140,14 +292,25 @@ export function createSignedInBrokerAdapter(overrides: Partial<SignedInBrokerAda
140
292
  }
141
293
  const name = broker?.name ?? instance.label;
142
294
  const orders = broker?.capabilities.orders;
143
- if (!orders) throw new Error(`${name} does not take orders from Gloom.`);
295
+ if (!orders) throw refused(`${name} does not take orders from Gloom.`);
144
296
  if (!orders.types.includes(request.orderType)) {
145
- throw new Error(`${name} does not take ${request.orderType} orders from Gloom.`);
297
+ throw refused(`${name} does not take ${request.orderType} orders from Gloom.`);
298
+ }
299
+ // A server that does not say it takes a bracket, an OCO pair or a trailing stop would drop its fields and place a bare
300
+ // order: never send one it has not named.
301
+ if (!request.orderClass && (request.takeProfitPrice !== undefined || request.stopLossPrice !== undefined)) {
302
+ throw refused("A take profit or stop loss needs a bracket or OCO order.");
303
+ }
304
+ if (request.orderClass && !orders.orderClasses?.includes(request.orderClass)) {
305
+ throw refused(`${name} does not take ${request.orderClass === "oco" ? "OCO" : "bracket"} orders from Gloom.`);
306
+ }
307
+ if (request.orderType === "TRAIL" && !orders.trailing?.includes(request.trailingPercent !== undefined ? "percent" : "amount")) {
308
+ throw refused(`${name} does not take this trailing stop from Gloom.`);
146
309
  }
147
- if (!(request.quantity > 0)) throw new Error("Quantity must be positive.");
310
+ if (!(request.quantity > 0)) throw refused("Quantity must be positive.");
148
311
  const needsLimit = request.orderType === "LMT" || request.orderType === "STP LMT";
149
312
  if (needsLimit && !(typeof request.limitPrice === "number" && request.limitPrice > 0)) {
150
- throw new Error("A limit order needs a limit price.");
313
+ throw refused("A limit order needs a limit price.");
151
314
  }
152
315
  return { name, mode: orders.mode };
153
316
  };
@@ -156,6 +319,8 @@ export function createSignedInBrokerAdapter(overrides: Partial<SignedInBrokerAda
156
319
  id: SIGNED_IN_BROKER_TYPE,
157
320
  name: "Signed-in broker",
158
321
  configSchema: [],
322
+ // A signed-in broker's quotes come through Gloom and count against the broker's allowance.
323
+ ticketQuotesOnly: true,
159
324
 
160
325
  async validate() {
161
326
  return true;
@@ -191,17 +356,51 @@ export function createSignedInBrokerAdapter(overrides: Partial<SignedInBrokerAda
191
356
  return getOptional<BrokerExecution[]>(instance, "/executions?period=DAYS_90", []);
192
357
  },
193
358
 
194
- listOpenOrders(instance) {
195
- return getOptional<BrokerOrder[]>(instance, "/orders", []);
359
+ async listOpenOrders(instance) {
360
+ return (await getOptional<BrokerOrder[]>(instance, "/orders", [])).map((order) => ownOrder(instance, order));
196
361
  },
197
362
 
198
363
  async previewOrder(instance, request) {
199
364
  const { name, mode } = await checkOrder(instance, request);
200
- return mode === "review" ? { warningText: `${name} opens this order for you to review and submit.` } : {};
365
+ if (mode === "review") return { warningText: `${name} opens this order for you to review and submit.` };
366
+ const answer = await orderAction(instance, () => deps.request<DirectOrderPreview>(
367
+ signedInBrokerId(instance),
368
+ "/orders",
369
+ { method: "POST", body: orderBody(request) },
370
+ ));
371
+ previews.set(instance.id, { order: canonical(orderBody(request)), previewId: answer.previewId, expiresAt: Date.parse(answer.expiresAt) });
372
+ const { impact } = answer;
373
+ const preview: BrokerOrderPreview = {
374
+ impactSource: impact.source,
375
+ impactSourceLabel: impact.sourceLabel,
376
+ disclosure: impact.disclosure,
377
+ currency: impact.currency,
378
+ estimatedCost: impact.estimatedCost,
379
+ commission: impact.commission,
380
+ commissionCurrency: impact.commission === undefined ? undefined : impact.currency,
381
+ fees: impact.fees,
382
+ cashBefore: impact.cashBefore,
383
+ cashAfter: impact.cashAfter,
384
+ };
385
+ return Object.fromEntries(Object.entries(preview).filter(([, value]) => value !== undefined)) as BrokerOrderPreview;
201
386
  },
202
387
 
203
388
  async placeOrder(instance, request) {
204
- const { name } = await checkOrder(instance, request);
389
+ const { name, mode } = await checkOrder(instance, request);
390
+ if (mode === "direct") {
391
+ // Only the order the user reviewed, while its check stands.
392
+ const preview = previews.get(instance.id);
393
+ if (!preview || preview.order !== canonical(orderBody(request)) || !(preview.expiresAt > deps.now())) {
394
+ throw refused("Review this order again before placing it.");
395
+ }
396
+ const placed = await orderAction(instance, () => deps.request<PlacedOrder>(
397
+ signedInBrokerId(instance),
398
+ "/orders",
399
+ { method: "POST", body: { ...orderBody(request), previewId: preview.previewId } },
400
+ ));
401
+ previews.delete(instance.id);
402
+ return ownOrder(instance, placed.order);
403
+ }
205
404
  const placed = await track(instance, () => deps.request<{ status: string; id: string; reviewUrl: string }>(
206
405
  signedInBrokerId(instance),
207
406
  "/orders",
@@ -228,23 +427,102 @@ export function createSignedInBrokerAdapter(overrides: Partial<SignedInBrokerAda
228
427
  };
229
428
  },
230
429
 
231
- async modifyOrder(instance) {
430
+ async modifyOrder(instance, orderId, request) {
431
+ const { name, mode } = await checkOrder(instance, request);
432
+ if (mode !== "direct") throw refused(`Orders sent to ${name} are managed in ${name}.`);
433
+ const handle = await brokerOrderHandle(instance, orderId);
434
+ const changed = await orderAction(instance, () => deps.request<PlacedOrder>(
435
+ signedInBrokerId(instance),
436
+ `/orders/${encodeURIComponent(handle.brokerOrderId)}`,
437
+ { method: "PUT", body: { ...orderBody(request), accountId: handle.accountId } },
438
+ ));
439
+ return ownOrder(instance, changed.order);
440
+ },
441
+
442
+ async cancelOrder(instance, orderId) {
232
443
  const name = brokerName(instance);
233
- throw new Error(`Orders sent to ${name} are managed in ${name}.`);
444
+ if (!directOrders(instance)) throw refused(`Orders sent to ${name} are managed in ${name}.`);
445
+ const handle = await brokerOrderHandle(instance, orderId);
446
+ await orderAction(instance, () => deps.request<{ cancelled: boolean }>(
447
+ signedInBrokerId(instance),
448
+ `/orders/${encodeURIComponent(handle.brokerOrderId)}?accountId=${encodeURIComponent(handle.accountId)}`,
449
+ { method: "DELETE" },
450
+ ));
234
451
  },
235
452
 
236
- async cancelOrder(instance) {
453
+ /**
454
+ * Direct mode only: what the ticket offers. Trading needs the profile
455
+ * switched on and a sign-in that granted it; the broker's linked
456
+ * account may still be read-only, which its check then says.
457
+ */
458
+ getTradingCapabilities(instance) {
237
459
  const name = brokerName(instance);
238
- throw new Error(`Orders sent to ${name} are managed in ${name}.`);
460
+ const orders = directOrders(instance);
461
+ if (!orders) {
462
+ return { enabled: false, disabledReason: `${name} does not take orders from the ticket.`, orderTypes: [], tif: [] };
463
+ }
464
+ const granted = canTrade.get(instance.id) === true;
465
+ const switchedOn = instance.config.tradingEnabled === true;
466
+ const capabilities: BrokerTradingCapabilities = {
467
+ enabled: granted && switchedOn,
468
+ orderTypes: [...orders.types],
469
+ tif: orders.tif?.length ? [...orders.tif] : DIRECT_TIF,
470
+ ...(orders.orderClasses?.length ? { orderClasses: [...orders.orderClasses] } : {}),
471
+ ...(orders.trailing?.length ? { trailing: [...orders.trailing] } : {}),
472
+ minQuantity: 1,
473
+ quantityStep: 1,
474
+ modify: true,
475
+ cancel: true,
476
+ executionKind: "order-summaries",
477
+ };
478
+ if (!granted) capabilities.disabledReason = `${name} is connected read-only. Connect it again in Brokers to allow trading.`;
479
+ else if (!switchedOn) capabilities.disabledReason = "Trading is off for this profile.";
480
+ return capabilities;
481
+ },
482
+
483
+ getTradingConfigUpdate(_instance, enabled) {
484
+ return { tradingEnabled: enabled };
485
+ },
486
+
487
+ // The ticket's quote. A symbol the broker cannot price, or its request
488
+ // allowance spent, is the ticket's to say; only a lost sign-in is the profile's.
489
+ async getQuote(ticker, instance) {
490
+ const id = signedInBrokerId(instance);
491
+ if (!directOrders(instance)) throw new Error(`${brokerName(instance)} gives no quotes to the ticket.`);
492
+ const answer = await orderAction(instance, () => deps.request<SignedInBrokerQuote>(
493
+ id,
494
+ `/quote?symbol=${encodeURIComponent(ticker.trim().toUpperCase())}`,
495
+ ));
496
+ const quote: Quote = {
497
+ symbol: answer.symbol,
498
+ name: answer.name,
499
+ price: answer.price,
500
+ bid: answer.bid,
501
+ ask: answer.ask,
502
+ bidSize: answer.bidSize,
503
+ askSize: answer.askSize,
504
+ currency: answer.currency ?? "USD",
505
+ // The broker gives no prior close: no change to show.
506
+ change: Number.NaN,
507
+ changePercent: Number.NaN,
508
+ changeBasis: "none",
509
+ lastUpdated: answer.lastUpdated,
510
+ receivedAt: deps.now(),
511
+ dataSource: answer.dataSource,
512
+ delivery: "poll",
513
+ providerId: id,
514
+ };
515
+ return quote;
239
516
  },
240
517
 
241
518
  async connect(instance) {
242
519
  await track(instance, async () => {
243
520
  const connection = await get<SignedInBrokerConnection>(instance, "");
521
+ canTrade.set(instance.id, connection.status === "connected" && connection.canTrade === true);
244
522
  if (connection.status !== "connected") {
245
523
  const name = brokerName(instance);
246
524
  const reason = brokerReason(connection.lastError);
247
- throw new Error(reason
525
+ throw new SignInNeededError(reason
248
526
  ? `${name} needs you to sign in again: ${reason}. Press Connect in Brokers.`
249
527
  : `Press Connect in Brokers to sign in to ${name}.`);
250
528
  }
@@ -4,12 +4,22 @@
4
4
  * appears here without an app release.
5
5
  */
6
6
  import { apiClient } from "../../api-client";
7
- import type { BrokerOrderType } from "../../types/trading";
7
+ import type { BrokerOrderClass, BrokerOrderType, BrokerTrailingUnit } from "../../types/trading";
8
8
 
9
9
  interface SignedInBrokerCapabilities {
10
10
  history: boolean;
11
11
  executions: boolean;
12
- orders: false | { mode: "review" | "direct"; types: BrokerOrderType[] };
12
+ /**
13
+ * Review: the broker keeps each order for the user to submit there. Direct: Gloom checks the
14
+ * order with the broker, the user confirms that check in the ticket, and Gloom places it.
15
+ */
16
+ orders: false | {
17
+ mode: "review" | "direct"; types: BrokerOrderType[]; tif?: string[];
18
+ /** Brackets and OCO pairs the broker places and runs itself; absent from a server that sends none. */
19
+ orderClasses?: BrokerOrderClass[];
20
+ /** How a trailing stop (`TRAIL` in `types`) is set. */
21
+ trailing?: BrokerTrailingUnit[];
22
+ };
13
23
  /** Connecting Gloom replaces this broker's link to other AI apps. */
14
24
  singleConnection: boolean;
15
25
  /** Shown before connecting, e.g. an account the user must create first. */
@@ -19,6 +29,8 @@ interface SignedInBrokerCapabilities {
19
29
  export interface SignedInBroker {
20
30
  id: string;
21
31
  name: string;
32
+ /** Under the name where brokers are listed, for one that is not itself a broker (SnapTrade). */
33
+ description?: string;
22
34
  capabilities: SignedInBrokerCapabilities;
23
35
  }
24
36